import * as path from 'path'; import { fileURLToPath } from 'url'; import * as fs from 'fs'; import * as child_process from 'child_process'; import typescript from '@rollup/plugin-typescript'; import commonjs from '@rollup/plugin-commonjs'; import alias from '@rollup/plugin-alias'; import replace from '@rollup/plugin-replace'; import nodeResolve from '@rollup/plugin-node-resolve'; import nodePolyfill from 'rollup-plugin-polyfill-node'; import html from '@rollup/plugin-html'; import json from '@rollup/plugin-json'; const dir = path.dirname(fileURLToPath(import.meta.url)); const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')); const default_remote_config = JSON.parse(fs.readFileSync(path.join(dir, 'resources', 'common', 'remote-config.json'), 'utf-8')); const git = (() => { try { fs.statSync(path.join(dir, '.git')); } catch (err) { return null; } const options = {cwd: dir}; const revision = child_process.execSync('git rev-parse HEAD', options).toString().trim(); const branch = child_process.execSync('git rev-parse --abbrev-ref HEAD', options).toString().trim(); const changed_files = child_process.execSync('git diff --name-only HEAD', options).toString().trim(); return { revision, branch: branch && branch !== 'HEAD' ? branch : null, changed_files: changed_files.length ? changed_files.split('\n') : [], }; })();; // If CI_COMMIT_TAG is set this is a tagged version for release const release = process.env.NODE_ENV === 'production' ? process.env.CI_COMMIT_TAG || null : null; /** * @type {import('@rollup/plugin-replace').RollupReplaceOptions} */ const replace_options = { include: ['src/util/product.ts'], values: { 'globalThis.__NXAPI_BUNDLE_PKG__': JSON.stringify(pkg), 'globalThis.__NXAPI_BUNDLE_GIT__': JSON.stringify(git), 'globalThis.__NXAPI_BUNDLE_RELEASE__': JSON.stringify(release), 'globalThis.__NXAPI_BUNDLE_DEFAULT_REMOTE_CONFIG__': JSON.stringify(default_remote_config), 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV ?? 'development'), }, preventAssignment: true, }; /** * @type {import('rollup').RollupOptions['watch']} */ const watch = { include: 'src/**', }; /** * @type {import('rollup').RollupOptions} */ const main = { input: ['src/cli-entry.ts', 'src/app/main/index.ts'], output: { dir: 'dist/bundle', format: 'es', sourcemap: true, entryFileNames: chunk => { if (chunk.name === 'cli-entry') return 'cli-bundle.js'; if (chunk.name === 'index') return 'app-main-bundle.js'; return 'entry-' + chunk.name + '.js'; }, chunkFileNames: 'chunk-[name].js', }, plugins: [ replace(replace_options), typescript({ outDir: 'dist/bundle/ts', noEmit: true, declaration: false, }), commonjs({ // the ".ts" extension is required extensions: ['.js', '.jsx', '.ts', '.tsx'], esmExternals: true, // events and stream modify module.exports requireReturnsDefault: 'preferred', }), json(), nodeResolve({ exportConditions: ['node'], browser: false, preferBuiltins: true, }), ], external: [ 'node-notifier', 'register-scheme', 'bindings', ], watch, }; /** * @type {import('rollup').RollupOptions} */ const app_entry = { input: 'src/app/app-entry.cts', output: { file: 'dist/bundle/app-entry.cjs', format: 'iife', inlineDynamicImports: true, sourcemap: true, }, plugins: [ replace(replace_options), replace({ include: ['src/app/app-entry.cts'], values: { '__NXAPI_BUNDLE_APP_MAIN__': JSON.stringify('./app-main-bundle.js'), }, preventAssignment: true, }), typescript({ noEmit: true, declaration: false, }), commonjs({ // the ".ts" extension is required extensions: ['.js', '.jsx', '.ts', '.tsx'], esmExternals: true, // events and stream modify module.exports requireReturnsDefault: 'preferred', }), json(), nodeResolve({ exportConditions: ['node'], browser: false, preferBuiltins: true, }), ], external: [ 'electron', path.resolve(__dirname, 'src/app/app-main-bundle.js'), ], watch, }; /** * @type {import('rollup').RollupOptions} */ const app_preload = { input: 'src/app/preload/index.ts', output: { file: 'dist/app/bundle/preload.cjs', format: 'cjs', sourcemap: true, }, plugins: [ replace(replace_options), typescript({ noEmit: true, declaration: false, }), commonjs({ // the ".ts" extension is required extensions: ['.js', '.jsx', '.ts', '.tsx'], esmExternals: true, }), nodeResolve({ browser: true, preferBuiltins: true, }), ], external: [ 'electron', ], watch, }; /** * @type {import('rollup').RollupOptions} */ const app_preload_webservice = { input: 'src/app/preload-webservice/index.ts', output: { file: 'dist/app/bundle/preload-webservice.cjs', format: 'cjs', }, plugins: [ replace(replace_options), typescript({ noEmit: true, declaration: false, }), commonjs({ // the ".ts" extension is required extensions: ['.js', '.jsx', '.ts', '.tsx'], esmExternals: true, }), nodeResolve({ browser: true, preferBuiltins: true, }), ], external: [ 'electron', ], watch, }; /** * @type {import('rollup').RollupOptions} */ const app_browser = { input: 'src/app/browser/index.ts', output: { dir: 'dist/app/bundle', format: 'es', sourcemap: true, manualChunks(id) { if (id.includes('node_modules')) { return 'vendor'; } if (id.startsWith('\0')) { return 'internal'; } }, chunkFileNames: 'chunk-[name].js', }, plugins: [ html({ title: 'nxapi', }), replace(replace_options), typescript({ outDir: 'dist/app/bundle/ts', noEmit: true, declaration: false, }), commonjs({ // the ".ts" extension is required extensions: ['.js', '.jsx', '.ts', '.tsx'], esmExternals: true, }), nodePolyfill(), alias({ entries: [ // react-native-web has an ESM and CommonJS build. By default the ESM build is // used when resolving react-native-web. For some reason this causes both versions // to be included in the bundle, so here we explicitly use the CommonJS build. {find: 'react-native', replacement: path.resolve(__dirname, 'node_modules', 'react-native-web', 'dist', 'cjs', 'index.js')}, // rollup-plugin-polyfill-node doesn't support node: module identifiers {find: /^node:(.+)/, replacement: '$1'}, ], }), nodeResolve({ browser: true, preferBuiltins: false, }), ], watch, }; export default [ main, app_entry, app_preload, app_preload_webservice, app_browser, ];