import * as cp from 'node:child_process'; import * as fs from 'fs-extra'; import * as os from 'node:os'; import * as path from 'node:path'; const rootPath = path.resolve(__dirname, '..'); const gniPath = path.resolve(__dirname, '../filenames.auto.gni'); const allDocs = fs.readdirSync(path.resolve(__dirname, '../docs/api')) .map(doc => `docs/api/${doc}`) .concat( fs.readdirSync(path.resolve(__dirname, '../docs/api/structures')) .map(doc => `docs/api/structures/${doc}`) ); const typingFiles = fs.readdirSync(path.resolve(__dirname, '../typings')).map(child => `typings/${child}`); const main = async () => { const webpackTargets = [ { name: 'sandbox_bundle_deps', config: 'webpack.config.sandboxed_renderer.js' }, { name: 'isolated_bundle_deps', config: 'webpack.config.isolated_renderer.js' }, { name: 'browser_bundle_deps', config: 'webpack.config.browser.js' }, { name: 'renderer_bundle_deps', config: 'webpack.config.renderer.js' }, { name: 'worker_bundle_deps', config: 'webpack.config.worker.js' }, { name: 'node_bundle_deps', config: 'webpack.config.node.js' }, { name: 'utility_bundle_deps', config: 'webpack.config.utility.js' } ]; const webpackTargetsWithDeps = await Promise.all(webpackTargets.map(async webpackTarget => { const tmpDir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-filenames-')); const child = cp.spawn('node', [ './node_modules/webpack-cli/bin/cli.js', '--config', `./build/webpack/${webpackTarget.config}`, '--stats', 'errors-only', '--output-path', tmpDir, '--output-filename', `${webpackTarget.name}.measure.js`, '--env', 'PRINT_WEBPACK_GRAPH' ], { cwd: path.resolve(__dirname, '..') }); let output = ''; child.stdout.on('data', chunk => { output += chunk.toString(); }); child.stderr.on('data', chunk => console.error(chunk.toString())); await new Promise((resolve, reject) => child.on('exit', (code) => { if (code !== 0) { console.error(output); return reject(new Error(`Failed to list webpack dependencies for entry: ${webpackTarget.name}`)); } resolve(); })); const webpackTargetWithDeps = { ...webpackTarget, dependencies: (JSON.parse(output) as string[]) // Remove whitespace .map(line => line.trim()) // Get the relative path .map(line => path.relative(rootPath, line).replace(/\\/g, '/')) // Only care about files in //electron .filter(line => !line.startsWith('..')) // Only care about our own files .filter(line => !line.startsWith('node_modules')) // All webpack builds depend on the tsconfig and package json files .concat(['tsconfig.json', 'tsconfig.electron.json', 'package.json', ...typingFiles]) // Make the generated list easier to read .sort() }; await fs.remove(tmpDir); return webpackTargetWithDeps; })); fs.writeFileSync( gniPath, `# THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT BY HAND auto_filenames = { api_docs = [ ${allDocs.map(doc => ` "${doc}",`).join('\n')} ] ${webpackTargetsWithDeps.map(target => ` ${target.name} = [ ${target.dependencies.map(dep => ` "${dep}",`).join('\n')} ]`).join('\n\n')} } `); }; if (require.main === module) { main().catch((err) => { console.error(err); process.exit(1); }); }