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:
Samuel Attard 2019-06-02 13:03:03 -07:00 committed by GitHub
parent a19e55a902
commit bc527f6b51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 1612 additions and 920 deletions

172
BUILD.gn
View file

@ -10,9 +10,9 @@ import("//tools/grit/repack.gni")
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
import("//v8/gni/snapshot_toolchain.gni")
import("build/asar.gni")
import("build/js_wrap.gni")
import("build/npm.gni")
import("build/tsc.gni")
import("build/webpack/webpack.gni")
import("buildflags/buildflags.gni")
import("electron_paks.gni")
import("filenames.auto.gni")
@ -71,135 +71,70 @@ npm_action("build_electron_definitions") {
]
}
npm_action("atom_browserify_sandbox_unwrapped") {
script = "browserify"
webpack_build("electron_browser_bundle") {
deps = [
":build_electron_definitions",
]
inputs = auto_filenames.sandbox_browserify_deps
inputs = auto_filenames.browser_bundle_deps
outputs = [
"$target_gen_dir/js2c/sandbox_bundle_unwrapped.js",
]
args = [
"lib/sandboxed_renderer/init.js",
"-r",
"./lib/sandboxed_renderer/api/exports/electron.js:electron",
"-t",
"aliasify",
"-p",
"[",
"tsify",
"-p",
"tsconfig.electron.json",
"]",
"--standalone",
"sandboxed_preload",
"-o",
rebase_path(outputs[0]),
]
config_file = "//electron/build/webpack/webpack.config.browser.js"
out_file = "$target_gen_dir/electron_asar/browser/init.js"
}
npm_action("atom_browserify_isolated_unwrapped") {
script = "browserify"
webpack_build("electron_renderer_bundle") {
deps = [
":build_electron_definitions",
]
inputs = auto_filenames.isolated_browserify_deps
inputs = auto_filenames.renderer_bundle_deps
outputs = [
"$target_gen_dir/js2c/isolated_bundle_unwrapped.js",
]
args = [
"lib/isolated_renderer/init.js",
"-t",
"aliasify",
"-p",
"[",
"tsify",
"-p",
"tsconfig.electron.json",
"]",
"--standalone",
"isolated_preload",
"-o",
rebase_path(outputs[0]),
]
config_file = "//electron/build/webpack/webpack.config.renderer.js"
out_file = "$target_gen_dir/electron_asar/renderer/init.js"
}
npm_action("atom_browserify_content_script_unwrapped") {
script = "browserify"
webpack_build("electron_worker_bundle") {
deps = [
":build_electron_definitions",
]
inputs = auto_filenames.context_script_browserify_deps
inputs = auto_filenames.worker_bundle_deps
outputs = [
"$target_gen_dir/js2c/content_script_bundle_unwrapped.js",
]
args = [
"lib/content_script/init.js",
"-t",
"aliasify",
"-p",
"[",
"tsify",
"-p",
"tsconfig.electron.json",
"]",
"--standalone",
"content_script_preload",
"-o",
rebase_path(outputs[0]),
]
config_file = "//electron/build/webpack/webpack.config.worker.js"
out_file = "$target_gen_dir/electron_asar/worker/init.js"
}
js_wrap("atom_browserify_content_script") {
webpack_build("electron_sandboxed_renderer_bundle") {
deps = [
":atom_browserify_content_script_unwrapped",
":build_electron_definitions",
]
inputs = [
"$target_gen_dir/js2c/content_script_bundle_unwrapped.js",
]
inputs = auto_filenames.sandbox_bundle_deps
outputs = [
"$target_gen_dir/js2c/content_script_bundle.js",
]
config_file = "//electron/build/webpack/webpack.config.sandboxed_renderer.js"
out_file = "$target_gen_dir/js2c/sandbox_bundle.js"
}
js_wrap("atom_browserify_isolated") {
webpack_build("electron_isolated_renderer_bundle") {
deps = [
":atom_browserify_isolated_unwrapped",
":build_electron_definitions",
]
inputs = [
"$target_gen_dir/js2c/isolated_bundle_unwrapped.js",
]
inputs = auto_filenames.isolated_bundle_deps
outputs = [
"$target_gen_dir/js2c/isolated_bundle.js",
]
config_file = "//electron/build/webpack/webpack.config.isolated_renderer.js"
out_file = "$target_gen_dir/js2c/isolated_bundle.js"
}
js_wrap("atom_browserify_sandbox") {
webpack_build("electron_content_script_bundle") {
deps = [
":atom_browserify_sandbox_unwrapped",
":build_electron_definitions",
]
inputs = [
"$target_gen_dir/js2c/sandbox_bundle_unwrapped.js",
]
inputs = auto_filenames.content_script_bundle_deps
outputs = [
"$target_gen_dir/js2c/sandbox_bundle.js",
]
config_file = "//electron/build/webpack/webpack.config.content_script.js"
out_file = "$target_gen_dir/js2c/content_script_bundle.js"
}
copy("atom_js2c_copy") {
@ -214,19 +149,19 @@ copy("atom_js2c_copy") {
action("atom_js2c") {
deps = [
":atom_browserify_content_script",
":atom_browserify_isolated",
":atom_browserify_sandbox",
":atom_js2c_copy",
":electron_content_script_bundle",
":electron_isolated_renderer_bundle",
":electron_sandboxed_renderer_bundle",
]
browserify_sources = [
webpack_sources = [
"$target_gen_dir/js2c/content_script_bundle.js",
"$target_gen_dir/js2c/isolated_bundle.js",
"$target_gen_dir/js2c/sandbox_bundle.js",
]
sources = browserify_sources + [
sources = webpack_sources + [
"$target_gen_dir/js2c/asar.js",
"$target_gen_dir/js2c/asar_init.js",
]
@ -242,46 +177,19 @@ action("atom_js2c") {
rebase_path(sources, root_build_dir)
}
target_gen_electron_js = "$target_gen_dir/js/electron"
target_gen_default_app_js = "$target_gen_dir/js/default_app"
typescript_build("lib_js") {
deps = [
":build_electron_definitions",
]
type_root = rebase_path("$target_gen_dir/tsc/electron/typings")
sources = filenames.js_sources
if (enable_desktop_capturer) {
sources += [
"lib/browser/desktop-capturer.js",
"lib/renderer/api/desktop-capturer.js",
]
}
if (enable_view_api) {
sources += [
"lib/browser/api/views/box-layout.js",
"lib/browser/api/views/button.js",
"lib/browser/api/views/label-button.js",
"lib/browser/api/views/layout-manager.js",
"lib/browser/api/views/md-text-button.js",
"lib/browser/api/views/resize-area.js",
"lib/browser/api/views/text-field.js",
]
}
output_gen_dir = target_gen_electron_js
output_dir_name = "lib"
tsconfig = "tsconfig.electron.json"
}
asar("electron_asar") {
deps = [
":lib_js",
":electron_browser_bundle",
":electron_renderer_bundle",
":electron_worker_bundle",
]
root = "$target_gen_electron_js/electron/lib"
sources = get_target_outputs(":lib_js")
root = "$target_gen_dir/electron_asar"
sources = get_target_outputs(":electron_browser_bundle") +
get_target_outputs(":electron_renderer_bundle") +
get_target_outputs(":electron_worker_bundle")
outputs = [
"$root_out_dir/resources/electron.asar",
]

View file

@ -1,19 +0,0 @@
template("js_wrap") {
assert(defined(invoker.inputs), "Need input JS script")
assert(defined(invoker.outputs), "Need output JS script")
action(target_name) {
forward_variables_from(invoker,
[
"deps",
"public_deps",
"sources",
"inputs",
"outputs",
])
script = "//electron/build/js_wrap.py"
args = [ "--in" ] + rebase_path(invoker.inputs) + [ "--out" ] +
rebase_path(invoker.outputs)
}
}

View file

@ -1,19 +0,0 @@
import sys
in_start = sys.argv.index("--in") + 1
out_start = sys.argv.index("--out") + 1
in_bundles = sys.argv[in_start:out_start - 1]
out_bundles = sys.argv[out_start:]
if len(in_bundles) != len(out_bundles):
print("--out and --in must provide the same number of arguments")
sys.exit(1)
for i in range(len(in_bundles)):
in_bundle = in_bundles[i]
out_path = out_bundles[i]
with open(in_bundle, 'r') as f:
lines = ["(function(){var exports={},module={exports};"] + f.readlines() + ["})();"]
with open(out_path, 'w') as out_f:
out_f.writelines(lines)

View file

@ -0,0 +1,2 @@
process.env.PRINT_WEBPACK_GRAPH = true
require('./run-compiler')

View 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)
}
})

View 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'],
})
] : [])
]
})
}

View file

@ -0,0 +1,4 @@
module.exports = require('./webpack.config.base')({
target: 'browser',
alwaysHasNode: true
})

View file

@ -0,0 +1,4 @@
module.exports = require('./webpack.config.base')({
target: 'content_script',
alwaysHasNode: false
})

View file

@ -0,0 +1,4 @@
module.exports = require('./webpack.config.base')({
target: 'isolated_renderer',
alwaysHasNode: false
})

View file

@ -0,0 +1,5 @@
module.exports = require('./webpack.config.base')({
target: 'renderer',
alwaysHasNode: true,
targetDeletesNodeGlobals: true
})

View file

@ -0,0 +1,4 @@
module.exports = require('./webpack.config.base')({
target: 'sandboxed_renderer',
alwaysHasNode: false
})

View 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
View 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,
]
}
}

View file

@ -119,8 +119,7 @@ Important things to notice in the preload script:
`remote` and `ipcRenderer` modules.
- The preload script must be contained in a single script, but it is possible to have
complex preload code composed with multiple modules by using a tool like
browserify, as explained below. In fact, browserify is already used by
Electron to provide a node-like environment to the preload script.
webpack or browserify. An example of using browserify is below.
To create a browserify bundle and use it as a preload script, something like
the following should be used:

View file

@ -112,13 +112,16 @@ auto_filenames = {
"docs/api/structures/web-source.md",
]
sandbox_browserify_deps = [
"lib/browser/api/module-list.js",
sandbox_bundle_deps = [
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/is-promise.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.js",
"lib/common/clipboard-utils.js",
"lib/common/crash-reporter.js",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.js",
@ -142,29 +145,31 @@ auto_filenames = {
"lib/renderer/web-frame-init.ts",
"lib/renderer/web-view/guest-view-internal.ts",
"lib/renderer/web-view/web-view-attributes.ts",
"lib/renderer/web-view/web-view-constants.ts",
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/web-view/web-view-impl.ts",
"lib/renderer/web-view/web-view-init.ts",
"lib/sandboxed_renderer/api/exports/electron.js",
"lib/sandboxed_renderer/api/module-list.js",
"lib/sandboxed_renderer/init.js",
"tsconfig.json",
"tsconfig.electron.json",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
]
isolated_browserify_deps = [
isolated_bundle_deps = [
"lib/common/electron-binding-setup.ts",
"lib/isolated_renderer/init.js",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/web-view/web-view-constants.ts",
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/window-setup.ts",
"tsconfig.json",
"tsconfig.electron.json",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
]
context_script_browserify_deps = [
content_script_bundle_deps = [
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.js",
"lib/content_script/init.js",
@ -176,8 +181,172 @@ auto_filenames = {
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/window-setup.ts",
"tsconfig.json",
"tsconfig.electron.json",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
]
browser_bundle_deps = [
"lib/browser/api/app.ts",
"lib/browser/api/auto-updater.js",
"lib/browser/api/auto-updater/auto-updater-native.js",
"lib/browser/api/auto-updater/auto-updater-win.js",
"lib/browser/api/auto-updater/squirrel-update-win.js",
"lib/browser/api/browser-view.js",
"lib/browser/api/browser-window.js",
"lib/browser/api/content-tracing.js",
"lib/browser/api/crash-reporter.js",
"lib/browser/api/dialog.js",
"lib/browser/api/exports/electron.js",
"lib/browser/api/global-shortcut.js",
"lib/browser/api/in-app-purchase.js",
"lib/browser/api/ipc-main.ts",
"lib/browser/api/menu-item-roles.js",
"lib/browser/api/menu-item.js",
"lib/browser/api/menu-utils.js",
"lib/browser/api/menu.js",
"lib/browser/api/module-list.js",
"lib/browser/api/net-log.js",
"lib/browser/api/net.js",
"lib/browser/api/notification.js",
"lib/browser/api/power-monitor.ts",
"lib/browser/api/power-save-blocker.js",
"lib/browser/api/protocol.ts",
"lib/browser/api/screen.ts",
"lib/browser/api/session.js",
"lib/browser/api/system-preferences.js",
"lib/browser/api/top-level-window.js",
"lib/browser/api/touch-bar.js",
"lib/browser/api/tray.js",
"lib/browser/api/view.js",
"lib/browser/api/views/box-layout.js",
"lib/browser/api/views/button.js",
"lib/browser/api/views/label-button.js",
"lib/browser/api/views/layout-manager.js",
"lib/browser/api/views/md-text-button.js",
"lib/browser/api/views/resize-area.js",
"lib/browser/api/views/text-field.js",
"lib/browser/api/web-contents-view.js",
"lib/browser/api/web-contents.js",
"lib/browser/chrome-extension.js",
"lib/browser/crash-reporter-init.js",
"lib/browser/default-menu.ts",
"lib/browser/desktop-capturer.js",
"lib/browser/devtools.js",
"lib/browser/guest-view-manager.js",
"lib/browser/guest-window-manager.js",
"lib/browser/init.ts",
"lib/browser/ipc-main-internal-utils.ts",
"lib/browser/ipc-main-internal.ts",
"lib/browser/navigation-controller.js",
"lib/browser/objects-registry.js",
"lib/browser/rpc-server.js",
"lib/browser/utils.ts",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/is-promise.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.js",
"lib/common/clipboard-utils.js",
"lib/common/crash-reporter.js",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.js",
"lib/common/init.ts",
"lib/common/parse-features-string.js",
"lib/common/path-utils.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.js",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
]
renderer_bundle_deps = [
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/is-promise.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.js",
"lib/common/clipboard-utils.js",
"lib/common/crash-reporter.js",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.js",
"lib/common/init.ts",
"lib/common/path-utils.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.js",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.js",
"lib/renderer/api/exports/electron.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.js",
"lib/renderer/chrome-api.ts",
"lib/renderer/content-scripts-injector.ts",
"lib/renderer/extensions/event.js",
"lib/renderer/extensions/i18n.js",
"lib/renderer/extensions/storage.js",
"lib/renderer/extensions/web-navigation.js",
"lib/renderer/init.ts",
"lib/renderer/inspector.ts",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/security-warnings.ts",
"lib/renderer/web-frame-init.ts",
"lib/renderer/web-view/guest-view-internal.ts",
"lib/renderer/web-view/web-view-attributes.ts",
"lib/renderer/web-view/web-view-constants.ts",
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/web-view/web-view-impl.ts",
"lib/renderer/web-view/web-view-init.ts",
"lib/renderer/webpack-provider.ts",
"lib/renderer/window-setup.ts",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
]
worker_bundle_deps = [
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/is-promise.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.js",
"lib/common/clipboard-utils.js",
"lib/common/crash-reporter.js",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.js",
"lib/common/init.ts",
"lib/common/reset-search-paths.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.js",
"lib/renderer/api/exports/electron.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.js",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/webpack-provider.ts",
"lib/worker/init.js",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
]
}

View file

@ -1,98 +1,4 @@
filenames = {
js_sources = [
"lib/browser/api/app.ts",
"lib/browser/api/auto-updater.js",
"lib/browser/api/auto-updater/auto-updater-native.js",
"lib/browser/api/auto-updater/auto-updater-win.js",
"lib/browser/api/auto-updater/squirrel-update-win.js",
"lib/browser/api/browser-view.js",
"lib/browser/api/browser-window.js",
"lib/browser/api/content-tracing.js",
"lib/browser/api/crash-reporter.js",
"lib/browser/api/dialog.js",
"lib/browser/api/exports/electron.js",
"lib/browser/api/global-shortcut.js",
"lib/browser/api/ipc-main.ts",
"lib/browser/api/in-app-purchase.js",
"lib/browser/api/menu-item-roles.js",
"lib/browser/api/menu-item.js",
"lib/browser/api/menu-utils.js",
"lib/browser/api/menu.js",
"lib/browser/api/module-list.js",
"lib/browser/api/net.js",
"lib/browser/api/net-log.js",
"lib/browser/api/notification.js",
"lib/browser/api/power-monitor.ts",
"lib/browser/api/power-save-blocker.js",
"lib/browser/api/protocol.ts",
"lib/browser/api/screen.ts",
"lib/browser/api/session.js",
"lib/browser/api/system-preferences.js",
"lib/browser/api/top-level-window.js",
"lib/browser/api/touch-bar.js",
"lib/browser/api/tray.js",
"lib/browser/api/view.js",
"lib/browser/api/web-contents.js",
"lib/browser/api/web-contents-view.js",
"lib/browser/devtools.js",
"lib/browser/chrome-extension.js",
"lib/browser/crash-reporter-init.js",
"lib/browser/default-menu.ts",
"lib/browser/guest-view-manager.js",
"lib/browser/guest-window-manager.js",
"lib/browser/init.ts",
"lib/browser/ipc-main-internal-utils.ts",
"lib/browser/ipc-main-internal.ts",
"lib/browser/navigation-controller.js",
"lib/browser/objects-registry.js",
"lib/browser/rpc-server.js",
"lib/browser/utils.ts",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/is-promise.js",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.js",
"lib/common/clipboard-utils.js",
"lib/common/crash-reporter.js",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.js",
"lib/common/init.ts",
"lib/common/parse-features-string.js",
"lib/common/path-utils.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.js",
"lib/renderer/callbacks-registry.js",
"lib/renderer/chrome-api.ts",
"lib/renderer/content-scripts-injector.ts",
"lib/renderer/init.ts",
"lib/renderer/inspector.ts",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/security-warnings.ts",
"lib/renderer/window-setup.ts",
"lib/renderer/web-frame-init.ts",
"lib/renderer/web-view/guest-view-internal.ts",
"lib/renderer/web-view/web-view-attributes.ts",
"lib/renderer/web-view/web-view-constants.ts",
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/web-view/web-view-impl.ts",
"lib/renderer/web-view/web-view-init.ts",
"lib/renderer/api/exports/electron.js",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/extensions/event.js",
"lib/renderer/extensions/i18n.js",
"lib/renderer/extensions/storage.js",
"lib/renderer/extensions/web-navigation.js",
"lib/worker/init.js",
]
default_app_ts_sources = [
"default_app/default_app.ts",
"default_app/index.ts",

View file

@ -1,6 +1,6 @@
import * as path from 'path'
import * as electron from 'electron'
import { deprecate, Menu } from 'electron'
import { EventEmitter } from 'events'
const bindings = process.electronBinding('app')
@ -10,8 +10,6 @@ const { app, App } = bindings
// Only one app object permitted.
export default app
const { deprecate, Menu } = electron
let dockMenu: Electron.Menu | null = null
// App is an EventEmitter.

View file

@ -10,11 +10,6 @@ common.defineProperties(exports)
for (const module of moduleList) {
Object.defineProperty(exports, module.name, {
enumerable: !module.private,
get: common.memoizedGetter(() => {
const value = require(`@electron/internal/browser/api/${module.file}.js`)
// Handle Typescript modules with an "export default X" statement
if (value.__esModule) return value.default
return value
})
get: common.handleESModule(module.loader)
})
}

View file

@ -0,0 +1,51 @@
'use strict'
// TODO: Figure out a way to not duplicate this information between here and module-list
// It is currently duplicated as module-list "require"s all the browser API file and the
// remote module in the renderer process depends on that file. As a result webpack
// includes all the browser API files in the renderer process as well and we want to avoid that
const features = process.electronBinding('features')
// Browser side modules, please sort alphabetically.
module.exports = [
{ name: 'app' },
{ name: 'autoUpdater' },
{ name: 'BrowserView' },
{ name: 'BrowserWindow' },
{ name: 'contentTracing' },
{ name: 'crashReporter' },
{ name: 'dialog' },
{ name: 'globalShortcut' },
{ name: 'ipcMain' },
{ name: 'inAppPurchase' },
{ name: 'Menu' },
{ name: 'MenuItem' },
{ name: 'net' },
{ name: 'netLog' },
{ name: 'Notification' },
{ name: 'powerMonitor' },
{ name: 'powerSaveBlocker' },
{ name: 'protocol' },
{ name: 'screen' },
{ name: 'session' },
{ name: 'systemPreferences' },
{ name: 'TopLevelWindow' },
{ name: 'TouchBar' },
{ name: 'Tray' },
{ name: 'View' },
{ name: 'webContents' },
{ name: 'WebContentsView' }
]
if (features.isViewApiEnabled()) {
module.exports.push(
{ name: 'BoxLayout' },
{ name: 'Button' },
{ name: 'LabelButton' },
{ name: 'LayoutManager' },
{ name: 'MdTextButton' },
{ name: 'ResizeArea' },
{ name: 'TextField' }
)
}

View file

@ -1,46 +1,48 @@
'use strict'
// TODO: Updating this file also required updating the module-keys file
const features = process.electronBinding('features')
// Browser side modules, please sort alphabetically.
module.exports = [
{ name: 'app', file: 'app' },
{ name: 'autoUpdater', file: 'auto-updater' },
{ name: 'BrowserView', file: 'browser-view' },
{ name: 'BrowserWindow', file: 'browser-window' },
{ name: 'contentTracing', file: 'content-tracing' },
{ name: 'crashReporter', file: 'crash-reporter' },
{ name: 'dialog', file: 'dialog' },
{ name: 'globalShortcut', file: 'global-shortcut' },
{ name: 'ipcMain', file: 'ipc-main' },
{ name: 'inAppPurchase', file: 'in-app-purchase' },
{ name: 'Menu', file: 'menu' },
{ name: 'MenuItem', file: 'menu-item' },
{ name: 'net', file: 'net' },
{ name: 'netLog', file: 'net-log' },
{ name: 'Notification', file: 'notification' },
{ name: 'powerMonitor', file: 'power-monitor' },
{ name: 'powerSaveBlocker', file: 'power-save-blocker' },
{ name: 'protocol', file: 'protocol' },
{ name: 'screen', file: 'screen' },
{ name: 'session', file: 'session' },
{ name: 'systemPreferences', file: 'system-preferences' },
{ name: 'TopLevelWindow', file: 'top-level-window' },
{ name: 'TouchBar', file: 'touch-bar' },
{ name: 'Tray', file: 'tray' },
{ name: 'View', file: 'view' },
{ name: 'webContents', file: 'web-contents' },
{ name: 'WebContentsView', file: 'web-contents-view' }
{ name: 'app', loader: () => require('./app') },
{ name: 'autoUpdater', loader: () => require('./auto-updater') },
{ name: 'BrowserView', loader: () => require('./browser-view') },
{ name: 'BrowserWindow', loader: () => require('./browser-window') },
{ name: 'contentTracing', loader: () => require('./content-tracing') },
{ name: 'crashReporter', loader: () => require('./crash-reporter') },
{ name: 'dialog', loader: () => require('./dialog') },
{ name: 'globalShortcut', loader: () => require('./global-shortcut') },
{ name: 'ipcMain', loader: () => require('./ipc-main') },
{ name: 'inAppPurchase', loader: () => require('./in-app-purchase') },
{ name: 'Menu', loader: () => require('./menu') },
{ name: 'MenuItem', loader: () => require('./menu-item') },
{ name: 'net', loader: () => require('./net') },
{ name: 'netLog', loader: () => require('./net-log') },
{ name: 'Notification', loader: () => require('./notification') },
{ name: 'powerMonitor', loader: () => require('./power-monitor') },
{ name: 'powerSaveBlocker', loader: () => require('./power-save-blocker') },
{ name: 'protocol', loader: () => require('./protocol') },
{ name: 'screen', loader: () => require('./screen') },
{ name: 'session', loader: () => require('./session') },
{ name: 'systemPreferences', loader: () => require('./system-preferences') },
{ name: 'TopLevelWindow', loader: () => require('./top-level-window') },
{ name: 'TouchBar', loader: () => require('./touch-bar') },
{ name: 'Tray', loader: () => require('./tray') },
{ name: 'View', loader: () => require('./view') },
{ name: 'webContents', loader: () => require('./web-contents') },
{ name: 'WebContentsView', loader: () => require('./web-contents-view') }
]
if (features.isViewApiEnabled()) {
module.exports.push(
{ name: 'BoxLayout', file: 'views/box-layout' },
{ name: 'Button', file: 'views/button' },
{ name: 'LabelButton', file: 'views/label-button' },
{ name: 'LayoutManager', file: 'views/layout-manager' },
{ name: 'MdTextButton', file: 'views/md-text-button' },
{ name: 'ResizeArea', file: 'views/resize-area' },
{ name: 'TextField', file: 'views/text-field' }
{ name: 'BoxLayout', loader: () => require('./views/box-layout') },
{ name: 'Button', loader: () => require('./views/button') },
{ name: 'LabelButton', loader: () => require('./views/label-button') },
{ name: 'LayoutManager', loader: () => require('./views/layout-manager') },
{ name: 'MdTextButton', loader: () => require('./views/md-text-button') },
{ name: 'ResizeArea', loader: () => require('./views/resize-area') },
{ name: 'TextField', loader: () => require('./views/text-field') }
)
}

View file

@ -2,14 +2,15 @@
const { app } = require('electron')
const cp = require('child_process')
const os = require('os')
const path = require('path')
const getTempDirectory = function () {
try {
return app.getPath('temp')
} catch {
return os.tmpdir()
// Delibrately laze-load the os module, this file is on the hot
// path when booting Electron and os takes between 5 - 8ms to load and we do not need it yet
return require('os').tmpdir()
}
}

View file

@ -16,11 +16,6 @@ require('../common/reset-search-paths')
// Import common settings.
require('@electron/internal/common/init')
const globalPaths = Module.globalPaths
// Expose public APIs.
globalPaths.push(path.join(__dirname, 'api', 'exports'))
if (process.platform === 'win32') {
// Redirect node's console to use our own implementations, since node can not
// handle console output when running as GUI program.
@ -112,7 +107,7 @@ if (process.resourcesPath) {
for (packagePath of searchPaths) {
try {
packagePath = path.join(process.resourcesPath, packagePath)
packageJson = require(path.join(packagePath, 'package.json'))
packageJson = __non_webpack_require__(path.join(packagePath, 'package.json')) // eslint-disable-line
break
} catch {
continue
@ -194,7 +189,7 @@ app.on('window-all-closed', () => {
Promise.all([
import('@electron/internal/browser/default-menu'),
app.whenReady
app.whenReady()
]).then(([{ setDefaultApplicationMenu }]) => {
// Create default menu
setDefaultApplicationMenu()

View file

@ -2,6 +2,12 @@
const moduleList = require('@electron/internal/common/api/module-list')
exports.handleESModule = (loader) => () => {
const value = loader()
if (value.__esModule) return value.default
return value
}
exports.memoizedGetter = (getter) => {
/*
* It's ok to leak this value as it would be leaked by the global
@ -24,12 +30,7 @@ exports.defineProperties = function (targetExports) {
for (const module of moduleList) {
descriptors[module.name] = {
enumerable: !module.private,
get: exports.memoizedGetter(() => {
const value = require(`@electron/internal/common/api/${module.file}.js`)
// Handle Typescript modules with an "export default X" statement
if (value.__esModule) return value.default
return value
})
get: exports.handleESModule(module.loader)
}
}
return Object.defineProperties(targetExports, descriptors)

View file

@ -2,10 +2,10 @@
// Common modules, please sort alphabetically
module.exports = [
{ name: 'clipboard', file: 'clipboard' },
{ name: 'nativeImage', file: 'native-image' },
{ name: 'shell', file: 'shell' },
{ name: 'clipboard', loader: () => require('./clipboard') },
{ name: 'nativeImage', loader: () => require('./native-image') },
{ name: 'shell', loader: () => require('./shell') },
// The internal modules, invisible unless you know their names.
{ name: 'deprecate', file: 'deprecate', private: true },
{ name: 'isPromise', file: 'is-promise', private: true }
{ name: 'deprecate', loader: () => require('./deprecate'), private: true },
{ name: 'isPromise', loader: () => require('./is-promise'), private: true }
]

View file

@ -5,9 +5,11 @@ const Module = require('module')
// Clear Node's global search paths.
Module.globalPaths.length = 0
// Clear current and parent(init.js)'s search paths.
module.paths = []
module.parent!.paths = []
// Clear current bundles search paths.
const currentNodeModule = Module._cache[__filename]
if (currentNodeModule) {
currentNodeModule.paths = []
}
// Prevent Node from adding paths outside this app to search paths.
const resourcesPathWithTrailingSlash = process.resourcesPath + path.sep
@ -25,19 +27,21 @@ Module._nodeModulePaths = function (from: string) {
}
}
const BASE_INTERNAL_PATH = path.resolve(__dirname, '..')
const INTERNAL_MODULE_PREFIX = '@electron/internal/'
// Make a fake Electron module that we will insert into the module cache
const electronModule = new Module('electron', null)
electronModule.id = 'electron'
electronModule.loaded = true
electronModule.filename = 'electron'
Object.defineProperty(electronModule, 'exports', {
get: () => require('electron')
})
Module._cache['electron'] = electronModule
// Patch Module._resolveFilename to always require the Electron API when
// require('electron') is done.
const electronPath = path.join(__dirname, '..', process.type!, 'api', 'exports', 'electron.js')
const originalResolveFilename = Module._resolveFilename
Module._resolveFilename = function (request: string, parent: NodeModule, isMain: boolean) {
if (request === 'electron') {
return electronPath
} else if (request.startsWith(INTERNAL_MODULE_PREFIX) && request.length > INTERNAL_MODULE_PREFIX.length) {
const slicedRequest = request.slice(INTERNAL_MODULE_PREFIX.length)
return path.resolve(BASE_INTERNAL_PATH, `${slicedRequest}${slicedRequest.endsWith('.js') ? '' : '.js'}`)
return 'electron'
} else {
return originalResolveFilename(request, parent, isMain)
}

View file

@ -12,7 +12,7 @@ const v8Util = process.electronBinding('v8_util')
// "ipc-internal" hidden value
v8Util.setHiddenValue(global, 'ipc-internal', v8Util.getHiddenValue(isolatedWorld, 'ipc-internal'))
// The process object created by browserify is not an event emitter, fix it so
// The process object created by webpack is not an event emitter, fix it so
// the API is more compatible with non-sandboxed renderers.
for (const prop of Object.keys(EventEmitter.prototype)) {
if (process.hasOwnProperty(prop)) {

View file

@ -6,23 +6,9 @@ const moduleList = require('@electron/internal/renderer/api/module-list')
// Import common modules.
common.defineProperties(exports)
for (const {
name,
file,
enabled = true,
private: isPrivate = false
} of moduleList) {
if (!enabled) {
continue
}
Object.defineProperty(exports, name, {
enumerable: !isPrivate,
get: common.memoizedGetter(() => {
const value = require(`@electron/internal/renderer/api/${file}.js`)
// Handle Typescript modules with an "export default X" statement
if (value.__esModule) return value.default
return value
})
for (const module of moduleList) {
Object.defineProperty(exports, module.name, {
enumerable: !module.private,
get: common.handleESModule(module.loader)
})
}

View file

@ -8,13 +8,15 @@ const enableRemoteModule = v8Util.getHiddenValue(global, 'enableRemoteModule')
// Renderer side modules, please sort alphabetically.
// A module is `enabled` if there is no explicit condition defined.
module.exports = [
{ name: 'crashReporter', file: 'crash-reporter', enabled: true },
{
name: 'desktopCapturer',
file: 'desktop-capturer',
enabled: features.isDesktopCapturerEnabled()
},
{ name: 'ipcRenderer', file: 'ipc-renderer' },
{ name: 'remote', file: 'remote', enabled: enableRemoteModule },
{ name: 'webFrame', file: 'web-frame' }
{ name: 'crashReporter', loader: () => require('./crash-reporter') },
{ name: 'ipcRenderer', loader: () => require('./ipc-renderer') },
{ name: 'webFrame', loader: () => require('./web-frame') }
]
if (features.isDesktopCapturerEnabled()) {
module.exports.push({ name: 'desktopCapturer', loader: () => require('./desktop-capturer') })
}
if (enableRemoteModule) {
module.exports.push({ name: 'remote', loader: () => require('./remote') })
}

View file

@ -350,7 +350,7 @@ const addBuiltinProperty = (name) => {
const browserModules =
require('@electron/internal/common/api/module-list').concat(
require('@electron/internal/browser/api/module-list'))
require('@electron/internal/browser/api/module-keys'))
// And add a helper receiver for each one.
browserModules

View file

@ -14,6 +14,10 @@ const Module = require('module')
// code, which does not work with this hack. However by modifying the
// "Module.wrapper" we can force Node to use the old code path to wrap module
// code with JavaScript.
//
// Note 3: We provide the equivilant extra variables internally through the
// webpack ProvidePlugin in webpack.config.base.js. If you add any extra
// variables to this wrapper please ensure to update that plugin as well.
Module.wrapper = [
'(function (exports, require, module, __filename, __dirname, process, global, Buffer) { ' +
// By running the code in a new closure, it would be possible for the module
@ -33,11 +37,6 @@ require('../common/reset-search-paths')
// Import common settings.
require('@electron/internal/common/init')
const globalPaths = Module.globalPaths
// Expose public APIs.
globalPaths.push(path.join(__dirname, 'api', 'exports'))
// The global variable will be used by ipc for event dispatching
const v8Util = process.electronBinding('v8_util')
@ -129,8 +128,8 @@ if (contextIsolation) {
if (nodeIntegration) {
// Export node bindings to global.
global.require = require
global.module = module
global.require = __non_webpack_require__ // eslint-disable-line
global.module = Module._cache[__filename]
// Set the __filename to the path of html file if it is file: protocol.
if (window.location.protocol === 'file:') {
@ -140,7 +139,7 @@ if (nodeIntegration) {
if (process.platform === 'win32') {
if (pathname[0] === '/') pathname = pathname.substr(1)
const isWindowsNetworkSharePath = location.hostname.length > 0 && globalPaths[0].startsWith('\\')
const isWindowsNetworkSharePath = location.hostname.length > 0 && __filename.startsWith('\\')
if (isWindowsNetworkSharePath) {
pathname = `//${location.host}/${pathname}`
}
@ -150,17 +149,17 @@ if (nodeIntegration) {
global.__dirname = path.dirname(global.__filename)
// Set module's filename so relative require can work as expected.
module.filename = global.__filename
global.module.filename = global.__filename
// Also search for module under the html file.
module.paths = module.paths.concat(Module._nodeModulePaths(global.__dirname))
global.module.paths = global.module.paths.concat(Module._nodeModulePaths(global.__dirname))
} else {
global.__filename = __filename
global.__dirname = __dirname
if (appPath) {
// Search for module under the app directory
module.paths = module.paths.concat(Module._nodeModulePaths(appPath))
global.module.paths = global.module.paths.concat(Module._nodeModulePaths(appPath))
}
}
@ -204,7 +203,7 @@ for (const preloadScript of preloadScripts) {
if (!isParentDir(getAppPath(), fs.realpathSync(preloadScript))) {
throw new Error('Preload scripts outside of app path are not allowed')
}
require(preloadScript)
__non_webpack_require__(preloadScript) // eslint-disable-line
} catch (error) {
console.error(`Unable to load preload script: ${preloadScript}`)
console.error(`${error}`)

View file

@ -3,6 +3,8 @@ import { invokeSync } from '@electron/internal/renderer/ipc-renderer-internal-ut
let shouldLog: boolean | null = null
const { platform, execPath, env } = process
/**
* This method checks if a security message should be logged.
* It does so by determining whether we're running as Electron,
@ -16,8 +18,6 @@ const shouldLogSecurityWarnings = function (): boolean {
return shouldLog
}
const { platform, execPath, env } = process
switch (platform) {
case 'darwin':
shouldLog = execPath.endsWith('MacOS/Electron') ||

View file

@ -0,0 +1,18 @@
// This file provides the global, process and Buffer variables to internal
// Electron code once they have been deleted from the global scope.
//
// It does this through the ProvidePlugin in the webpack.config.base.js file
// Check out the Module.wrapper override in renderer/init.ts for more
// information on how this works and why we need it
// Rip global off of window (which is also global) so that webpack doesn't
// auto replace it with a looped reference to this file
const _global = (self as any || window as any).global as NodeJS.Global
const process = _global.process
const Buffer = _global.Buffer
export {
_global,
process,
Buffer
}

View file

@ -8,7 +8,7 @@ const { EventEmitter } = events
process.electronBinding = require('@electron/internal/common/electron-binding-setup').electronBindingSetup(binding.get, 'renderer')
const v8Util = process.electronBinding('v8_util')
// Expose browserify Buffer as a hidden value. This is used by C++ code to
// Expose Buffer shim as a hidden value. This is used by C++ code to
// deserialize Buffer instances sent from browser process.
v8Util.setHiddenValue(global, 'Buffer', Buffer)
// The `lib/renderer/api/ipc-renderer.js` module looks for the ipc object in the
@ -17,7 +17,7 @@ v8Util.setHiddenValue(global, 'ipc', new EventEmitter())
// The `lib/renderer/ipc-renderer-internal.js` module looks for the ipc object in the
// "ipc-internal" hidden value
v8Util.setHiddenValue(global, 'ipc-internal', new EventEmitter())
// The process object created by browserify is not an event emitter, fix it so
// The process object created by webpack is not an event emitter, fix it so
// the API is more compatible with non-sandboxed renderers.
for (const prop of Object.keys(EventEmitter.prototype)) {
if (process.hasOwnProperty(prop)) {
@ -143,20 +143,8 @@ const errorUtils = require('@electron/internal/common/error-utils')
//
// - `require`: The `preloadRequire` function
// - `process`: The `preloadProcess` object
// - `Buffer`: Browserify `Buffer` implementation
// - `global`: The window object, which is aliased to `global` by browserify.
//
// Browserify bundles can make use of an external require function as explained
// in https://github.com/substack/node-browserify#multiple-bundles, so electron
// apps can use multi-module preload scripts in sandboxed renderers.
//
// For example, the user can create a bundle with:
//
// $ browserify -x electron preload.js > renderer.js
//
// and any `require('electron')` calls in `preload.js` will work as expected
// since browserify won't try to include `electron` in the bundle, falling back
// to the `preloadRequire` function above.
// - `Buffer`: Shim of `Buffer` implementation
// - `global`: The window object, which is aliased to `global` by webpack.
function runPreloadScript (preloadSrc) {
const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate, clearImmediate, exports) {
${preloadSrc}

View file

@ -13,12 +13,9 @@ require('../common/reset-search-paths')
// Import common settings.
require('@electron/internal/common/init')
// Expose public APIs.
Module.globalPaths.push(path.join(__dirname, 'api', 'exports'))
// Export node bindings to global.
global.require = require
global.module = module
global.require = __non_webpack_require__ // eslint-disable-line
global.module = Module._cache[__filename]
// Set the __filename to the path of html file if it is file: protocol.
if (self.location.protocol === 'file:') {
@ -27,10 +24,10 @@ if (self.location.protocol === 'file:') {
global.__dirname = path.dirname(global.__filename)
// Set module's filename so relative require can work as expected.
module.filename = global.__filename
global.module.filename = global.__filename
// Also search for module under the html file.
module.paths = module.paths.concat(Module._nodeModulePaths(global.__dirname))
global.module.paths = global.module.paths.concat(Module._nodeModulePaths(global.__dirname))
} else {
global.__filename = __filename
global.__dirname = __dirname

View file

@ -14,11 +14,11 @@
"@types/mocha": "^5.2.6",
"@types/node": "^10.12.21",
"@types/split": "^1.0.0",
"@types/webpack": "^4.4.32",
"@types/webpack-env": "^1.13.9",
"@typescript-eslint/eslint-plugin": "^1.4.2",
"@typescript-eslint/parser": "^1.4.2",
"aliasify": "^2.1.0",
"asar": "^1.0.0",
"browserify": "^16.2.3",
"check-for-leaks": "^1.0.2",
"clang-format": "^1.2.3",
"colors": "^1.1.2",
@ -51,14 +51,16 @@
"standard-markdown": "^5.0.0",
"sumchecker": "^2.0.2",
"temp": "^0.8.3",
"timers-browserify": "1.4.2",
"ts-loader": "^6.0.2",
"ts-node": "^6.0.3",
"tsify": "^4.0.1",
"typescript": "~3.3.3333"
"typescript": "~3.3.3333",
"webpack": "^4.32.2",
"webpack-cli": "^3.3.2"
},
"private": true,
"scripts": {
"asar": "asar",
"browserify": "browserify",
"bump-version": "./script/bump-version.js",
"check-tls": "python ./script/tls.py",
"clang-format": "find atom/ chromium_src/ -iname *.h -o -iname *.cc -o -iname *.mm | xargs clang-format -i",
@ -82,24 +84,14 @@
"repl": "node ./script/start.js --interactive",
"start": "node ./script/start.js",
"test": "node ./script/spec-runner.js",
"tsc": "tsc"
"tsc": "tsc",
"webpack": "node build/webpack/run-compiler"
},
"license": "MIT",
"author": "Electron Community",
"keywords": [
"electron"
],
"aliasify": {
"replacements": {
"@electron/internal/(.+)": "./lib/$1"
},
"appliesTo": {
"includeExtensions": [
".js",
".ts"
]
}
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",

View file

@ -14,41 +14,39 @@ const allDocs = fs.readdirSync(path.resolve(__dirname, '../docs/api'))
)
const main = async () => {
const browserifyTargets = [
const webpackTargets = [
{
name: 'sandbox_browserify_deps',
entry: 'lib/sandboxed_renderer/init.js'
name: 'sandbox_bundle_deps',
config: 'webpack.config.sandboxed_renderer.js'
},
{
name: 'isolated_browserify_deps',
entry: 'lib/isolated_renderer/init.js'
name: 'isolated_bundle_deps',
config: 'webpack.config.isolated_renderer.js'
},
{
name: 'context_script_browserify_deps',
entry: 'lib/content_script/init.js'
name: 'content_script_bundle_deps',
config: 'webpack.config.content_script.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'
}
]
await Promise.all(browserifyTargets.map(async browserifyTarget => {
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/browserify/bin/cmd.js',
browserifyTarget.entry,
...(browserifyTarget.name === 'sandbox_browserify_deps' ? [
'-r',
'./lib/sandboxed_renderer/api/exports/electron.js:electron'
] : []),
'-t',
'aliasify',
'-p',
'[',
'tsify',
'-p',
'tsconfig.electron.json',
']',
'-o',
path.resolve(tmpDir, 'out.js'),
'--list'
'build/webpack/get-outputs.js',
`./${webpackTarget.config}`,
path.resolve(tmpDir, `${webpackTarget.name}.measure.js`)
], {
cwd: path.resolve(__dirname, '..')
})
@ -60,28 +58,25 @@ const main = async () => {
await new Promise((resolve, reject) => child.on('exit', (code) => {
if (code !== 0) {
console.error(output)
return reject(new Error(`Failed to list browserify dependencies for entry: ${browserifyTarget.name}`))
return reject(new Error(`Failed to list webpack dependencies for entry: ${webpackTarget.name}`))
}
resolve()
}))
browserifyTarget.dependencies = output
.split('\n')
webpackTarget.dependencies = JSON.parse(output)
// Remove whitespace
.map(line => line.trim())
// Ignore empty lines
.filter(line => line)
// Get the relative path
.map(line => path.relative(rootPath, line))
// 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'])
// Make the generated list easier to read
.sort()
// All browserify commands depend on the tsconfig and package json files
.concat(['tsconfig.json', 'tsconfig.electron.json', 'package.json'])
await fs.remove(tmpDir)
}))
@ -93,7 +88,7 @@ auto_filenames = {
${allDocs.map(doc => ` "${doc}",`).join('\n')}
]
${browserifyTargets.map(target => ` ${target.name} = [
${webpackTargets.map(target => ` ${target.name} = [
${target.dependencies.map(dep => ` "${dep}",`).join('\n')}
]`).join('\n\n')}
}

View file

@ -42,7 +42,7 @@ describe('asar package', function () {
it('does not leak fd', function () {
let readCalls = 1
while (readCalls <= 10000) {
fs.readFileSync(path.join(process.resourcesPath, 'electron.asar', 'renderer', 'api', 'ipc-renderer.js'))
fs.readFileSync(path.join(process.resourcesPath, 'electron.asar', 'renderer', 'init.js'))
readCalls++
}
})

View file

@ -3,7 +3,7 @@ const { expect } = chai
describe('feature-string parsing', () => {
it('is indifferent to whitespace around keys and values', () => {
const parseFeaturesString = require('@electron/internal/common/parse-features-string')
const parseFeaturesString = require('../lib/common/parse-features-string')
const checkParse = (string, parsed) => {
const features = {}
parseFeaturesString(string, (k, v) => { features[k] = v })

View file

@ -1,19 +0,0 @@
#!/usr/bin/env python
import os
import subprocess
import sys
SOURCE_ROOT = os.path.dirname(os.path.dirname(__file__))
BROWSERIFY = os.path.join(SOURCE_ROOT, 'node_modules', '.bin', 'browserify')
if sys.platform == 'win32':
BROWSERIFY += '.cmd'
deps = subprocess.check_output([BROWSERIFY, '--list'] + sys.argv[1:])
for dep in deps.split('\n'):
if dep:
dep = os.path.relpath(dep, SOURCE_ROOT)
if sys.platform == 'win32':
print('/'.join(dep.split('\\')))
else:
print(dep)

1441
yarn.lock

File diff suppressed because it is too large Load diff