build: Wrap bundles using webpack (#25557)
This commit is contained in:
parent
f7945ade07
commit
56d1fafe66
9 changed files with 169 additions and 178 deletions
|
@ -1,2 +0,0 @@
|
||||||
process.env.PRINT_WEBPACK_GRAPH = true;
|
|
||||||
require('./run-compiler');
|
|
|
@ -1,45 +0,0 @@
|
||||||
const fs = require('fs');
|
|
||||||
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)
|
|
||||||
};
|
|
||||||
|
|
||||||
const { wrapInitWithProfilingTimeout, wrapInitWithTryCatch, ...webpackConfig } = config;
|
|
||||||
|
|
||||||
webpack(webpackConfig, (err, stats) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
process.exit(1);
|
|
||||||
} else if (stats.hasErrors()) {
|
|
||||||
console.error(stats.toString('normal'));
|
|
||||||
process.exit(1);
|
|
||||||
} else {
|
|
||||||
let contents = fs.readFileSync(outPath, 'utf8');
|
|
||||||
if (wrapInitWithTryCatch) {
|
|
||||||
contents = `try {
|
|
||||||
${contents}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Electron ${webpackConfig.output.filename} script failed to run');
|
|
||||||
console.error(err);
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
if (wrapInitWithProfilingTimeout) {
|
|
||||||
contents = `function ___electron_webpack_init__() {
|
|
||||||
${contents}
|
|
||||||
};
|
|
||||||
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
|
|
||||||
setTimeout(___electron_webpack_init__, 0);
|
|
||||||
} else {
|
|
||||||
___electron_webpack_init__();
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
fs.writeFileSync(outPath, contents);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -2,16 +2,12 @@ const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const TerserPlugin = require('terser-webpack-plugin');
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
|
const WrapperPlugin = require('wrapper-webpack-plugin');
|
||||||
|
|
||||||
const electronRoot = path.resolve(__dirname, '../..');
|
const electronRoot = path.resolve(__dirname, '../..');
|
||||||
|
|
||||||
const onlyPrintingGraph = !!process.env.PRINT_WEBPACK_GRAPH;
|
|
||||||
|
|
||||||
class AccessDependenciesPlugin {
|
class AccessDependenciesPlugin {
|
||||||
apply (compiler) {
|
apply (compiler) {
|
||||||
// Only hook into webpack when we are printing the dependency graph
|
|
||||||
if (!onlyPrintingGraph) return;
|
|
||||||
|
|
||||||
compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
|
compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
|
||||||
compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
|
compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
|
||||||
const filePaths = modules.map(m => m.resource).filter(p => p).map(p => path.relative(electronRoot, p));
|
const filePaths = modules.map(m => m.resource).filter(p => p).map(p => path.relative(electronRoot, p));
|
||||||
|
@ -21,49 +17,6 @@ class AccessDependenciesPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const defines = {
|
|
||||||
BUILDFLAG: onlyPrintingGraph ? '(a => a)' : ''
|
|
||||||
};
|
|
||||||
|
|
||||||
const buildFlagsPrefix = '--buildflags=';
|
|
||||||
const buildFlagArg = process.argv.find(arg => arg.startsWith(buildFlagsPrefix));
|
|
||||||
|
|
||||||
if (buildFlagArg) {
|
|
||||||
const buildFlagPath = buildFlagArg.substr(buildFlagsPrefix.length);
|
|
||||||
|
|
||||||
const flagFile = fs.readFileSync(buildFlagPath, 'utf8');
|
|
||||||
for (const line of flagFile.split(/(\r\n|\r|\n)/g)) {
|
|
||||||
const flagMatch = line.match(/#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/);
|
|
||||||
if (flagMatch) {
|
|
||||||
const [, flagName, flagValue] = flagMatch;
|
|
||||||
defines[flagName] = JSON.stringify(Boolean(parseInt(flagValue, 10)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ignoredModules = [];
|
|
||||||
|
|
||||||
if (defines.ENABLE_DESKTOP_CAPTURER === 'false') {
|
|
||||||
ignoredModules.push(
|
|
||||||
'@electron/internal/browser/desktop-capturer',
|
|
||||||
'@electron/internal/browser/api/desktop-capturer',
|
|
||||||
'@electron/internal/renderer/api/desktop-capturer'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defines.ENABLE_REMOTE_MODULE === 'false') {
|
|
||||||
ignoredModules.push(
|
|
||||||
'@electron/internal/browser/remote/server',
|
|
||||||
'@electron/internal/renderer/api/remote'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defines.ENABLE_VIEWS_API === 'false') {
|
|
||||||
ignoredModules.push(
|
|
||||||
'@electron/internal/browser/api/views/image-view.js'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = ({
|
module.exports = ({
|
||||||
alwaysHasNode,
|
alwaysHasNode,
|
||||||
loadElectronFromAlternateTarget,
|
loadElectronFromAlternateTarget,
|
||||||
|
@ -79,76 +32,148 @@ module.exports = ({
|
||||||
|
|
||||||
const electronAPIFile = path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts');
|
const electronAPIFile = path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts');
|
||||||
|
|
||||||
return ({
|
return (env = {}, argv = {}) => {
|
||||||
mode: 'development',
|
const onlyPrintingGraph = !!env.PRINT_WEBPACK_GRAPH;
|
||||||
devtool: false,
|
const outputFilename = argv['output-filename'] || `${target}.bundle.js`;
|
||||||
entry,
|
|
||||||
target: alwaysHasNode ? 'node' : 'web',
|
const defines = {
|
||||||
output: {
|
BUILDFLAG: onlyPrintingGraph ? '(a => a)' : ''
|
||||||
filename: `${target}.bundle.js`
|
};
|
||||||
},
|
|
||||||
wrapInitWithProfilingTimeout,
|
if (env.buildflags) {
|
||||||
wrapInitWithTryCatch,
|
const flagFile = fs.readFileSync(env.buildflags, 'utf8');
|
||||||
resolve: {
|
for (const line of flagFile.split(/(\r\n|\r|\n)/g)) {
|
||||||
alias: {
|
const flagMatch = line.match(/#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/);
|
||||||
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
if (flagMatch) {
|
||||||
electron$: electronAPIFile,
|
const [, flagName, flagValue] = flagMatch;
|
||||||
'electron/main$': electronAPIFile,
|
defines[flagName] = JSON.stringify(Boolean(parseInt(flagValue, 10)));
|
||||||
'electron/renderer$': electronAPIFile,
|
|
||||||
'electron/common$': electronAPIFile,
|
|
||||||
// Force timers to resolve to our dependency that doesn't use window.postMessage
|
|
||||||
timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
|
|
||||||
},
|
|
||||||
extensions: ['.ts', '.js']
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [{
|
|
||||||
test: (moduleName) => !onlyPrintingGraph && ignoredModules.includes(moduleName),
|
|
||||||
loader: 'null-loader'
|
|
||||||
}, {
|
|
||||||
test: /\.ts$/,
|
|
||||||
loader: 'ts-loader',
|
|
||||||
options: {
|
|
||||||
configFile: path.resolve(electronRoot, 'tsconfig.electron.json'),
|
|
||||||
transpileOnly: onlyPrintingGraph,
|
|
||||||
ignoreDiagnostics: [
|
|
||||||
// File '{0}' is not under 'rootDir' '{1}'.
|
|
||||||
6059
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}]
|
}
|
||||||
},
|
}
|
||||||
node: {
|
|
||||||
__dirname: false,
|
const ignoredModules = [];
|
||||||
__filename: false,
|
|
||||||
// We provide our own "timers" import above, any usage of setImmediate inside
|
if (defines.ENABLE_DESKTOP_CAPTURER === 'false') {
|
||||||
// one of our renderer bundles should import it from the 'timers' package
|
ignoredModules.push(
|
||||||
setImmediate: false
|
'@electron/internal/browser/desktop-capturer',
|
||||||
},
|
'@electron/internal/browser/api/desktop-capturer',
|
||||||
optimization: {
|
'@electron/internal/renderer/api/desktop-capturer'
|
||||||
minimize: true,
|
);
|
||||||
minimizer: [
|
}
|
||||||
new TerserPlugin({
|
|
||||||
terserOptions: {
|
if (defines.ENABLE_REMOTE_MODULE === 'false') {
|
||||||
keep_classnames: true,
|
ignoredModules.push(
|
||||||
keep_fnames: true
|
'@electron/internal/browser/remote/server',
|
||||||
}
|
'@electron/internal/renderer/api/remote'
|
||||||
})
|
);
|
||||||
]
|
}
|
||||||
},
|
|
||||||
plugins: [
|
if (defines.ENABLE_VIEWS_API === 'false') {
|
||||||
new AccessDependenciesPlugin(),
|
ignoredModules.push(
|
||||||
...(targetDeletesNodeGlobals ? [
|
'@electron/internal/browser/api/views/image-view.js'
|
||||||
new webpack.ProvidePlugin({
|
);
|
||||||
process: ['@electron/internal/common/webpack-provider', 'process'],
|
}
|
||||||
global: ['@electron/internal/common/webpack-provider', '_global'],
|
|
||||||
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer']
|
const plugins = [];
|
||||||
})
|
|
||||||
] : []),
|
if (onlyPrintingGraph) {
|
||||||
new webpack.ProvidePlugin({
|
plugins.push(new AccessDependenciesPlugin());
|
||||||
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise']
|
}
|
||||||
}),
|
|
||||||
new webpack.DefinePlugin(defines)
|
if (targetDeletesNodeGlobals) {
|
||||||
]
|
plugins.push(new webpack.ProvidePlugin({
|
||||||
});
|
process: ['@electron/internal/common/webpack-provider', 'process'],
|
||||||
|
global: ['@electron/internal/common/webpack-provider', '_global'],
|
||||||
|
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer']
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins.push(new webpack.ProvidePlugin({
|
||||||
|
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise']
|
||||||
|
}));
|
||||||
|
|
||||||
|
plugins.push(new webpack.DefinePlugin(defines));
|
||||||
|
|
||||||
|
if (wrapInitWithProfilingTimeout) {
|
||||||
|
plugins.push(new WrapperPlugin({
|
||||||
|
header: 'function ___electron_webpack_init__() {',
|
||||||
|
footer: `
|
||||||
|
};
|
||||||
|
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
|
||||||
|
setTimeout(___electron_webpack_init__, 0);
|
||||||
|
} else {
|
||||||
|
___electron_webpack_init__();
|
||||||
|
}`
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrapInitWithTryCatch) {
|
||||||
|
plugins.push(new WrapperPlugin({
|
||||||
|
header: 'try {',
|
||||||
|
footer: `
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Electron ${outputFilename} script failed to run');
|
||||||
|
console.error(err);
|
||||||
|
}`
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
mode: 'development',
|
||||||
|
devtool: false,
|
||||||
|
entry,
|
||||||
|
target: alwaysHasNode ? 'node' : 'web',
|
||||||
|
output: {
|
||||||
|
filename: outputFilename
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
||||||
|
electron$: electronAPIFile,
|
||||||
|
'electron/main$': electronAPIFile,
|
||||||
|
'electron/renderer$': electronAPIFile,
|
||||||
|
'electron/common$': electronAPIFile,
|
||||||
|
// Force timers to resolve to our dependency that doesn't use window.postMessage
|
||||||
|
timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
|
||||||
|
},
|
||||||
|
extensions: ['.ts', '.js']
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [{
|
||||||
|
test: (moduleName) => !onlyPrintingGraph && ignoredModules.includes(moduleName),
|
||||||
|
loader: 'null-loader'
|
||||||
|
}, {
|
||||||
|
test: /\.ts$/,
|
||||||
|
loader: 'ts-loader',
|
||||||
|
options: {
|
||||||
|
configFile: path.resolve(electronRoot, 'tsconfig.electron.json'),
|
||||||
|
transpileOnly: onlyPrintingGraph,
|
||||||
|
ignoreDiagnostics: [
|
||||||
|
// File '{0}' is not under 'rootDir' '{1}'.
|
||||||
|
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
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
minimize: true,
|
||||||
|
minimizer: [
|
||||||
|
new TerserPlugin({
|
||||||
|
terserOptions: {
|
||||||
|
keep_classnames: true,
|
||||||
|
keep_fnames: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,6 @@ template("webpack_build") {
|
||||||
inputs = [
|
inputs = [
|
||||||
invoker.config_file,
|
invoker.config_file,
|
||||||
"//electron/build/webpack/webpack.config.base.js",
|
"//electron/build/webpack/webpack.config.base.js",
|
||||||
"//electron/build/webpack/run-compiler.js",
|
|
||||||
"//electron/tsconfig.json",
|
"//electron/tsconfig.json",
|
||||||
"//electron/yarn.lock",
|
"//electron/yarn.lock",
|
||||||
"//electron/typings/internal-ambient.d.ts",
|
"//electron/typings/internal-ambient.d.ts",
|
||||||
|
@ -24,9 +23,12 @@ template("webpack_build") {
|
||||||
] + invoker.inputs
|
] + invoker.inputs
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
|
"--config",
|
||||||
rebase_path(invoker.config_file),
|
rebase_path(invoker.config_file),
|
||||||
rebase_path(invoker.out_file),
|
"--output-filename=" + get_path_info(invoker.out_file, "file"),
|
||||||
"--buildflags=" + rebase_path("$target_gen_dir/buildflags/buildflags.h"),
|
"--output-path=" + rebase_path(get_path_info(invoker.out_file, "dir")),
|
||||||
|
"--env.buildflags=" +
|
||||||
|
rebase_path("$target_gen_dir/buildflags/buildflags.h"),
|
||||||
]
|
]
|
||||||
deps += [ "buildflags" ]
|
deps += [ "buildflags" ]
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,8 @@
|
||||||
"ts-node": "6.2.0",
|
"ts-node": "6.2.0",
|
||||||
"typescript": "^4.0.2",
|
"typescript": "^4.0.2",
|
||||||
"webpack": "^4.43.0",
|
"webpack": "^4.43.0",
|
||||||
"webpack-cli": "^3.3.12"
|
"webpack-cli": "^3.3.12",
|
||||||
|
"wrapper-webpack-plugin": "^2.1.0"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -91,7 +92,7 @@
|
||||||
"start": "node ./script/start.js",
|
"start": "node ./script/start.js",
|
||||||
"test": "node ./script/spec-runner.js",
|
"test": "node ./script/spec-runner.js",
|
||||||
"tsc": "tsc",
|
"tsc": "tsc",
|
||||||
"webpack": "node build/webpack/run-compiler"
|
"webpack": "webpack"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Electron Community",
|
"author": "Electron Community",
|
||||||
|
@ -141,4 +142,4 @@
|
||||||
"@types/temp": "^0.8.34",
|
"@types/temp": "^0.8.34",
|
||||||
"aws-sdk": "^2.727.1"
|
"aws-sdk": "^2.727.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,12 @@ const main = async () => {
|
||||||
const webpackTargetsWithDeps = await Promise.all(webpackTargets.map(async webpackTarget => {
|
const webpackTargetsWithDeps = await Promise.all(webpackTargets.map(async webpackTarget => {
|
||||||
const tmpDir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-filenames-'));
|
const tmpDir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-filenames-'));
|
||||||
const child = cp.spawn('node', [
|
const child = cp.spawn('node', [
|
||||||
'build/webpack/get-outputs.js',
|
'./node_modules/webpack-cli/bin/cli.js',
|
||||||
`./${webpackTarget.config}`,
|
'--config', `./build/webpack/${webpackTarget.config}`,
|
||||||
path.resolve(tmpDir, `${webpackTarget.name}.measure.js`)
|
'--display', 'errors-only',
|
||||||
|
`--output-path=${tmpDir}`,
|
||||||
|
`--output-filename=${webpackTarget.name}.measure.js`,
|
||||||
|
'--env.PRINT_WEBPACK_GRAPH'
|
||||||
], {
|
], {
|
||||||
cwd: path.resolve(__dirname, '..')
|
cwd: path.resolve(__dirname, '..')
|
||||||
});
|
});
|
||||||
|
|
|
@ -424,7 +424,7 @@ node::Environment* NodeBindings::CreateEnvironment(
|
||||||
DCHECK(env);
|
DCHECK(env);
|
||||||
|
|
||||||
// This will only be caught when something has gone terrible wrong as all
|
// This will only be caught when something has gone terrible wrong as all
|
||||||
// electron scripts are wrapped in a try {} catch {} in run-compiler.js
|
// electron scripts are wrapped in a try {} catch {} by webpack
|
||||||
if (try_catch.HasCaught()) {
|
if (try_catch.HasCaught()) {
|
||||||
LOG(ERROR) << "Failed to initialize node environment in process: "
|
LOG(ERROR) << "Failed to initialize node environment in process: "
|
||||||
<< process_type;
|
<< process_type;
|
||||||
|
|
|
@ -29,7 +29,7 @@ v8::MaybeLocal<v8::Value> CompileAndCall(
|
||||||
v8::MaybeLocal<v8::Value> ret = fn->Call(
|
v8::MaybeLocal<v8::Value> ret = fn->Call(
|
||||||
context, v8::Null(isolate), arguments->size(), arguments->data());
|
context, v8::Null(isolate), arguments->size(), arguments->data());
|
||||||
// This will only be caught when something has gone terrible wrong as all
|
// This will only be caught when something has gone terrible wrong as all
|
||||||
// electron scripts are wrapped in a try {} catch {} in run-compiler.js
|
// electron scripts are wrapped in a try {} catch {} by webpack
|
||||||
if (try_catch.HasCaught()) {
|
if (try_catch.HasCaught()) {
|
||||||
LOG(ERROR) << "Failed to CompileAndCall electron script: " << id;
|
LOG(ERROR) << "Failed to CompileAndCall electron script: " << id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8151,7 +8151,7 @@ webpack-cli@^3.3.12:
|
||||||
v8-compile-cache "^2.1.1"
|
v8-compile-cache "^2.1.1"
|
||||||
yargs "^13.3.2"
|
yargs "^13.3.2"
|
||||||
|
|
||||||
webpack-sources@^1.4.0, webpack-sources@^1.4.1:
|
webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1:
|
||||||
version "1.4.3"
|
version "1.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933"
|
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933"
|
||||||
integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==
|
integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==
|
||||||
|
@ -8257,6 +8257,13 @@ wrapped@^1.0.1:
|
||||||
co "3.1.0"
|
co "3.1.0"
|
||||||
sliced "^1.0.1"
|
sliced "^1.0.1"
|
||||||
|
|
||||||
|
wrapper-webpack-plugin@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrapper-webpack-plugin/-/wrapper-webpack-plugin-2.1.0.tgz#2b5d80f46af84c9eeb707d08796a115e233adeac"
|
||||||
|
integrity sha512-e+2FhSYGCxhDq3PcUw5mRhH+8vcYa+9d9AuLChJUZ9ZbUPhQOHZ/O2dnN98iTqeUuvrzSSOv13+x/NhrAm5JEg==
|
||||||
|
dependencies:
|
||||||
|
webpack-sources "^1.1.0"
|
||||||
|
|
||||||
wrappy@1:
|
wrappy@1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
|
|
Loading…
Add table
Reference in a new issue