From 681f0f9fe1ca40425342102f01b0f1f406013858 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 27 Feb 2017 14:47:20 +0100 Subject: [PATCH] Make Atom work also without a snapshot --- src/package.coffee | 3 +- static/index.js | 143 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 116 insertions(+), 30 deletions(-) diff --git a/src/package.coffee b/src/package.coffee index e34c70981..386cc0018 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -41,7 +41,8 @@ class Package @metadata ?= @packageManager.loadPackageMetadata(@path) @bundledPackage = @packageManager.isBundledPackagePath(@path) @name = @metadata?.name ? path.basename(@path) - # ModuleCache.add(@path, @metadata) + unless @bundledPackage + ModuleCache.add(@path, @metadata) @reset() ### diff --git a/static/index.js b/static/index.js index e1d06558f..9fbfbcea7 100644 --- a/static/index.js +++ b/static/index.js @@ -1,48 +1,133 @@ (function () { - let loadSettings - const Module = require('module') - const Path = require('path') - const vm = require('vm') - const {remote, ipcRenderer} = require('electron') + const path = require('path') + const getWindowLoadSettings = require('../src/get-window-load-settings') + const entryPointDirPath = __dirname + let blobStore = null + let devMode = false + let useSnapshot = false + let requireFunction = null + + window.onload = function () { + try { + var startTime = Date.now() - if (typeof snapshotResult !== 'undefined') { - window.onload = function () { - process.resourcesPath = Path.normalize(process.resourcesPath) process.on('unhandledRejection', function (error, promise) { console.error('Unhandled promise rejection %o with error: %o', promise, error) }) - loadSettings = remote.getCurrentWindow().loadSettings + // Normalize to make sure drive letter case is consistent on Windows + process.resourcesPath = path.normalize(process.resourcesPath) - if (!process.env.ATOM_HOME) { - // Ensure ATOM_HOME is always set before anything else is required - // This is because of a difference in Linux not inherited between browser and render processes - // https://github.com/atom/atom/issues/5412 - if (loadSettings && loadSettings.atomHome) { - process.env.ATOM_HOME = loadSettings.atomHome + setupAtomHome() + devMode = getWindowLoadSettings().devMode || !getWindowLoadSettings().resourcePath.startsWith(process.resourcesPath + path.sep) + useSnapshot = !devMode && typeof snapshotResult !== 'undefined' + requireFunction = useSnapshot ? snapshotResult.customRequire : require + + if (devMode) { + var metadata = require('../package.json') + if (!metadata._deprecatedPackages) { + try { + metadata._deprecatedPackages = require('../script/deprecated-packages.json') + } catch (requireError) { + console.error('Failed to setup deprecated packages list', requireError.stack) + } } + } else if (useSnapshot) { + Module.prototype.require = function (modulePath) { + const absoluteFilePath = Module._resolveFilename(modulePath, this, false) + const relativeFilePath = path.relative(entryPointDirPath, absoluteFilePath) + return snapshotResult.customRequire(relativeFilePath) + } + + snapshotResult.setGlobals(global, process, window, document, Module._load) } - require('../src/crash-reporter-start')({_version: loadSettings.appVersion}) + const FileSystemBlobStore = requireFunction('../src/file-system-blob-store.js') + blobStore = FileSystemBlobStore.load( + path.join(process.env.ATOM_HOME, 'blob-store/') + ) - const entryPointDirPath = __dirname - Module.prototype.require = function (path) { - const absoluteFilePath = Module._resolveFilename(path, this, false) - const relativeFilePath = Path.relative(entryPointDirPath, absoluteFilePath) - const cachedModule = snapshotResult.customRequire.cache[relativeFilePath] - return cachedModule ? cachedModule : Module._load(path, this, false) + const NativeCompileCache = requireFunction('../src/native-compile-cache.js') + NativeCompileCache.setCacheStore(blobStore) + NativeCompileCache.setV8Version(process.versions.v8) + NativeCompileCache.install() + + if (getWindowLoadSettings().profileStartup) { + profileStartup(Date.now() - startTime) + } else { + setupWindow() + setLoadTime(Date.now() - startTime) } + } catch (error) { + handleSetupError(error) + } + } - snapshotResult.setGlobals(global, process, window, document, require) + function setLoadTime (loadTime) { + if (global.atom) { + global.atom.loadTime = loadTime + } + } - const CSON = snapshotResult.customRequire("../node_modules/season/lib/cson.js") - CSON.setCacheDir(Path.join(process.env.ATOM_HOME, 'compile-cache', 'cson')) + function handleSetupError (error) { + const currentWindow = require('electron').remote.getCurrentWindow() + currentWindow.setSize(800, 600) + currentWindow.center() + currentWindow.show() + currentWindow.openDevTools() + console.error(error.stack || error) + } - const CompileCache = snapshotResult.customRequire('../src/compile-cache.js') - CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME) + function setupWindow () { + const CompileCache = requireFunction('../src/compile-cache.js') + CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME) - const initialize = snapshotResult.customRequire('../src/initialize-application-window.js') - initialize().then(() => { ipcRenderer.send('window-command', 'window:loaded') }) + const ModuleCache = requireFunction('../src/module-cache.js') + ModuleCache.register(getWindowLoadSettings()) + + const startCrashReporter = requireFunction('../src/crash-reporter-start.js') + startCrashReporter({_version: getWindowLoadSettings().appVersion}) + + const CSON = requireFunction(useSnapshot ? '../node_modules/season/lib/cson.js' : 'season') + CSON.setCacheDir(path.join(CompileCache.getCacheDirectory(), 'cson')) + + const initScriptPath = path.relative(entryPointDirPath, getWindowLoadSettings().windowInitializationScript) + const initialize = requireFunction(initScriptPath) + return initialize({blobStore: blobStore}).then(function () { + require('electron').ipcRenderer.send('window-command', 'window:loaded') + }) + } + + function profileStartup (initialTime) { + function profile () { + console.profile('startup') + var startTime = Date.now() + setupWindow().then(function () { + setLoadTime(Date.now() - startTime + initialTime) + console.profileEnd('startup') + console.log('Switch to the Profiles tab to view the created startup profile') + }) + } + + const webContents = require('electron').remote.getCurrentWindow().webContents + if (webContents.devToolsWebContents) { + profile() + } else { + webContents.once('devtools-opened', () => { setTimeout(profile, 1000) }) + webContents.openDevTools() + } + } + + function setupAtomHome () { + if (process.env.ATOM_HOME) { + return + } + + // Ensure ATOM_HOME is always set before anything else is required + // This is because of a difference in Linux not inherited between browser and render processes + // https://github.com/atom/atom/issues/5412 + if (getWindowLoadSettings() && getWindowLoadSettings().atomHome) { + process.env.ATOM_HOME = getWindowLoadSettings().atomHome } } })()