refactor: bundle the browser and renderer process electron code (#18553)
* refactor: bundle the browser and renderer process electron code * Bundles browser/init and renderer/init * Improves load performance of main process by ~40% * Improves load performance of renderer process by ~30% * Prevents users from importing our "requiring" our internal logic such as ipc-main-internal. This makes those message buses safer as they are less accessible, there is still some more work to be done though to lock down those buses completely. * The electron.asar file now only contains 2 files, as a future improvement maybe we can use atom_natives to ship these two files embedded in the binary * This also removes our dependency on browserify which had some strange edge cases that caused us to have to hack around require-order and stopped us using certain ES6/7 features we should have been able to use (async / await in some files in the sandboxed renderer init script) TLDR: Things are faster and better :) * fix: I really do not want to talk about it * chore: add performance improvements from debugging * fix: resolve the provided path so webpack thinks it is absolute * chore: fixup per PR review * fix: use webpacks ProvidePlugin to keep global, process and Buffer alive after deletion from global scope for use in internal code * fix: bundle worker/init as well to make node-in-workers work * chore: update wording as per feedback * chore: make the timers hack work when yarn is not used
This commit is contained in:
parent
a19e55a902
commit
bc527f6b51
40 changed files with 1612 additions and 920 deletions
2
build/webpack/get-outputs.js
Normal file
2
build/webpack/get-outputs.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
process.env.PRINT_WEBPACK_GRAPH = true
|
||||
require('./run-compiler')
|
22
build/webpack/run-compiler.js
Normal file
22
build/webpack/run-compiler.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
|
||||
const configPath = process.argv[2]
|
||||
const outPath = path.resolve(process.argv[3])
|
||||
const config = require(configPath)
|
||||
config.output = {
|
||||
path: path.dirname(outPath),
|
||||
filename: path.basename(outPath)
|
||||
}
|
||||
|
||||
webpack(config, (err, stats) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
} else if (stats.hasErrors()) {
|
||||
console.error(stats.toString('normal'))
|
||||
process.exit(1)
|
||||
} else {
|
||||
process.exit(0)
|
||||
}
|
||||
})
|
80
build/webpack/webpack.config.base.js
Normal file
80
build/webpack/webpack.config.base.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
|
||||
const electronRoot = path.resolve(__dirname, '../..')
|
||||
|
||||
const onlyPrintingGraph = !!process.env.PRINT_WEBPACK_GRAPH
|
||||
|
||||
class AccessDependenciesPlugin {
|
||||
apply(compiler) {
|
||||
// Only hook into webpack when we are printing the dependency graph
|
||||
if (!onlyPrintingGraph) return
|
||||
|
||||
compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
|
||||
compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
|
||||
const filePaths = modules.map(m => m.resource).filter(p => p).map(p => path.relative(electronRoot, p))
|
||||
console.info(JSON.stringify(filePaths))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ({
|
||||
alwaysHasNode,
|
||||
loadElectronFromAlternateTarget,
|
||||
targetDeletesNodeGlobals,
|
||||
target
|
||||
}) => {
|
||||
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts')
|
||||
if (!fs.existsSync(entry)) {
|
||||
entry = path.resolve(electronRoot, 'lib', target, 'init.js')
|
||||
}
|
||||
|
||||
return ({
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map',
|
||||
entry,
|
||||
target: alwaysHasNode ? 'node' : 'web',
|
||||
output: {
|
||||
filename: `${target}.bundle.js`
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
||||
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.js'),
|
||||
// Force timers to resolve to our dependency that doens't use window.postMessage
|
||||
'timers': path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
|
||||
},
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.ts$/,
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
configFile: path.resolve(electronRoot, 'tsconfig.electron.json'),
|
||||
transpileOnly: onlyPrintingGraph,
|
||||
ignoreDiagnostics: [6059]
|
||||
}
|
||||
}]
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
// We provide our own "timers" import above, any usage of setImmediate inside
|
||||
// one of our renderer bundles should import it from the 'timers' package
|
||||
setImmediate: false,
|
||||
},
|
||||
plugins: [
|
||||
new AccessDependenciesPlugin(),
|
||||
...(targetDeletesNodeGlobals ? [
|
||||
new webpack.ProvidePlugin({
|
||||
process: ['@electron/internal/renderer/webpack-provider', 'process'],
|
||||
global: ['@electron/internal/renderer/webpack-provider', '_global'],
|
||||
Buffer: ['@electron/internal/renderer/webpack-provider', 'Buffer'],
|
||||
})
|
||||
] : [])
|
||||
]
|
||||
})
|
||||
}
|
4
build/webpack/webpack.config.browser.js
Normal file
4
build/webpack/webpack.config.browser.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = require('./webpack.config.base')({
|
||||
target: 'browser',
|
||||
alwaysHasNode: true
|
||||
})
|
4
build/webpack/webpack.config.content_script.js
Normal file
4
build/webpack/webpack.config.content_script.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = require('./webpack.config.base')({
|
||||
target: 'content_script',
|
||||
alwaysHasNode: false
|
||||
})
|
4
build/webpack/webpack.config.isolated_renderer.js
Normal file
4
build/webpack/webpack.config.isolated_renderer.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = require('./webpack.config.base')({
|
||||
target: 'isolated_renderer',
|
||||
alwaysHasNode: false
|
||||
})
|
5
build/webpack/webpack.config.renderer.js
Normal file
5
build/webpack/webpack.config.renderer.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
module.exports = require('./webpack.config.base')({
|
||||
target: 'renderer',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true
|
||||
})
|
4
build/webpack/webpack.config.sandboxed_renderer.js
Normal file
4
build/webpack/webpack.config.sandboxed_renderer.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = require('./webpack.config.base')({
|
||||
target: 'sandboxed_renderer',
|
||||
alwaysHasNode: false
|
||||
})
|
6
build/webpack/webpack.config.worker.js
Normal file
6
build/webpack/webpack.config.worker.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = require('./webpack.config.base')({
|
||||
target: 'worker',
|
||||
loadElectronFromAlternateTarget: 'renderer',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true
|
||||
})
|
35
build/webpack/webpack.gni
Normal file
35
build/webpack/webpack.gni
Normal file
|
@ -0,0 +1,35 @@
|
|||
import("../npm.gni")
|
||||
|
||||
template("webpack_build") {
|
||||
assert(defined(invoker.config_file), "Need webpack config file to run")
|
||||
assert(defined(invoker.out_file), "Need output file to run")
|
||||
assert(defined(invoker.inputs), "Need webpack inputs to run")
|
||||
|
||||
npm_action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"public_deps",
|
||||
])
|
||||
script = "webpack"
|
||||
|
||||
inputs = [
|
||||
invoker.config_file,
|
||||
"//electron/build/webpack/webpack.config.base.js",
|
||||
"//electron/tsconfig.json",
|
||||
"//electron/yarn.lock",
|
||||
"//electron/typings/internal-ambient.d.ts",
|
||||
"//electron/typings/internal-electron.d.ts",
|
||||
"//electron/typings/internal-helpers.d.ts",
|
||||
] + invoker.inputs
|
||||
|
||||
args = [
|
||||
rebase_path(invoker.config_file),
|
||||
rebase_path(invoker.out_file),
|
||||
]
|
||||
|
||||
outputs = [
|
||||
invoker.out_file,
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue