pulsar/script/lib/generate-startup-snapshot.js

343 lines
11 KiB
JavaScript

const childProcess = require('child_process');
const fs = require('fs');
const path = require('path');
const electronLink = require('electron-link');
const terser = require('terser');
const CONFIG = require('../config');
module.exports = function(packagedAppPath) {
const snapshotScriptPath = path.join(CONFIG.buildOutputPath, 'startup.js');
const coreModules = new Set([
'electron',
'atom',
'shell',
'WNdb',
'lapack',
'remote'
]);
const baseDirPath = path.join(CONFIG.intermediateAppPath, 'static');
let processedFiles = 0;
return electronLink({
baseDirPath,
mainPath: path.resolve(
baseDirPath,
'..',
'src',
'initialize-application-window.js'
),
cachePath: path.join(CONFIG.atomHomeDirPath, 'snapshot-cache'),
auxiliaryData: CONFIG.snapshotAuxiliaryData,
shouldExcludeModule: ({ requiringModulePath, requiredModulePath }) => {
if (processedFiles > 0) {
process.stdout.write('\r');
}
process.stdout.write(
`Generating snapshot script at "${snapshotScriptPath}" (${++processedFiles})`
);
const requiringModuleRelativePath = path.relative(
baseDirPath,
requiringModulePath
);
const requiredModuleRelativePath = path.relative(
baseDirPath,
requiredModulePath
);
return (
requiredModulePath.endsWith('.node') ||
coreModules.has(requiredModulePath) ||
requiringModuleRelativePath.endsWith(
path.join('node_modules/xregexp/xregexp-all.js')
) ||
(requiredModuleRelativePath.startsWith(path.join('..', 'src')) &&
requiredModuleRelativePath.endsWith('-element.js')) ||
requiredModuleRelativePath.startsWith(
path.join('..', 'node_modules', 'dugite')
) ||
requiredModuleRelativePath.startsWith(
path.join(
'..',
'node_modules',
'markdown-preview',
'node_modules',
'yaml-front-matter'
)
) ||
requiredModuleRelativePath.startsWith(
path.join(
'..',
'node_modules',
'markdown-preview',
'node_modules',
'cheerio'
)
) ||
requiredModuleRelativePath.startsWith(
path.join(
'..',
'node_modules',
'markdown-preview',
'node_modules',
'marked'
)
) ||
requiredModuleRelativePath.startsWith(
path.join('..', 'node_modules', 'typescript-simple')
) ||
requiredModuleRelativePath.endsWith(
path.join(
'node_modules',
'coffee-script',
'lib',
'coffee-script',
'register.js'
)
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'fs-extra', 'lib', 'index.js')
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'graceful-fs', 'graceful-fs.js')
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'htmlparser2', 'lib', 'index.js')
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'minimatch', 'minimatch.js')
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'request', 'index.js')
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'request', 'request.js')
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'superstring', 'index.js')
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'temp', 'lib', 'temp.js')
) ||
requiredModuleRelativePath.endsWith(
path.join('node_modules', 'parse5', 'lib', 'index.js')
) ||
requiredModuleRelativePath === path.join('..', 'exports', 'atom.js') ||
requiredModuleRelativePath ===
path.join('..', 'src', 'electron-shims.js') ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'atom-keymap',
'lib',
'command-event.js'
) ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'babel-core', 'index.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'debug', 'node.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'git-utils', 'src', 'git.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'glob', 'glob.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'iconv-lite', 'lib', 'index.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'less', 'index.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'less', 'lib', 'less', 'fs.js') ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'less',
'lib',
'less-node',
'index.js'
) ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'lodash.isequal', 'index.js') ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'node-fetch',
'lib',
'fetch-error.js'
) ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'oniguruma', 'src', 'oniguruma.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'resolve', 'index.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'resolve', 'lib', 'core.js') ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'settings-view',
'node_modules',
'glob',
'glob.js'
) ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'spell-check',
'lib',
'locale-checker.js'
) ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'spell-check',
'lib',
'system-checker.js'
) ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'spellchecker',
'lib',
'spellchecker.js'
) ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'spelling-manager',
'node_modules',
'natural',
'lib',
'natural',
'index.js'
) ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'tar', 'tar.js') ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'ls-archive',
'node_modules',
'tar',
'tar.js'
) ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'tmp', 'lib', 'tmp.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'tree-sitter', 'index.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'yauzl', 'index.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'winreg', 'lib', 'registry.js') ||
requiredModuleRelativePath ===
path.join('..', 'node_modules', 'scandal', 'lib', 'scandal.js') ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'@atom',
'fuzzy-native',
'lib',
'main.js'
) ||
requiredModuleRelativePath ===
path.join(
'..',
'node_modules',
'vscode-ripgrep',
'lib',
'index.js'
) ||
// The startup-time script is used by both the renderer and the main process and having it in the
// snapshot causes issues.
requiredModuleRelativePath === path.join('..', 'src', 'startup-time.js')
);
}
}).then(({ snapshotScript }) => {
process.stdout.write('\n');
process.stdout.write('Minifying startup script');
const minification = terser.minify(snapshotScript, {
keep_fnames: true,
keep_classnames: true,
compress: { keep_fargs: true, keep_infinity: true }
});
if (minification.error) throw minification.error;
process.stdout.write('\n');
fs.writeFileSync(snapshotScriptPath, minification.code);
console.log('Verifying if snapshot can be executed via `mksnapshot`');
const verifySnapshotScriptPath = path.join(
CONFIG.repositoryRootPath,
'script',
'verify-snapshot-script'
);
let nodeBundledInElectronPath;
if (process.platform === 'darwin') {
nodeBundledInElectronPath = path.join(
packagedAppPath,
'Contents',
'MacOS',
CONFIG.executableName
);
} else {
nodeBundledInElectronPath = path.join(
packagedAppPath,
CONFIG.executableName
);
}
childProcess.execFileSync(
nodeBundledInElectronPath,
[verifySnapshotScriptPath, snapshotScriptPath],
{ env: Object.assign({}, process.env, { ELECTRON_RUN_AS_NODE: 1 }) }
);
console.log('Generating startup blob with mksnapshot');
childProcess.spawnSync(process.execPath, [
path.join(
CONFIG.repositoryRootPath,
'script',
'node_modules',
'electron-mksnapshot',
'mksnapshot.js'
),
snapshotScriptPath,
'--output_dir',
CONFIG.buildOutputPath
]);
let startupBlobDestinationPath;
if (process.platform === 'darwin') {
startupBlobDestinationPath = `${packagedAppPath}/Contents/Frameworks/Electron Framework.framework/Resources`;
} else {
startupBlobDestinationPath = packagedAppPath;
}
const snapshotBinaries = ['v8_context_snapshot.bin', 'snapshot_blob.bin'];
for (let snapshotBinary of snapshotBinaries) {
const destinationPath = path.join(
startupBlobDestinationPath,
snapshotBinary
);
console.log(`Moving generated startup blob into "${destinationPath}"`);
try {
fs.unlinkSync(destinationPath);
} catch (err) {
// Doesn't matter if the file doesn't exist already
if (!err.code || err.code !== 'ENOENT') {
throw err;
}
}
fs.renameSync(
path.join(CONFIG.buildOutputPath, snapshotBinary),
destinationPath
);
}
});
};