From 363723fc84f7b8477592e0105aeb331ec9a017af Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 14 Aug 2017 05:01:11 +0200 Subject: node_modules --- node_modules/webpack/lib/AmdMainTemplatePlugin.js | 2 +- node_modules/webpack/lib/AsyncDependenciesBlock.js | 12 +- .../webpack/lib/BasicEvaluatedExpression.js | 24 +- node_modules/webpack/lib/Chunk.js | 120 ++- node_modules/webpack/lib/Compilation.js | 427 ++++++---- node_modules/webpack/lib/Compiler.js | 875 +++++++++++---------- node_modules/webpack/lib/ContextModule.js | 100 ++- node_modules/webpack/lib/ContextModuleFactory.js | 261 +++--- node_modules/webpack/lib/DefinePlugin.js | 4 +- node_modules/webpack/lib/DelegatedModule.js | 14 +- .../webpack/lib/DelegatedModuleFactoryPlugin.js | 9 +- node_modules/webpack/lib/DelegatedPlugin.js | 3 + node_modules/webpack/lib/DllReferencePlugin.js | 3 + node_modules/webpack/lib/EntryOptionPlugin.js | 20 +- .../EvalSourceMapDevToolModuleTemplatePlugin.js | 7 +- .../lib/ExportPropertyMainTemplatePlugin.js | 31 + node_modules/webpack/lib/ExternalModule.js | 7 +- .../webpack/lib/ExternalModuleFactoryPlugin.js | 2 +- .../webpack/lib/FlagDependencyExportsPlugin.js | 2 +- .../webpack/lib/FlagInitialModulesAsUsedPlugin.js | 2 +- .../webpack/lib/FunctionModuleTemplatePlugin.js | 20 +- .../webpack/lib/HotModuleReplacement.runtime.js | 76 +- .../webpack/lib/HotModuleReplacementPlugin.js | 442 +++++------ node_modules/webpack/lib/HotUpdateChunkTemplate.js | 11 +- .../webpack/lib/JsonpMainTemplate.runtime.js | 5 +- .../webpack/lib/JsonpMainTemplatePlugin.js | 17 +- node_modules/webpack/lib/LibManifestPlugin.js | 17 +- node_modules/webpack/lib/LibraryTemplatePlugin.js | 7 +- node_modules/webpack/lib/MainTemplate.js | 4 - node_modules/webpack/lib/Module.js | 140 +++- node_modules/webpack/lib/ModuleFilenameHelpers.js | 2 +- node_modules/webpack/lib/ModuleReason.js | 42 +- node_modules/webpack/lib/MultiCompiler.js | 284 ++++--- node_modules/webpack/lib/NodeStuffPlugin.js | 2 +- node_modules/webpack/lib/NormalModule.js | 53 +- node_modules/webpack/lib/NormalModuleFactory.js | 278 ++++--- node_modules/webpack/lib/Parser.js | 181 +++-- node_modules/webpack/lib/ParserHelpers.js | 9 + node_modules/webpack/lib/ProgressPlugin.js | 24 +- node_modules/webpack/lib/RawModule.js | 4 + node_modules/webpack/lib/RecordIdsPlugin.js | 6 +- node_modules/webpack/lib/RequestShortener.js | 41 +- node_modules/webpack/lib/RequireJsStuffPlugin.js | 2 +- node_modules/webpack/lib/RuleSet.js | 6 +- node_modules/webpack/lib/SourceMapDevToolPlugin.js | 165 ++-- node_modules/webpack/lib/Stats.js | 333 ++++---- node_modules/webpack/lib/Template.js | 8 +- node_modules/webpack/lib/UmdMainTemplatePlugin.js | 49 +- node_modules/webpack/lib/WebpackOptionsApply.js | 10 +- .../webpack/lib/WebpackOptionsDefaulter.js | 9 + node_modules/webpack/lib/dependencies/AMDPlugin.js | 4 +- .../webpack/lib/dependencies/CommonJsPlugin.js | 3 +- .../lib/dependencies/DelegatedExportsDependency.js | 33 + .../webpack/lib/dependencies/DepBlockHelpers.js | 35 +- .../dependencies/HarmonyCompatibilityDependency.js | 2 +- .../HarmonyImportDependencyParserPlugin.js | 19 + .../HarmonyImportSpecifierDependency.js | 8 +- .../lib/dependencies/HarmonyModulesHelpers.js | 20 +- .../webpack/lib/dependencies/ImportParserPlugin.js | 15 +- .../webpack/lib/dependencies/ImportPlugin.js | 10 +- .../dependencies/ImportWeakContextDependency.js | 22 + .../lib/dependencies/ImportWeakDependency.js | 47 ++ .../lib/dependencies/RequireContextDependency.js | 6 +- .../RequireContextDependencyParserPlugin.js | 10 +- .../lib/dependencies/RequireContextPlugin.js | 31 +- .../dependencies/RequireEnsureDependenciesBlock.js | 8 +- .../RequireResolveDependencyParserPlugin.js | 2 +- .../webpack/lib/node/NodeMainTemplatePlugin.js | 332 ++++---- node_modules/webpack/lib/node/NodeSourcePlugin.js | 2 + .../webpack/lib/node/NodeWatchFileSystem.js | 2 +- .../lib/optimize/AggressiveMergingPlugin.js | 62 +- .../lib/optimize/AggressiveSplittingPlugin.js | 101 +-- .../lib/optimize/ChunkModuleIdRangePlugin.js | 4 +- .../webpack/lib/optimize/CommonsChunkPlugin.js | 51 +- .../webpack/lib/optimize/ConcatenatedModule.js | 816 +++++++++++++++++++ .../lib/optimize/EnsureChunkConditionsPlugin.js | 9 +- .../lib/optimize/FlagIncludedChunksPlugin.js | 8 +- .../lib/optimize/MergeDuplicateChunksPlugin.js | 15 +- .../lib/optimize/ModuleConcatenationPlugin.js | 307 ++++++++ .../webpack/lib/optimize/OccurrenceOrderPlugin.js | 120 ++- .../lib/optimize/RemoveParentModulesPlugin.js | 50 +- .../webpack/lib/optimize/UglifyJsPlugin.js | 229 +----- node_modules/webpack/lib/prepareOptions.js | 29 + node_modules/webpack/lib/util/Semaphore.js | 32 + node_modules/webpack/lib/util/SortableSet.js | 45 ++ node_modules/webpack/lib/util/identifier.js | 24 +- node_modules/webpack/lib/webpack.js | 106 ++- .../lib/webworker/WebWorkerChunkTemplatePlugin.js | 4 +- .../lib/webworker/WebWorkerMainTemplate.runtime.js | 5 +- .../lib/webworker/WebWorkerMainTemplatePlugin.js | 57 +- 90 files changed, 4329 insertions(+), 2528 deletions(-) create mode 100644 node_modules/webpack/lib/ExportPropertyMainTemplatePlugin.js create mode 100644 node_modules/webpack/lib/dependencies/DelegatedExportsDependency.js create mode 100644 node_modules/webpack/lib/dependencies/ImportWeakContextDependency.js create mode 100644 node_modules/webpack/lib/dependencies/ImportWeakDependency.js create mode 100644 node_modules/webpack/lib/optimize/ConcatenatedModule.js create mode 100644 node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js create mode 100644 node_modules/webpack/lib/prepareOptions.js create mode 100644 node_modules/webpack/lib/util/Semaphore.js create mode 100644 node_modules/webpack/lib/util/SortableSet.js (limited to 'node_modules/webpack/lib') diff --git a/node_modules/webpack/lib/AmdMainTemplatePlugin.js b/node_modules/webpack/lib/AmdMainTemplatePlugin.js index 0ff688167..727f49ba3 100644 --- a/node_modules/webpack/lib/AmdMainTemplatePlugin.js +++ b/node_modules/webpack/lib/AmdMainTemplatePlugin.js @@ -17,7 +17,7 @@ class AmdMainTemplatePlugin { const mainTemplate = compilation.mainTemplate; compilation.templatesPlugin("render-with-entry", (source, chunk, hash) => { - const externals = chunk.modules.filter((m) => m.external); + const externals = chunk.getModules().filter((m) => m.external); const externalsDepsArray = JSON.stringify(externals.map((m) => typeof m.request === "object" ? m.request.amd : m.request )); diff --git a/node_modules/webpack/lib/AsyncDependenciesBlock.js b/node_modules/webpack/lib/AsyncDependenciesBlock.js index 0f5603324..27d5988b6 100644 --- a/node_modules/webpack/lib/AsyncDependenciesBlock.js +++ b/node_modules/webpack/lib/AsyncDependenciesBlock.js @@ -37,17 +37,7 @@ module.exports = class AsyncDependenciesBlock extends DependenciesBlock { sortItems() { super.sortItems(); if(this.chunks) { - this.chunks.sort((a, b) => { - let i = 0; - while(true) { // eslint-disable-line no-constant-condition - if(!a.modules[i] && !b.modules[i]) return 0; - if(!a.modules[i]) return -1; - if(!b.modules[i]) return 1; - if(a.modules[i].id > b.modules[i].id) return 1; - if(a.modules[i].id < b.modules[i].id) return -1; - i++; - } - }); + this.chunks.sort((a, b) => a.compareTo(b)); } } }; diff --git a/node_modules/webpack/lib/BasicEvaluatedExpression.js b/node_modules/webpack/lib/BasicEvaluatedExpression.js index d811cbebe..eab51de83 100644 --- a/node_modules/webpack/lib/BasicEvaluatedExpression.js +++ b/node_modules/webpack/lib/BasicEvaluatedExpression.js @@ -55,8 +55,18 @@ class BasicEvaluatedExpression { return Object.prototype.hasOwnProperty.call(this, "quasis"); } + isTruthy() { + return this.truthy; + } + + isFalsy() { + return this.falsy; + } + asBool() { - if(this.isBoolean()) return this.bool; + if(this.truthy) return true; + else if(this.falsy) return false; + else if(this.isBoolean()) return this.bool; else if(this.isNull()) return false; else if(this.isString()) return !!this.string; else if(this.isNumber()) return !!this.number; @@ -163,6 +173,18 @@ class BasicEvaluatedExpression { return this; } + setTruthy() { + this.falsy = false; + this.truthy = true; + return this; + } + + setFalsy() { + this.falsy = true; + this.truthy = false; + return this; + } + addOptions(options) { if(!this.options) this.options = []; options.forEach(item => { diff --git a/node_modules/webpack/lib/Chunk.js b/node_modules/webpack/lib/Chunk.js index 6962fd6c7..8e7cef13c 100644 --- a/node_modules/webpack/lib/Chunk.js +++ b/node_modules/webpack/lib/Chunk.js @@ -4,15 +4,23 @@ */ "use strict"; +const util = require("util"); const compareLocations = require("./compareLocations"); +const SortableSet = require("./util/SortableSet"); let debugId = 1000; -const byId = (a, b) => { +const sortById = (a, b) => { if(a.id < b.id) return -1; if(b.id < a.id) return 1; return 0; }; +const sortByIdentifier = (a, b) => { + if(a.identifier() > b.identifier()) return 1; + if(a.identifier() < b.identifier()) return -1; + return 0; +}; + class Chunk { constructor(name, module, loc) { @@ -20,7 +28,7 @@ class Chunk { this.ids = null; this.debugId = debugId++; this.name = name; - this.modules = []; + this._modules = new SortableSet(undefined, sortByIdentifier); this.entrypoints = []; this.chunks = []; this.parents = []; @@ -88,7 +96,11 @@ class Chunk { } addModule(module) { - return this.addToCollection(this.modules, module); + if(!this._modules.has(module)) { + this._modules.add(module); + return true; + } + return false; } addBlock(block) { @@ -96,9 +108,7 @@ class Chunk { } removeModule(module) { - const idx = this.modules.indexOf(module); - if(idx >= 0) { - this.modules.splice(idx, 1); + if(this._modules.delete(module)) { module.removeChunk(this); return true; } @@ -133,9 +143,65 @@ class Chunk { }); } + setModules(modules) { + this._modules = new SortableSet(modules, sortByIdentifier); + } + + getNumberOfModules() { + return this._modules.size; + } + + get modulesIterable() { + return this._modules; + } + + forEachModule(fn) { + this._modules.forEach(fn); + } + + mapModules(fn) { + return Array.from(this._modules, fn); + } + + compareTo(otherChunk) { + this._modules.sort(); + otherChunk._modules.sort(); + if(this._modules.size > otherChunk._modules.size) return -1; + if(this._modules.size < otherChunk._modules.size) return 1; + const a = this._modules[Symbol.iterator](); + const b = otherChunk._modules[Symbol.iterator](); + while(true) { // eslint-disable-line + const aItem = a.next(); + const bItem = b.next(); + if(aItem.done) return 0; + const aModuleIdentifier = aItem.value.identifier(); + const bModuleIdentifier = bItem.value.identifier(); + if(aModuleIdentifier > bModuleIdentifier) return -1; + if(aModuleIdentifier < bModuleIdentifier) return 1; + } + } + + containsModule(module) { + return this._modules.has(module); + } + + getModules() { + return Array.from(this._modules); + } + + getModulesIdent() { + this._modules.sort(); + let str = ""; + this._modules.forEach(m => { + str += m.identifier() + "#"; + }); + return str; + } + remove(reason) { // cleanup modules - this.modules.slice().forEach(module => { + // Array.from is used here to create a clone, because removeChunk modifies this._modules + Array.from(this._modules).forEach(module => { module.removeChunk(this); }); @@ -219,9 +285,10 @@ class Chunk { return false; } - const otherChunkModules = otherChunk.modules.slice(); + // Array.from is used here to create a clone, because moveModule modifies otherChunk._modules + const otherChunkModules = Array.from(otherChunk._modules); otherChunkModules.forEach(module => otherChunk.moveModule(module, this)); - otherChunk.modules.length = 0; + otherChunk._modules.clear(); otherChunk.parents.forEach(parentChunk => parentChunk.replaceChunk(otherChunk, this)); otherChunk.parents.length = 0; @@ -276,14 +343,14 @@ class Chunk { } isEmpty() { - return this.modules.length === 0; + return this._modules.size === 0; } updateHash(hash) { hash.update(`${this.id} `); hash.update(this.ids ? this.ids.join(",") : ""); hash.update(`${this.name || ""} `); - this.modules.forEach(m => m.updateHash(hash)); + this._modules.forEach(m => m.updateHash(hash)); } canBeIntegrated(otherChunk) { @@ -307,8 +374,8 @@ class Chunk { modulesSize() { let count = 0; - for(let i = 0; i < this.modules.length; i++) { - count += this.modules[i].size(); + for(const module of this._modules) { + count += module.size(); } return count; } @@ -325,9 +392,8 @@ class Chunk { let integratedModulesSize = this.modulesSize(); // only count modules that do not exist in this chunk! - for(let i = 0; i < otherChunk.modules.length; i++) { - const otherModule = otherChunk.modules[i]; - if(this.modules.indexOf(otherModule) === -1) { + for(const otherModule of otherChunk._modules) { + if(!this._modules.has(otherModule)) { integratedModulesSize += otherModule.size(); } } @@ -355,8 +421,12 @@ class Chunk { }; } + sortModules(sortByFn) { + this._modules.sortWith(sortByFn || sortById); + } + sortItems() { - this.modules.sort(byId); + this.sortModules(); this.origins.sort((a, b) => { const aIdent = a.module.identifier(); const bIdent = b.module.identifier(); @@ -368,12 +438,12 @@ class Chunk { if(origin.reasons) origin.reasons.sort(); }); - this.parents.sort(byId); - this.chunks.sort(byId); + this.parents.sort(sortById); + this.chunks.sort(sortById); } toString() { - return `Chunk[${this.modules.join()}]`; + return `Chunk[${Array.from(this._modules).join()}]`; } checkConstraints() { @@ -393,4 +463,14 @@ class Chunk { } } +Object.defineProperty(Chunk.prototype, "modules", { + configurable: false, + get: util.deprecate(function() { + return Array.from(this._modules); + }, "Chunk.modules is deprecated. Use Chunk.getNumberOfModules/mapModules/forEachModule/containsModule instead."), + set: util.deprecate(function(value) { + this.setModules(value); + }, "Chunk.modules is deprecated. Use Chunk.addModule/removeModule instead.") +}); + module.exports = Chunk; diff --git a/node_modules/webpack/lib/Compilation.js b/node_modules/webpack/lib/Compilation.js index 4ac48da50..b59c0eb53 100644 --- a/node_modules/webpack/lib/Compilation.js +++ b/node_modules/webpack/lib/Compilation.js @@ -22,6 +22,7 @@ const Dependency = require("./Dependency"); const ChunkRenderError = require("./ChunkRenderError"); const CachedSource = require("webpack-sources").CachedSource; const Stats = require("./Stats"); +const Semaphore = require("./util/Semaphore"); function byId(a, b) { if(a.id < b.id) return -1; @@ -62,6 +63,8 @@ class Compilation extends Tapable { this.hotUpdateChunkTemplate = new HotUpdateChunkTemplate(this.outputOptions); this.moduleTemplate = new ModuleTemplate(this.outputOptions); + this.semaphore = new Semaphore(options.parallelism || 100); + this.entries = []; this.preparedChunks = []; this.entrypoints = {}; @@ -80,6 +83,8 @@ class Compilation extends Tapable { this.children = []; this.dependencyFactories = new Map(); this.dependencyTemplates = new Map(); + this.dependencyTemplates.set("hash", ""); + this.childrenCounters = {}; } getStats() { @@ -112,8 +117,6 @@ class Compilation extends Tapable { cacheModule.errors.forEach(err => this.errors.push(err), this); cacheModule.warnings.forEach(err => this.warnings.push(err), this); return cacheModule; - } else { - module.lastId = cacheModule.id; } } module.unbuild(); @@ -229,120 +232,128 @@ class Compilation extends Tapable { callback(); }; - const factory = item[0]; - factory.create({ - contextInfo: { - issuer: module.nameForCondition && module.nameForCondition(), - compiler: _this.compiler.name - }, - context: module.context, - dependencies: dependencies - }, function factoryCallback(err, dependentModule) { - let afterFactory; - - function isOptional() { - return dependencies.filter(d => !d.optional).length === 0; - } + _this.semaphore.acquire(() => { + const factory = item[0]; + factory.create({ + contextInfo: { + issuer: module.nameForCondition && module.nameForCondition(), + compiler: _this.compiler.name + }, + context: module.context, + dependencies: dependencies + }, function factoryCallback(err, dependentModule) { + let afterFactory; + + function isOptional() { + return dependencies.filter(d => !d.optional).length === 0; + } - function errorOrWarningAndCallback(err) { - if(isOptional()) { - return warningAndCallback(err); - } else { - return errorAndCallback(err); + function errorOrWarningAndCallback(err) { + if(isOptional()) { + return warningAndCallback(err); + } else { + return errorAndCallback(err); + } } - } - function iterationDependencies(depend) { - for(let index = 0; index < depend.length; index++) { - const dep = depend[index]; - dep.module = dependentModule; - dependentModule.addReason(module, dep); + function iterationDependencies(depend) { + for(let index = 0; index < depend.length; index++) { + const dep = depend[index]; + dep.module = dependentModule; + dependentModule.addReason(module, dep); + } } - } - if(err) { - return errorOrWarningAndCallback(new ModuleNotFoundError(module, err, dependencies)); - } - if(!dependentModule) { - return process.nextTick(callback); - } - if(_this.profile) { - if(!dependentModule.profile) { - dependentModule.profile = {}; + if(err) { + _this.semaphore.release(); + return errorOrWarningAndCallback(new ModuleNotFoundError(module, err, dependencies)); + } + if(!dependentModule) { + _this.semaphore.release(); + return process.nextTick(callback); + } + if(_this.profile) { + if(!dependentModule.profile) { + dependentModule.profile = {}; + } + afterFactory = Date.now(); + dependentModule.profile.factory = afterFactory - start; } - afterFactory = Date.now(); - dependentModule.profile.factory = afterFactory - start; - } - dependentModule.issuer = module; - const newModule = _this.addModule(dependentModule, cacheGroup); + dependentModule.issuer = module; + const newModule = _this.addModule(dependentModule, cacheGroup); - if(!newModule) { // from cache - dependentModule = _this.getModule(dependentModule); + if(!newModule) { // from cache + dependentModule = _this.getModule(dependentModule); - if(dependentModule.optional) { - dependentModule.optional = isOptional(); - } + if(dependentModule.optional) { + dependentModule.optional = isOptional(); + } - iterationDependencies(dependencies); + iterationDependencies(dependencies); - if(_this.profile) { - if(!module.profile) { - module.profile = {}; - } - const time = Date.now() - start; - if(!module.profile.dependencies || time > module.profile.dependencies) { - module.profile.dependencies = time; + if(_this.profile) { + if(!module.profile) { + module.profile = {}; + } + const time = Date.now() - start; + if(!module.profile.dependencies || time > module.profile.dependencies) { + module.profile.dependencies = time; + } } + + _this.semaphore.release(); + return process.nextTick(callback); } - return process.nextTick(callback); - } + if(newModule instanceof Module) { + if(_this.profile) { + newModule.profile = dependentModule.profile; + } - if(newModule instanceof Module) { - if(_this.profile) { - newModule.profile = dependentModule.profile; - } + newModule.optional = isOptional(); + newModule.issuer = dependentModule.issuer; + dependentModule = newModule; - newModule.optional = isOptional(); - newModule.issuer = dependentModule.issuer; - dependentModule = newModule; + iterationDependencies(dependencies); - iterationDependencies(dependencies); + if(_this.profile) { + const afterBuilding = Date.now(); + module.profile.building = afterBuilding - afterFactory; + } - if(_this.profile) { - const afterBuilding = Date.now(); - module.profile.building = afterBuilding - afterFactory; + _this.semaphore.release(); + if(recursive) { + return process.nextTick(_this.processModuleDependencies.bind(_this, dependentModule, callback)); + } else { + return process.nextTick(callback); + } } - if(recursive) { - return process.nextTick(_this.processModuleDependencies.bind(_this, dependentModule, callback)); - } else { - return process.nextTick(callback); - } - } + dependentModule.optional = isOptional(); - dependentModule.optional = isOptional(); + iterationDependencies(dependencies); - iterationDependencies(dependencies); + _this.buildModule(dependentModule, isOptional(), module, dependencies, err => { + if(err) { + _this.semaphore.release(); + return errorOrWarningAndCallback(err); + } - _this.buildModule(dependentModule, isOptional(), module, dependencies, err => { - if(err) { - return errorOrWarningAndCallback(err); - } + if(_this.profile) { + const afterBuilding = Date.now(); + dependentModule.profile.building = afterBuilding - afterFactory; + } - if(_this.profile) { - const afterBuilding = Date.now(); - dependentModule.profile.building = afterBuilding - afterFactory; - } + _this.semaphore.release(); + if(recursive) { + _this.processModuleDependencies(dependentModule, callback); + } else { + return callback(); + } + }); - if(recursive) { - _this.processModuleDependencies(dependentModule, callback); - } else { - return callback(); - } }); - }); }, function finalCallbackAddModuleDependencies(err) { // In V8, the Error objects keep a reference to the functions on the stack. These warnings & @@ -362,13 +373,13 @@ class Compilation extends Tapable { _addModuleChain(context, dependency, onModule, callback) { const start = this.profile && Date.now(); - const errorAndCallback = this.bail ? function errorAndCallback(err) { + const errorAndCallback = this.bail ? (err) => { callback(err); - } : function errorAndCallback(err) { + } : (err) => { err.dependencies = [dependency]; this.errors.push(err); callback(); - }.bind(this); + }; if(typeof dependency !== "object" || dependency === null || !dependency.constructor) { throw new Error("Parameter 'dependency' must be a Dependency"); @@ -379,79 +390,85 @@ class Compilation extends Tapable { throw new Error(`No dependency factory available for this dependency type: ${dependency.constructor.name}`); } - moduleFactory.create({ - contextInfo: { - issuer: "", - compiler: this.compiler.name - }, - context: context, - dependencies: [dependency] - }, (err, module) => { - if(err) { - return errorAndCallback(new EntryModuleNotFoundError(err)); - } - - let afterFactory; - - if(this.profile) { - if(!module.profile) { - module.profile = {}; + this.semaphore.acquire(() => { + moduleFactory.create({ + contextInfo: { + issuer: "", + compiler: this.compiler.name + }, + context: context, + dependencies: [dependency] + }, (err, module) => { + if(err) { + this.semaphore.release(); + return errorAndCallback(new EntryModuleNotFoundError(err)); } - afterFactory = Date.now(); - module.profile.factory = afterFactory - start; - } - - const result = this.addModule(module); - if(!result) { - module = this.getModule(module); - onModule(module); + let afterFactory; if(this.profile) { - const afterBuilding = Date.now(); - module.profile.building = afterBuilding - afterFactory; + if(!module.profile) { + module.profile = {}; + } + afterFactory = Date.now(); + module.profile.factory = afterFactory - start; } - return callback(null, module); - } + const result = this.addModule(module); + if(!result) { + module = this.getModule(module); - if(result instanceof Module) { - if(this.profile) { - result.profile = module.profile; - } + onModule(module); - module = result; + if(this.profile) { + const afterBuilding = Date.now(); + module.profile.building = afterBuilding - afterFactory; + } - onModule(module); + this.semaphore.release(); + return callback(null, module); + } - moduleReady.call(this); - return; - } + if(result instanceof Module) { + if(this.profile) { + result.profile = module.profile; + } - onModule(module); + module = result; - this.buildModule(module, false, null, null, (err) => { - if(err) { - return errorAndCallback(err); - } + onModule(module); - if(this.profile) { - const afterBuilding = Date.now(); - module.profile.building = afterBuilding - afterFactory; + moduleReady.call(this); + return; } - moduleReady.call(this); - }); + onModule(module); - function moduleReady() { - this.processModuleDependencies(module, err => { + this.buildModule(module, false, null, null, (err) => { if(err) { - return callback(err); + this.semaphore.release(); + return errorAndCallback(err); } - return callback(null, module); + if(this.profile) { + const afterBuilding = Date.now(); + module.profile.building = afterBuilding - afterFactory; + } + + moduleReady.call(this); }); - } + + function moduleReady() { + this.semaphore.release(); + this.processModuleDependencies(module, err => { + if(err) { + return callback(err); + } + + return callback(null, module); + }); + } + }); }); } @@ -511,7 +528,7 @@ class Compilation extends Tapable { if(err) return callback(err); deps.forEach(d => { if(d.module && d.module.removeReason(module, d)) { - module.chunks.forEach(chunk => { + module.forEachChunk(chunk => { if(!d.module.hasReasonForChunk(chunk)) { if(d.module.removeChunk(chunk)) { this.removeChunkFromDependencies(d.module, chunk); @@ -568,12 +585,12 @@ class Compilation extends Tapable { while(self.applyPluginsBailResult1("optimize-modules-basic", self.modules) || self.applyPluginsBailResult1("optimize-modules", self.modules) || - self.applyPluginsBailResult1("optimize-modules-advanced", self.modules)); // eslint-disable-line no-extra-semi + self.applyPluginsBailResult1("optimize-modules-advanced", self.modules)) { /* empty */ } self.applyPlugins1("after-optimize-modules", self.modules); while(self.applyPluginsBailResult1("optimize-chunks-basic", self.chunks) || self.applyPluginsBailResult1("optimize-chunks", self.chunks) || - self.applyPluginsBailResult1("optimize-chunks-advanced", self.chunks)); // eslint-disable-line no-extra-semi + self.applyPluginsBailResult1("optimize-chunks-advanced", self.chunks)) { /* empty */ } self.applyPlugins1("after-optimize-chunks", self.chunks); self.applyPluginsAsyncSeries("optimize-tree", self.chunks, self.modules, function sealPart2(err) { @@ -583,6 +600,11 @@ class Compilation extends Tapable { self.applyPlugins2("after-optimize-tree", self.chunks, self.modules); + while(self.applyPluginsBailResult("optimize-chunk-modules-basic", self.chunks, self.modules) || + self.applyPluginsBailResult("optimize-chunk-modules", self.chunks, self.modules) || + self.applyPluginsBailResult("optimize-chunk-modules-advanced", self.chunks, self.modules)) { /* empty */ } + self.applyPlugins2("after-optimize-chunk-modules", self.chunks, self.modules); + const shouldRecord = self.applyPluginsBailResult("should-record") !== false; self.applyPlugins2("revive-modules", self.modules, self.records); @@ -824,7 +846,11 @@ class Compilation extends Tapable { } } - processDependenciesBlockForChunk(block, chunk) { + processDependenciesBlockForChunk(module, chunk) { + let block = module; + const initialChunk = chunk; + const chunkDependencies = new Map(); // Map> + const iteratorBlock = b => { let c; if(!b.chunks) { @@ -834,9 +860,17 @@ class Compilation extends Tapable { } else { c = b.chunks[0]; } - chunk.addChunk(c); - c.addParent(chunk); - queue.push([b, c]); + let deps = chunkDependencies.get(chunk); + if(!deps) chunkDependencies.set(chunk, deps = []); + deps.push({ + chunk: c, + module + }); + queue.push({ + block: b, + module: null, + chunk: c + }); }; const iteratorDependency = d => { @@ -848,18 +882,25 @@ class Compilation extends Tapable { } if(chunk.addModule(d.module)) { d.module.addChunk(chunk); - queue.push([d.module, chunk]); + queue.push({ + block: d.module, + module: d.module, + chunk + }); } }; - const queue = [ - [block, chunk] - ]; + const queue = [{ + block, + module, + chunk + }]; while(queue.length) { const queueItem = queue.pop(); - block = queueItem[0]; - chunk = queueItem[1]; + block = queueItem.block; + module = queueItem.module; + chunk = queueItem.chunk; if(block.variables) { iterationBlockVariable(block.variables, iteratorDependency); @@ -873,6 +914,47 @@ class Compilation extends Tapable { iterationOfArrayCallback(block.blocks, iteratorBlock); } } + + chunk = initialChunk; + let chunks = new Set(); + const queue2 = [{ + chunk, + chunks + }]; + + const filterFn = dep => { + if(chunks.has(dep.chunk)) return false; + for(const chunk of chunks) { + if(chunk.containsModule(dep.module)) + return false; + } + return true; + }; + + while(queue2.length) { + const queueItem = queue2.pop(); + chunk = queueItem.chunk; + chunks = queueItem.chunks; + + const deps = chunkDependencies.get(chunk); + if(!deps) continue; + + const depsFiltered = deps.filter(filterFn); + + for(let i = 0; i < depsFiltered.length; i++) { + const dep = depsFiltered[i]; + const depChunk = dep.chunk; + chunk.addChunk(depChunk); + depChunk.addParent(chunk); + + const newChunks = depsFiltered.length > 1 ? new Set(chunks) : chunks; + newChunks.add(chunk); + queue2.push({ + chunk: depChunk, + chunks: newChunks + }); + } + } } removeChunkFromDependencies(block, chunk) { @@ -1017,7 +1099,7 @@ class Compilation extends Tapable { const modules = this.modules; for(let indexModule = 0; indexModule < modules.length; indexModule++) { - modules[indexModule].sortItems(); + modules[indexModule].sortItems(false); } const chunks = this.chunks; @@ -1031,13 +1113,24 @@ class Compilation extends Tapable { const modules = this.modules; for(let indexModule = 0; indexModule < modules.length; indexModule++) { - modules[indexModule].sortItems(); + modules[indexModule].sortItems(true); } const chunks = this.chunks; for(let indexChunk = 0; indexChunk < chunks.length; indexChunk++) { chunks[indexChunk].sortItems(); } + + const byMessage = (a, b) => { + const ma = `${a.message}`; + const mb = `${b.message}`; + if(ma < mb) return -1; + if(mb < ma) return 1; + return 0; + }; + + this.errors.sort(byMessage); + this.warnings.sort(byMessage); } summarizeDependencies() { @@ -1106,6 +1199,12 @@ class Compilation extends Tapable { this.children.forEach(function(child) { hash.update(child.hash); }); + this.warnings.forEach(function(warning) { + hash.update(`${warning.message}`); + }); + this.errors.forEach(function(error) { + hash.update(`${error.message}`); + }); // clone needed as sort below is inplace mutation const chunks = this.chunks.slice(); /** @@ -1218,8 +1317,10 @@ class Compilation extends Tapable { return this.mainTemplate.applyPluginsWaterfall("asset-path", filename, data); } - createChildCompiler(name, outputOptions) { - return this.compiler.createChildCompiler(this, name, outputOptions); + createChildCompiler(name, outputOptions, plugins) { + var idx = (this.childrenCounters[name] || 0); + this.childrenCounters[name] = idx + 1; + return this.compiler.createChildCompiler(this, name, idx, outputOptions, plugins); } checkConstraints() { diff --git a/node_modules/webpack/lib/Compiler.js b/node_modules/webpack/lib/Compiler.js index dc17a89f3..8e3118a8c 100644 --- a/node_modules/webpack/lib/Compiler.js +++ b/node_modules/webpack/lib/Compiler.js @@ -2,503 +2,528 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -var path = require("path"); -var Tapable = require("tapable"); - -var Compilation = require("./Compilation"); -var Stats = require("./Stats"); -var NormalModuleFactory = require("./NormalModuleFactory"); -var ContextModuleFactory = require("./ContextModuleFactory"); - -function Watching(compiler, watchOptions, handler) { - this.startTime = null; - this.invalid = false; - this.handler = handler; - this.closed = false; - if(typeof watchOptions === "number") { - this.watchOptions = { - aggregateTimeout: watchOptions - }; - } else if(watchOptions && typeof watchOptions === "object") { - this.watchOptions = Object.assign({}, watchOptions); - } else { - this.watchOptions = {}; +"use strict"; + +const path = require("path"); +const Tapable = require("tapable"); + +const Compilation = require("./Compilation"); +const Stats = require("./Stats"); +const NormalModuleFactory = require("./NormalModuleFactory"); +const ContextModuleFactory = require("./ContextModuleFactory"); + +const makePathsRelative = require("./util/identifier").makePathsRelative; + +class Watching { + constructor(compiler, watchOptions, handler) { + this.startTime = null; + this.invalid = false; + this.handler = handler; + this.callbacks = []; + this.closed = false; + if(typeof watchOptions === "number") { + this.watchOptions = { + aggregateTimeout: watchOptions + }; + } else if(watchOptions && typeof watchOptions === "object") { + this.watchOptions = Object.assign({}, watchOptions); + } else { + this.watchOptions = {}; + } + this.watchOptions.aggregateTimeout = this.watchOptions.aggregateTimeout || 200; + this.compiler = compiler; + this.running = true; + this.compiler.readRecords(err => { + if(err) return this._done(err); + + this._go(); + }); } - this.watchOptions.aggregateTimeout = this.watchOptions.aggregateTimeout || 200; - this.compiler = compiler; - this.running = true; - this.compiler.readRecords(function(err) { - if(err) return this._done(err); - - this._go(); - }.bind(this)); -} -Watching.prototype._go = function() { - var self = this; - self.startTime = Date.now(); - self.running = true; - self.invalid = false; - self.compiler.applyPluginsAsync("watch-run", self, function(err) { - if(err) return self._done(err); - self.compiler.compile(function onCompiled(err, compilation) { - if(err) return self._done(err); - if(self.invalid) return self._done(); - - if(self.compiler.applyPluginsBailResult("should-emit", compilation) === false) { - return self._done(null, compilation); - } + _go() { + this.startTime = Date.now(); + this.running = true; + this.invalid = false; + this.compiler.applyPluginsAsync("watch-run", this, err => { + if(err) return this._done(err); + const onCompiled = (err, compilation) => { + if(err) return this._done(err); + if(this.invalid) return this._done(); + + if(this.compiler.applyPluginsBailResult("should-emit", compilation) === false) { + return this._done(null, compilation); + } - self.compiler.emitAssets(compilation, function(err) { - if(err) return self._done(err); - if(self.invalid) return self._done(); + this.compiler.emitAssets(compilation, err => { + if(err) return this._done(err); + if(this.invalid) return this._done(); - self.compiler.emitRecords(function(err) { - if(err) return self._done(err); + this.compiler.emitRecords(err => { + if(err) return this._done(err); - if(compilation.applyPluginsBailResult("need-additional-pass")) { - compilation.needAdditionalPass = true; + if(compilation.applyPluginsBailResult("need-additional-pass")) { + compilation.needAdditionalPass = true; - var stats = new Stats(compilation); - stats.startTime = self.startTime; - stats.endTime = Date.now(); - self.compiler.applyPlugins("done", stats); + const stats = new Stats(compilation); + stats.startTime = this.startTime; + stats.endTime = Date.now(); + this.compiler.applyPlugins("done", stats); - self.compiler.applyPluginsAsync("additional-pass", function(err) { - if(err) return self._done(err); - self.compiler.compile(onCompiled); - }); - return; - } - return self._done(null, compilation); + this.compiler.applyPluginsAsync("additional-pass", err => { + if(err) return this._done(err); + this.compiler.compile(onCompiled); + }); + return; + } + return this._done(null, compilation); + }); }); - }); + }; + this.compiler.compile(onCompiled); }); - }); -}; - -Watching.prototype._getStats = function(compilation) { - var stats = new Stats(compilation); - stats.startTime = this.startTime; - stats.endTime = Date.now(); - return stats; -}; - -Watching.prototype._done = function(err, compilation) { - this.running = false; - if(this.invalid) return this._go(); - - var stats = compilation ? this._getStats(compilation) : null; - if(err) { - this.compiler.applyPlugins("failed", err); - this.handler(err, stats); - return; } - this.compiler.applyPlugins("done", stats); - this.handler(null, stats); - if(!this.closed) { - this.watch(compilation.fileDependencies, compilation.contextDependencies, compilation.missingDependencies); - } -}; - -Watching.prototype.watch = function(files, dirs, missing) { - this.pausedWatcher = null; - this.watcher = this.compiler.watchFileSystem.watch(files, dirs, missing, this.startTime, this.watchOptions, function(err, filesModified, contextModified, missingModified, fileTimestamps, contextTimestamps) { - this.pausedWatcher = this.watcher; - this.watcher = null; - if(err) return this.handler(err); - - this.compiler.fileTimestamps = fileTimestamps; - this.compiler.contextTimestamps = contextTimestamps; - this.invalidate(); - }.bind(this), function(fileName, changeTime) { - this.compiler.applyPlugins("invalid", fileName, changeTime); - }.bind(this)); -}; - -Watching.prototype.invalidate = function() { - if(this.watcher) { - this.pausedWatcher = this.watcher; - this.watcher.pause(); - this.watcher = null; + _getStats(compilation) { + const stats = new Stats(compilation); + stats.startTime = this.startTime; + stats.endTime = Date.now(); + return stats; } - if(this.running) { - this.invalid = true; - return false; - } else { - this._go(); - } -}; - -Watching.prototype.close = function(callback) { - if(callback === undefined) callback = function() {}; - this.closed = true; - if(this.watcher) { - this.watcher.close(); - this.watcher = null; + _done(err, compilation) { + this.running = false; + if(this.invalid) return this._go(); + + const stats = compilation ? this._getStats(compilation) : null; + if(err) { + this.compiler.applyPlugins("failed", err); + this.handler(err, stats); + return; + } + + this.compiler.applyPlugins("done", stats); + this.handler(null, stats); + if(!this.closed) { + this.watch(compilation.fileDependencies, compilation.contextDependencies, compilation.missingDependencies); + } + this.callbacks.forEach(cb => cb()); + this.callbacks.length = 0; } - if(this.pausedWatcher) { - this.pausedWatcher.close(); + + watch(files, dirs, missing) { this.pausedWatcher = null; + this.watcher = this.compiler.watchFileSystem.watch(files, dirs, missing, this.startTime, this.watchOptions, (err, filesModified, contextModified, missingModified, fileTimestamps, contextTimestamps) => { + this.pausedWatcher = this.watcher; + this.watcher = null; + if(err) return this.handler(err); + + this.compiler.fileTimestamps = fileTimestamps; + this.compiler.contextTimestamps = contextTimestamps; + this.invalidate(); + }, (fileName, changeTime) => { + this.compiler.applyPlugins("invalid", fileName, changeTime); + }); + } + + invalidate(callback) { + if(callback) { + this.callbacks.push(callback); + } + if(this.watcher) { + this.pausedWatcher = this.watcher; + this.watcher.pause(); + this.watcher = null; + } + if(this.running) { + this.invalid = true; + return false; + } else { + this._go(); + } } - if(this.running) { - this.invalid = true; - this._done = () => { + + close(callback) { + if(callback === undefined) callback = function() {}; + + this.closed = true; + if(this.watcher) { + this.watcher.close(); + this.watcher = null; + } + if(this.pausedWatcher) { + this.pausedWatcher.close(); + this.pausedWatcher = null; + } + if(this.running) { + this.invalid = true; + this._done = () => { + this.compiler.applyPlugins("watch-close"); + callback(); + }; + } else { this.compiler.applyPlugins("watch-close"); callback(); - }; - } else { - this.compiler.applyPlugins("watch-close"); - callback(); + } } -}; - -function Compiler() { - Tapable.call(this); - - this.outputPath = ""; - this.outputFileSystem = null; - this.inputFileSystem = null; - - this.recordsInputPath = null; - this.recordsOutputPath = null; - this.records = {}; - - this.fileTimestamps = {}; - this.contextTimestamps = {}; - - this.resolvers = { - normal: null, - loader: null, - context: null - }; - var deprecationReported = false; - this.parser = { - plugin: function(hook, fn) { - if(!deprecationReported) { - console.warn("webpack: Using compiler.parser is deprecated.\n" + - "Use compiler.plugin(\"compilation\", function(compilation, data) {\n data.normalModuleFactory.plugin(\"parser\", function(parser, options) { parser.plugin(/* ... */); });\n}); instead. " + - "It was called " + new Error().stack.split("\n")[2].trim() + "."); - deprecationReported = true; - } - this.plugin("compilation", function(compilation, data) { - data.normalModuleFactory.plugin("parser", function(parser) { - parser.plugin(hook, fn); - }); - }); - }.bind(this), - apply: function() { - var args = arguments; - if(!deprecationReported) { - console.warn("webpack: Using compiler.parser is deprecated.\n" + - "Use compiler.plugin(\"compilation\", function(compilation, data) {\n data.normalModuleFactory.plugin(\"parser\", function(parser, options) { parser.apply(/* ... */); });\n}); instead. " + - "It was called " + new Error().stack.split("\n")[2].trim() + "."); - deprecationReported = true; - } - this.plugin("compilation", function(compilation, data) { - data.normalModuleFactory.plugin("parser", function(parser) { - parser.apply.apply(parser, args); - }); - }); - }.bind(this) - }; - - this.options = {}; } -module.exports = Compiler; -Compiler.prototype = Object.create(Tapable.prototype); -Compiler.prototype.constructor = Compiler; +class Compiler extends Tapable { + constructor() { + super(); + this.outputPath = ""; + this.outputFileSystem = null; + this.inputFileSystem = null; -Compiler.Watching = Watching; -Compiler.prototype.watch = function(watchOptions, handler) { - this.fileTimestamps = {}; - this.contextTimestamps = {}; - var watching = new Watching(this, watchOptions, handler); - return watching; -}; + this.recordsInputPath = null; + this.recordsOutputPath = null; + this.records = {}; + + this.fileTimestamps = {}; + this.contextTimestamps = {}; -Compiler.prototype.run = function(callback) { - var self = this; - var startTime = Date.now(); + this.resolvers = { + normal: null, + loader: null, + context: null + }; + let deprecationReported = false; + this.parser = { + plugin: (hook, fn) => { + if(!deprecationReported) { + console.warn("webpack: Using compiler.parser is deprecated.\n" + + "Use compiler.plugin(\"compilation\", function(compilation, data) {\n data.normalModuleFactory.plugin(\"parser\", function(parser, options) { parser.plugin(/* ... */); });\n}); instead. " + + "It was called " + new Error().stack.split("\n")[2].trim() + "."); + deprecationReported = true; + } + this.plugin("compilation", (compilation, data) => { + data.normalModuleFactory.plugin("parser", parser => { + parser.plugin(hook, fn); + }); + }); + }, + apply: () => { + const args = arguments; + if(!deprecationReported) { + console.warn("webpack: Using compiler.parser is deprecated.\n" + + "Use compiler.plugin(\"compilation\", function(compilation, data) {\n data.normalModuleFactory.plugin(\"parser\", function(parser, options) { parser.apply(/* ... */); });\n}); instead. " + + "It was called " + new Error().stack.split("\n")[2].trim() + "."); + deprecationReported = true; + } + this.plugin("compilation", (compilation, data) => { + data.normalModuleFactory.plugin("parser", parser => { + parser.apply.apply(parser, args); + }); + }); + } + }; - self.applyPluginsAsync("before-run", self, function(err) { - if(err) return callback(err); + this.options = {}; + } + + watch(watchOptions, handler) { + this.fileTimestamps = {}; + this.contextTimestamps = {}; + const watching = new Watching(this, watchOptions, handler); + return watching; + } + + run(callback) { + const startTime = Date.now(); - self.applyPluginsAsync("run", self, function(err) { + const onCompiled = (err, compilation) => { if(err) return callback(err); - self.readRecords(function(err) { + if(this.applyPluginsBailResult("should-emit", compilation) === false) { + const stats = new Stats(compilation); + stats.startTime = startTime; + stats.endTime = Date.now(); + this.applyPlugins("done", stats); + return callback(null, stats); + } + + this.emitAssets(compilation, err => { if(err) return callback(err); - self.compile(function onCompiled(err, compilation) { - if(err) return callback(err); + if(compilation.applyPluginsBailResult("need-additional-pass")) { + compilation.needAdditionalPass = true; - if(self.applyPluginsBailResult("should-emit", compilation) === false) { - var stats = new Stats(compilation); - stats.startTime = startTime; - stats.endTime = Date.now(); - self.applyPlugins("done", stats); - return callback(null, stats); - } + const stats = new Stats(compilation); + stats.startTime = startTime; + stats.endTime = Date.now(); + this.applyPlugins("done", stats); - self.emitAssets(compilation, function(err) { + this.applyPluginsAsync("additional-pass", err => { if(err) return callback(err); + this.compile(onCompiled); + }); + return; + } - if(compilation.applyPluginsBailResult("need-additional-pass")) { - compilation.needAdditionalPass = true; + this.emitRecords(err => { + if(err) return callback(err); - var stats = new Stats(compilation); - stats.startTime = startTime; - stats.endTime = Date.now(); - self.applyPlugins("done", stats); + const stats = new Stats(compilation); + stats.startTime = startTime; + stats.endTime = Date.now(); + this.applyPlugins("done", stats); + return callback(null, stats); + }); + }); + }; - self.applyPluginsAsync("additional-pass", function(err) { - if(err) return callback(err); - self.compile(onCompiled); - }); - return; - } + this.applyPluginsAsync("before-run", this, err => { + if(err) return callback(err); - self.emitRecords(function(err) { - if(err) return callback(err); + this.applyPluginsAsync("run", this, err => { + if(err) return callback(err); - var stats = new Stats(compilation); - stats.startTime = startTime; - stats.endTime = Date.now(); - self.applyPlugins("done", stats); - return callback(null, stats); - }); - }); + this.readRecords(err => { + if(err) return callback(err); + + this.compile(onCompiled); }); }); }); - }); -}; - -Compiler.prototype.runAsChild = function(callback) { - this.compile(function(err, compilation) { - if(err) return callback(err); - - this.parentCompilation.children.push(compilation); - Object.keys(compilation.assets).forEach(function(name) { - this.parentCompilation.assets[name] = compilation.assets[name]; - }.bind(this)); - - var entries = Object.keys(compilation.entrypoints).map(function(name) { - return compilation.entrypoints[name].chunks; - }).reduce(function(array, chunks) { - return array.concat(chunks); - }, []); - - return callback(null, entries, compilation); - }.bind(this)); -}; - -Compiler.prototype.purgeInputFileSystem = function() { - if(this.inputFileSystem && this.inputFileSystem.purge) - this.inputFileSystem.purge(); -}; - -Compiler.prototype.emitAssets = function(compilation, callback) { - var outputPath; - - this.applyPluginsAsync("emit", compilation, function(err) { - if(err) return callback(err); - outputPath = compilation.getPath(this.outputPath); - this.outputFileSystem.mkdirp(outputPath, emitFiles.bind(this)); - }.bind(this)); - - function emitFiles(err) { - if(err) return callback(err); - - require("async").forEach(Object.keys(compilation.assets), function(file, callback) { - - var targetFile = file; - var queryStringIdx = targetFile.indexOf("?"); - if(queryStringIdx >= 0) { - targetFile = targetFile.substr(0, queryStringIdx); - } + } - if(targetFile.match(/\/|\\/)) { - var dir = path.dirname(targetFile); - this.outputFileSystem.mkdirp(this.outputFileSystem.join(outputPath, dir), writeOut.bind(this)); - } else writeOut.call(this); + runAsChild(callback) { + this.compile((err, compilation) => { + if(err) return callback(err); - function writeOut(err) { - if(err) return callback(err); - var targetPath = this.outputFileSystem.join(outputPath, targetFile); - var source = compilation.assets[file]; - if(source.existsAt === targetPath) { - source.emitted = false; - return callback(); - } - var content = source.source(); + this.parentCompilation.children.push(compilation); + Object.keys(compilation.assets).forEach(name => { + this.parentCompilation.assets[name] = compilation.assets[name]; + }); + + const entries = Object.keys(compilation.entrypoints).map(name => { + return compilation.entrypoints[name].chunks; + }).reduce((array, chunks) => { + return array.concat(chunks); + }, []); + + return callback(null, entries, compilation); + }); + } + + purgeInputFileSystem() { + if(this.inputFileSystem && this.inputFileSystem.purge) + this.inputFileSystem.purge(); + } + + emitAssets(compilation, callback) { + let outputPath; + + const emitFiles = (err) => { + if(err) return callback(err); - if(!Buffer.isBuffer(content)) { - content = new Buffer(content, "utf8"); //eslint-disable-line + require("async").forEach(Object.keys(compilation.assets), (file, callback) => { + + let targetFile = file; + const queryStringIdx = targetFile.indexOf("?"); + if(queryStringIdx >= 0) { + targetFile = targetFile.substr(0, queryStringIdx); } - source.existsAt = targetPath; - source.emitted = true; - this.outputFileSystem.writeFile(targetPath, content, callback); - } + const writeOut = (err) => { + if(err) return callback(err); + const targetPath = this.outputFileSystem.join(outputPath, targetFile); + const source = compilation.assets[file]; + if(source.existsAt === targetPath) { + source.emitted = false; + return callback(); + } + let content = source.source(); + + if(!Buffer.isBuffer(content)) { + content = new Buffer(content, "utf8"); // eslint-disable-line + } + + source.existsAt = targetPath; + source.emitted = true; + this.outputFileSystem.writeFile(targetPath, content, callback); + }; + + if(targetFile.match(/\/|\\/)) { + const dir = path.dirname(targetFile); + this.outputFileSystem.mkdirp(this.outputFileSystem.join(outputPath, dir), writeOut); + } else writeOut(); - }.bind(this), function(err) { + }, err => { + if(err) return callback(err); + + afterEmit.call(this); + }); + }; + + this.applyPluginsAsync("emit", compilation, err => { if(err) return callback(err); + outputPath = compilation.getPath(this.outputPath); + this.outputFileSystem.mkdirp(outputPath, emitFiles); + }); + + function afterEmit() { + this.applyPluginsAsyncSeries1("after-emit", compilation, err => { + if(err) return callback(err); + + return callback(); + }); + } - afterEmit.call(this); - }.bind(this)); } - function afterEmit() { - this.applyPluginsAsyncSeries1("after-emit", compilation, function(err) { + emitRecords(callback) { + if(!this.recordsOutputPath) return callback(); + const idx1 = this.recordsOutputPath.lastIndexOf("/"); + const idx2 = this.recordsOutputPath.lastIndexOf("\\"); + let recordsOutputPathDirectory = null; + if(idx1 > idx2) recordsOutputPathDirectory = this.recordsOutputPath.substr(0, idx1); + if(idx1 < idx2) recordsOutputPathDirectory = this.recordsOutputPath.substr(0, idx2); + if(!recordsOutputPathDirectory) return writeFile.call(this); + this.outputFileSystem.mkdirp(recordsOutputPathDirectory, err => { if(err) return callback(err); + writeFile.call(this); + }); + + function writeFile() { + this.outputFileSystem.writeFile(this.recordsOutputPath, JSON.stringify(this.records, undefined, 2), callback); + } + } + readRecords(callback) { + if(!this.recordsInputPath) { + this.records = {}; return callback(); + } + this.inputFileSystem.stat(this.recordsInputPath, err => { + // It doesn't exist + // We can ignore this. + if(err) return callback(); + + this.inputFileSystem.readFile(this.recordsInputPath, (err, content) => { + if(err) return callback(err); + + try { + this.records = JSON.parse(content.toString("utf-8")); + } catch(e) { + e.message = "Cannot parse records: " + e.message; + return callback(e); + } + + return callback(); + }); }); } -}; - -Compiler.prototype.emitRecords = function emitRecords(callback) { - if(!this.recordsOutputPath) return callback(); - var idx1 = this.recordsOutputPath.lastIndexOf("/"); - var idx2 = this.recordsOutputPath.lastIndexOf("\\"); - var recordsOutputPathDirectory = null; - if(idx1 > idx2) recordsOutputPathDirectory = this.recordsOutputPath.substr(0, idx1); - if(idx1 < idx2) recordsOutputPathDirectory = this.recordsOutputPath.substr(0, idx2); - if(!recordsOutputPathDirectory) return writeFile.call(this); - this.outputFileSystem.mkdirp(recordsOutputPathDirectory, function(err) { - if(err) return callback(err); - writeFile.call(this); - }.bind(this)); - - function writeFile() { - this.outputFileSystem.writeFile(this.recordsOutputPath, JSON.stringify(this.records, undefined, 2), callback); + createChildCompiler(compilation, compilerName, compilerIndex, outputOptions, plugins) { + const childCompiler = new Compiler(); + if(Array.isArray(plugins)) { + plugins.forEach(plugin => childCompiler.apply(plugin)); + } + for(const name in this._plugins) { + if(["make", "compile", "emit", "after-emit", "invalid", "done", "this-compilation"].indexOf(name) < 0) + childCompiler._plugins[name] = this._plugins[name].slice(); + } + childCompiler.name = compilerName; + childCompiler.outputPath = this.outputPath; + childCompiler.inputFileSystem = this.inputFileSystem; + childCompiler.outputFileSystem = null; + childCompiler.resolvers = this.resolvers; + childCompiler.fileTimestamps = this.fileTimestamps; + childCompiler.contextTimestamps = this.contextTimestamps; + + const relativeCompilerName = makePathsRelative(this.context, compilerName); + if(!this.records[relativeCompilerName]) this.records[relativeCompilerName] = []; + if(this.records[relativeCompilerName][compilerIndex]) + childCompiler.records = this.records[relativeCompilerName][compilerIndex]; + else + this.records[relativeCompilerName].push(childCompiler.records = {}); + + if(this.cache) { + if(!this.cache.children) this.cache.children = {}; + if(!this.cache.children[compilerName]) this.cache.children[compilerName] = []; + if(this.cache.children[compilerName][compilerIndex]) + childCompiler.cache = this.cache.children[compilerName][compilerIndex]; + else + this.cache.children[compilerName].push(childCompiler.cache = {}); + } + + childCompiler.options = Object.create(this.options); + childCompiler.options.output = Object.create(childCompiler.options.output); + for(const name in outputOptions) { + childCompiler.options.output[name] = outputOptions[name]; + } + childCompiler.parentCompilation = compilation; + return childCompiler; } -}; -Compiler.prototype.readRecords = function readRecords(callback) { - var self = this; - if(!self.recordsInputPath) { - self.records = {}; - return callback(); + isChild() { + return !!this.parentCompilation; } - self.inputFileSystem.stat(self.recordsInputPath, function(err) { - // It doesn't exist - // We can ignore self. - if(err) return callback(); - - self.inputFileSystem.readFile(self.recordsInputPath, function(err, content) { - if(err) return callback(err); - try { - self.records = JSON.parse(content.toString("utf-8")); - } catch(e) { - e.message = "Cannot parse records: " + e.message; - return callback(e); - } + createCompilation() { + return new Compilation(this); + } - return callback(); - }); - }); -}; + newCompilation(params) { + const compilation = this.createCompilation(); + compilation.fileTimestamps = this.fileTimestamps; + compilation.contextTimestamps = this.contextTimestamps; + compilation.name = this.name; + compilation.records = this.records; + compilation.compilationDependencies = params.compilationDependencies; + this.applyPlugins("this-compilation", compilation, params); + this.applyPlugins("compilation", compilation, params); + return compilation; + } -Compiler.prototype.createChildCompiler = function(compilation, compilerName, outputOptions, plugins) { - var childCompiler = new Compiler(); - if(Array.isArray(plugins)) { - plugins.forEach(plugin => childCompiler.apply(plugin)); + createNormalModuleFactory() { + const normalModuleFactory = new NormalModuleFactory(this.options.context, this.resolvers, this.options.module || {}); + this.applyPlugins("normal-module-factory", normalModuleFactory); + return normalModuleFactory; } - for(var name in this._plugins) { - if(["make", "compile", "emit", "after-emit", "invalid", "done", "this-compilation"].indexOf(name) < 0) - childCompiler._plugins[name] = this._plugins[name].slice(); + + createContextModuleFactory() { + const contextModuleFactory = new ContextModuleFactory(this.resolvers, this.inputFileSystem); + this.applyPlugins("context-module-factory", contextModuleFactory); + return contextModuleFactory; } - childCompiler.name = compilerName; - childCompiler.outputPath = this.outputPath; - childCompiler.inputFileSystem = this.inputFileSystem; - childCompiler.outputFileSystem = null; - childCompiler.resolvers = this.resolvers; - childCompiler.fileTimestamps = this.fileTimestamps; - childCompiler.contextTimestamps = this.contextTimestamps; - if(!this.records[compilerName]) this.records[compilerName] = []; - this.records[compilerName].push(childCompiler.records = {}); - childCompiler.options = Object.create(this.options); - childCompiler.options.output = Object.create(childCompiler.options.output); - for(name in outputOptions) { - childCompiler.options.output[name] = outputOptions[name]; + + newCompilationParams() { + const params = { + normalModuleFactory: this.createNormalModuleFactory(), + contextModuleFactory: this.createContextModuleFactory(), + compilationDependencies: [] + }; + return params; } - childCompiler.parentCompilation = compilation; - return childCompiler; -}; - -Compiler.prototype.isChild = function() { - return !!this.parentCompilation; -}; - -Compiler.prototype.createCompilation = function() { - return new Compilation(this); -}; - -Compiler.prototype.newCompilation = function(params) { - var compilation = this.createCompilation(); - compilation.fileTimestamps = this.fileTimestamps; - compilation.contextTimestamps = this.contextTimestamps; - compilation.name = this.name; - compilation.records = this.records; - compilation.compilationDependencies = params.compilationDependencies; - this.applyPlugins("this-compilation", compilation, params); - this.applyPlugins("compilation", compilation, params); - return compilation; -}; - -Compiler.prototype.createNormalModuleFactory = function() { - var normalModuleFactory = new NormalModuleFactory(this.options.context, this.resolvers, this.options.module || {}); - this.applyPlugins("normal-module-factory", normalModuleFactory); - return normalModuleFactory; -}; - -Compiler.prototype.createContextModuleFactory = function() { - var contextModuleFactory = new ContextModuleFactory(this.resolvers, this.inputFileSystem); - this.applyPlugins("context-module-factory", contextModuleFactory); - return contextModuleFactory; -}; - -Compiler.prototype.newCompilationParams = function() { - var params = { - normalModuleFactory: this.createNormalModuleFactory(), - contextModuleFactory: this.createContextModuleFactory(), - compilationDependencies: [] - }; - return params; -}; - -Compiler.prototype.compile = function(callback) { - var self = this; - var params = self.newCompilationParams(); - self.applyPluginsAsync("before-compile", params, function(err) { - if(err) return callback(err); - - self.applyPlugins("compile", params); - - var compilation = self.newCompilation(params); - - self.applyPluginsParallel("make", compilation, function(err) { + + compile(callback) { + const params = this.newCompilationParams(); + this.applyPluginsAsync("before-compile", params, err => { if(err) return callback(err); - compilation.finish(); + this.applyPlugins("compile", params); - compilation.seal(function(err) { + const compilation = this.newCompilation(params); + + this.applyPluginsParallel("make", compilation, err => { if(err) return callback(err); - self.applyPluginsAsync("after-compile", compilation, function(err) { + compilation.finish(); + + compilation.seal(err => { if(err) return callback(err); - return callback(null, compilation); + this.applyPluginsAsync("after-compile", compilation, err => { + if(err) return callback(err); + + return callback(null, compilation); + }); }); }); }); - }); -}; + } +} + +Compiler.Watching = Watching; +module.exports = Compiler; diff --git a/node_modules/webpack/lib/ContextModule.js b/node_modules/webpack/lib/ContextModule.js index 9771fcd80..a894e6268 100644 --- a/node_modules/webpack/lib/ContextModule.js +++ b/node_modules/webpack/lib/ContextModule.js @@ -140,8 +140,13 @@ class ContextModule extends Module { this.addBlock(block); } - } else { + } else if(this.async === "weak" || this.async === "async-weak") { + + // we mark all dependencies as weak + dependencies.forEach(dep => dep.weak = true); + this.dependencies = dependencies; + } else { // if we are lazy create a new async dependency block per dependency // and add all blocks to this context dependencies.forEach((dep, idx) => { @@ -198,6 +203,58 @@ module.exports = webpackContext; webpackContext.id = ${JSON.stringify(id)};`; } + getWeakSyncSource(dependencies, id) { + const map = this.getUserRequestMap(dependencies); + return `var map = ${JSON.stringify(map, null, "\t")}; +function webpackContext(req) { + var id = webpackContextResolve(req); + if(!__webpack_require__.m[id]) + throw new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)"); + return __webpack_require__(id); +}; +function webpackContextResolve(req) { + var id = map[req]; + if(!(id + 1)) // check for number or string + throw new Error("Cannot find module '" + req + "'."); + return id; +}; +webpackContext.keys = function webpackContextKeys() { + return Object.keys(map); +}; +webpackContext.resolve = webpackContextResolve; +webpackContext.id = ${JSON.stringify(id)}; +module.exports = webpackContext;`; + } + + getAsyncWeakSource(dependencies, id) { + const map = this.getUserRequestMap(dependencies); + + return `var map = ${JSON.stringify(map, null, "\t")}; +function webpackAsyncContext(req) { + return webpackAsyncContextResolve(req).then(function(id) { + if(!__webpack_require__.m[id]) + throw new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)"); + return __webpack_require__(id); + }); +}; +function webpackAsyncContextResolve(req) { + // Here Promise.resolve().then() is used instead of new Promise() to prevent + // uncatched exception popping up in devtools + return Promise.resolve().then(function() { + var id = map[req]; + if(!(id + 1)) // check for number or string + throw new Error("Cannot find module '" + req + "'."); + return id; + }); +}; +webpackAsyncContext.keys = function webpackAsyncContextKeys() { + return Object.keys(map); +}; +webpackAsyncContext.resolve = webpackAsyncContextResolve; +webpackAsyncContext.id = ${JSON.stringify(id)}; +module.exports = webpackAsyncContext;`; + } + getEagerSource(dependencies, id) { const map = this.getUserRequestMap(dependencies); return `var map = ${JSON.stringify(map, null, "\t")}; @@ -205,20 +262,21 @@ function webpackAsyncContext(req) { return webpackAsyncContextResolve(req).then(__webpack_require__); }; function webpackAsyncContextResolve(req) { - return new Promise(function(resolve, reject) { + // Here Promise.resolve().then() is used instead of new Promise() to prevent + // uncatched exception popping up in devtools + return Promise.resolve().then(function() { var id = map[req]; if(!(id + 1)) // check for number or string - reject(new Error("Cannot find module '" + req + "'.")); - else - resolve(id); + throw new Error("Cannot find module '" + req + "'."); + return id; }); }; webpackAsyncContext.keys = function webpackAsyncContextKeys() { return Object.keys(map); }; webpackAsyncContext.resolve = webpackAsyncContextResolve; -module.exports = webpackAsyncContext; -webpackAsyncContext.id = ${JSON.stringify(id)};`; +webpackAsyncContext.id = ${JSON.stringify(id)}; +module.exports = webpackAsyncContext;`; } getLazyOnceSource(block, dependencies, id, outputOptions, requestShortener) { @@ -240,8 +298,8 @@ webpackAsyncContext.keys = function webpackAsyncContextKeys() { return Object.keys(map); }; webpackAsyncContext.resolve = webpackAsyncContextResolve; -module.exports = webpackAsyncContext; -webpackAsyncContext.id = ${JSON.stringify(id)};`; +webpackAsyncContext.id = ${JSON.stringify(id)}; +module.exports = webpackAsyncContext;`; } getLazySource(blocks, id) { @@ -282,8 +340,8 @@ function webpackAsyncContext(req) { webpackAsyncContext.keys = function webpackAsyncContextKeys() { return Object.keys(map); }; -module.exports = webpackAsyncContext; -webpackAsyncContext.id = ${JSON.stringify(id)};`; +webpackAsyncContext.id = ${JSON.stringify(id)}; +module.exports = webpackAsyncContext;`; } getSourceForEmptyContext(id) { @@ -298,7 +356,11 @@ webpackEmptyContext.id = ${JSON.stringify(id)};`; getSourceForEmptyAsyncContext(id) { return `function webpackEmptyAsyncContext(req) { - return new Promise(function(resolve, reject) { reject(new Error("Cannot find module '" + req + "'.")); }); + // Here Promise.resolve().then() is used instead of new Promise() to prevent + // uncatched exception popping up in devtools + return Promise.resolve().then(function() { + throw new Error("Cannot find module '" + req + "'."); + }); } webpackEmptyAsyncContext.keys = function() { return []; }; webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext; @@ -318,13 +380,25 @@ webpackEmptyAsyncContext.id = ${JSON.stringify(id)};`; return this.getEagerSource(this.dependencies, this.id); } return this.getSourceForEmptyAsyncContext(this.id); - } else if(asyncMode === "lazy-once") { + } + if(asyncMode === "lazy-once") { const block = this.blocks[0]; if(block) { return this.getLazyOnceSource(block, block.dependencies, this.id, outputOptions, requestShortener); } return this.getSourceForEmptyAsyncContext(this.id); } + if(asyncMode === "async-weak") { + if(this.dependencies && this.dependencies.length > 0) { + return this.getAsyncWeakSource(this.dependencies, this.id); + } + return this.getSourceForEmptyAsyncContext(this.id); + } + if(asyncMode === "weak") { + if(this.dependencies && this.dependencies.length > 0) { + return this.getWeakSyncSource(this.dependencies, this.id); + } + } if(this.dependencies && this.dependencies.length > 0) { return this.getSyncSource(this.dependencies, this.id); } diff --git a/node_modules/webpack/lib/ContextModuleFactory.js b/node_modules/webpack/lib/ContextModuleFactory.js index a2b666fad..a5947064b 100644 --- a/node_modules/webpack/lib/ContextModuleFactory.js +++ b/node_modules/webpack/lib/ContextModuleFactory.js @@ -2,158 +2,159 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -var asyncLib = require("async"); -var path = require("path"); - -var Tapable = require("tapable"); -var ContextModule = require("./ContextModule"); -var ContextElementDependency = require("./dependencies/ContextElementDependency"); - -function ContextModuleFactory(resolvers) { - Tapable.call(this); - this.resolvers = resolvers; -} -module.exports = ContextModuleFactory; - -ContextModuleFactory.prototype = Object.create(Tapable.prototype); -ContextModuleFactory.prototype.constructor = ContextModuleFactory; - -ContextModuleFactory.prototype.create = function(data, callback) { - var module = this; - var context = data.context; - var dependencies = data.dependencies; - var dependency = dependencies[0]; - this.applyPluginsAsyncWaterfall("before-resolve", { - context: context, - request: dependency.request, - recursive: dependency.recursive, - regExp: dependency.regExp, - async: dependency.async, - dependencies: dependencies - }, function(err, result) { - if(err) return callback(err); - - // Ignored - if(!result) return callback(); - - var context = result.context; - var request = result.request; - var recursive = result.recursive; - var regExp = result.regExp; - var asyncContext = result.async; - var dependencies = result.dependencies; - - var loaders, resource, loadersPrefix = ""; - var idx = request.lastIndexOf("!"); - if(idx >= 0) { - loaders = request.substr(0, idx + 1); - for(var i = 0; i < loaders.length && loaders[i] === "!"; i++) { - loadersPrefix += "!"; +"use strict"; + +const asyncLib = require("async"); +const path = require("path"); + +const Tapable = require("tapable"); +const ContextModule = require("./ContextModule"); +const ContextElementDependency = require("./dependencies/ContextElementDependency"); + +module.exports = class ContextModuleFactory extends Tapable { + constructor(resolvers) { + super(); + this.resolvers = resolvers; + } + + create(data, callback) { + const module = this; + const context = data.context; + const dependencies = data.dependencies; + const dependency = dependencies[0]; + this.applyPluginsAsyncWaterfall("before-resolve", { + context: context, + request: dependency.request, + recursive: dependency.recursive, + regExp: dependency.regExp, + async: dependency.async, + dependencies: dependencies + }, (err, result) => { + if(err) return callback(err); + + // Ignored + if(!result) return callback(); + + const context = result.context; + const request = result.request; + const recursive = result.recursive; + const regExp = result.regExp; + const asyncContext = result.async; + const dependencies = result.dependencies; + + let loaders, resource, loadersPrefix = ""; + const idx = request.lastIndexOf("!"); + if(idx >= 0) { + loaders = request.substr(0, idx + 1); + let i; + for(i = 0; i < loaders.length && loaders[i] === "!"; i++) { + loadersPrefix += "!"; + } + loaders = loaders.substr(i).replace(/!+$/, "").replace(/!!+/g, "!"); + if(loaders === "") loaders = []; + else loaders = loaders.split("!"); + resource = request.substr(idx + 1); + } else { + loaders = []; + resource = request; } - loaders = loaders.substr(i).replace(/!+$/, "").replace(/!!+/g, "!"); - if(loaders === "") loaders = []; - else loaders = loaders.split("!"); - resource = request.substr(idx + 1); - } else { - loaders = []; - resource = request; - } - - var resolvers = module.resolvers; - - asyncLib.parallel([ - function(callback) { - resolvers.context.resolve({}, context, resource, function(err, result) { - if(err) return callback(err); - callback(null, result); - }); - }, - function(callback) { - asyncLib.map(loaders, function(loader, callback) { - resolvers.loader.resolve({}, context, loader, function(err, result) { + + const resolvers = module.resolvers; + + asyncLib.parallel([ + function(callback) { + resolvers.context.resolve({}, context, resource, function(err, result) { if(err) return callback(err); callback(null, result); }); - }, callback); - } - ], function(err, result) { - if(err) return callback(err); - - module.applyPluginsAsyncWaterfall("after-resolve", { - loaders: loadersPrefix + result[1].join("!") + (result[1].length > 0 ? "!" : ""), - resource: result[0], - recursive: recursive, - regExp: regExp, - async: asyncContext, - dependencies: dependencies, - resolveDependencies: module.resolveDependencies.bind(module) - }, function(err, result) { + }, + function(callback) { + asyncLib.map(loaders, function(loader, callback) { + resolvers.loader.resolve({}, context, loader, function(err, result) { + if(err) return callback(err); + callback(null, result); + }); + }, callback); + } + ], (err, result) => { if(err) return callback(err); - // Ignored - if(!result) return callback(); + module.applyPluginsAsyncWaterfall("after-resolve", { + loaders: loadersPrefix + result[1].join("!") + (result[1].length > 0 ? "!" : ""), + resource: result[0], + recursive: recursive, + regExp: regExp, + async: asyncContext, + dependencies: dependencies, + resolveDependencies: module.resolveDependencies.bind(module) + }, function(err, result) { + if(err) return callback(err); + + // Ignored + if(!result) return callback(); - return callback(null, new ContextModule(result.resolveDependencies, result.resource, result.recursive, result.regExp, result.loaders, result.async, dependency.chunkName)); + return callback(null, new ContextModule(result.resolveDependencies, result.resource, result.recursive, result.regExp, result.loaders, result.async, dependency.chunkName)); + }); }); }); - }); -}; + } -ContextModuleFactory.prototype.resolveDependencies = function resolveDependencies(fs, resource, recursive, regExp, callback) { - if(!regExp || !resource) - return callback(null, []); - (function addDirectory(directory, callback) { - fs.readdir(directory, function(err, files) { - if(err) return callback(err); - if(!files || files.length === 0) return callback(null, []); - asyncLib.map(files.filter(function(p) { - return p.indexOf(".") !== 0; - }), function(seqment, callback) { + resolveDependencies(fs, resource, recursive, regExp, callback) { + if(!regExp || !resource) + return callback(null, []); + (function addDirectory(directory, callback) { + fs.readdir(directory, (err, files) => { + if(err) return callback(err); + if(!files || files.length === 0) return callback(null, []); + asyncLib.map(files.filter(function(p) { + return p.indexOf(".") !== 0; + }), (seqment, callback) => { - var subResource = path.join(directory, seqment); + const subResource = path.join(directory, seqment); - fs.stat(subResource, function(err, stat) { - if(err) return callback(err); + fs.stat(subResource, (err, stat) => { + if(err) return callback(err); - if(stat.isDirectory()) { + if(stat.isDirectory()) { - if(!recursive) return callback(); - addDirectory.call(this, subResource, callback); + if(!recursive) return callback(); + addDirectory.call(this, subResource, callback); - } else if(stat.isFile()) { + } else if(stat.isFile()) { - var obj = { - context: resource, - request: "." + subResource.substr(resource.length).replace(/\\/g, "/") - }; + const obj = { + context: resource, + request: "." + subResource.substr(resource.length).replace(/\\/g, "/") + }; - this.applyPluginsAsyncWaterfall("alternatives", [obj], function(err, alternatives) { - if(err) return callback(err); - alternatives = alternatives.filter(function(obj) { - return regExp.test(obj.request); - }).map(function(obj) { - var dep = new ContextElementDependency(obj.request); - dep.optional = true; - return dep; + this.applyPluginsAsyncWaterfall("alternatives", [obj], (err, alternatives) => { + if(err) return callback(err); + alternatives = alternatives.filter(function(obj) { + return regExp.test(obj.request); + }).map(function(obj) { + const dep = new ContextElementDependency(obj.request); + dep.optional = true; + return dep; + }); + callback(null, alternatives); }); - callback(null, alternatives); - }); - } else callback(); + } else callback(); - }.bind(this)); + }); - }.bind(this), function(err, result) { - if(err) return callback(err); + }, (err, result) => { + if(err) return callback(err); - if(!result) return callback(null, []); + if(!result) return callback(null, []); - callback(null, result.filter(function(i) { - return !!i; - }).reduce(function(a, i) { - return a.concat(i); - }, [])); + callback(null, result.filter(function(i) { + return !!i; + }).reduce(function(a, i) { + return a.concat(i); + }, [])); + }); }); - }.bind(this)); - }.call(this, resource, callback)); + }.call(this, resource, callback)); + } }; diff --git a/node_modules/webpack/lib/DefinePlugin.js b/node_modules/webpack/lib/DefinePlugin.js index 52bbdfe31..6318124f5 100644 --- a/node_modules/webpack/lib/DefinePlugin.js +++ b/node_modules/webpack/lib/DefinePlugin.js @@ -35,7 +35,7 @@ class DefinePlugin { }(definitions, "")); function stringifyObj(obj) { - return "__webpack_require__.i({" + Object.keys(obj).map((key) => { + return "Object({" + Object.keys(obj).map((key) => { const code = obj[key]; return JSON.stringify(key) + ":" + toCode(code); }).join(",") + "})"; @@ -111,7 +111,7 @@ class DefinePlugin { function applyObjectDefine(key, obj) { const code = stringifyObj(obj); parser.plugin("can-rename " + key, ParserHelpers.approve); - parser.plugin("evaluate Identifier " + key, (expr) => new BasicEvaluatedExpression().setRange(expr.range)); + parser.plugin("evaluate Identifier " + key, (expr) => new BasicEvaluatedExpression().setTruthy().setRange(expr.range)); parser.plugin("evaluate typeof " + key, ParserHelpers.evaluateToString("object")); parser.plugin("expression " + key, ParserHelpers.toConstantDependency(code)); parser.plugin("typeof " + key, ParserHelpers.toConstantDependency(JSON.stringify("object"))); diff --git a/node_modules/webpack/lib/DelegatedModule.js b/node_modules/webpack/lib/DelegatedModule.js index d06e82214..cd80a21ff 100644 --- a/node_modules/webpack/lib/DelegatedModule.js +++ b/node_modules/webpack/lib/DelegatedModule.js @@ -9,20 +9,26 @@ const OriginalSource = require("webpack-sources").OriginalSource; const RawSource = require("webpack-sources").RawSource; const WebpackMissingModule = require("./dependencies/WebpackMissingModule"); const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency"); +const DelegatedExportsDependency = require("./dependencies/DelegatedExportsDependency"); class DelegatedModule extends Module { - constructor(sourceRequest, data, type, userRequest) { + constructor(sourceRequest, data, type, userRequest, originalRequest) { super(); this.sourceRequest = sourceRequest; this.request = data.id; this.meta = data.meta; this.type = type; + this.originalRequest = originalRequest; this.userRequest = userRequest; this.built = false; this.delegated = true; this.delegateData = data; } + libIdent(options) { + return typeof this.originalRequest === "string" ? this.originalRequest : this.originalRequest.libIdent(options); + } + identifier() { return `delegated ${JSON.stringify(this.request)} from ${this.sourceRequest}`; } @@ -38,10 +44,10 @@ class DelegatedModule extends Module { build(options, compilation, resolver, fs, callback) { this.built = true; this.builtTime = Date.now(); - this.usedExports = true; - this.providedExports = this.delegateData.exports || true; + this.cacheable = true; this.dependencies.length = 0; this.addDependency(new DelegatedSourceDependency(this.sourceRequest)); + this.addDependency(new DelegatedExportsDependency(this, this.delegateData.exports || true)); callback(); } @@ -57,7 +63,7 @@ class DelegatedModule extends Module { if(!sourceModule) { str = WebpackMissingModule.moduleCode(this.sourceRequest); } else { - str = `module.exports = (__webpack_require__(${sourceModule.id}))`; + str = `module.exports = (__webpack_require__(${JSON.stringify(sourceModule.id)}))`; switch(this.type) { case "require": diff --git a/node_modules/webpack/lib/DelegatedModuleFactoryPlugin.js b/node_modules/webpack/lib/DelegatedModuleFactoryPlugin.js index 501125bd0..f26dfca94 100644 --- a/node_modules/webpack/lib/DelegatedModuleFactoryPlugin.js +++ b/node_modules/webpack/lib/DelegatedModuleFactoryPlugin.js @@ -29,13 +29,14 @@ class DelegatedModuleFactoryPlugin { let resolved; if(innerRequest in this.options.content) { resolved = this.options.content[innerRequest]; - return callback(null, new DelegatedModule(this.options.source, resolved, this.options.type, innerRequest)); + return callback(null, new DelegatedModule(this.options.source, resolved, this.options.type, innerRequest, request)); } for(let i = 0; i < this.options.extensions.length; i++) { - const requestPlusExt = innerRequest + this.options.extensions[i]; + const extension = this.options.extensions[i]; + const requestPlusExt = innerRequest + extension; if(requestPlusExt in this.options.content) { resolved = this.options.content[requestPlusExt]; - return callback(null, new DelegatedModule(this.options.source, resolved, this.options.type, requestPlusExt)); + return callback(null, new DelegatedModule(this.options.source, resolved, this.options.type, requestPlusExt, request + extension)); } } } @@ -47,7 +48,7 @@ class DelegatedModuleFactoryPlugin { const request = module.libIdent(this.options); if(request && request in this.options.content) { const resolved = this.options.content[request]; - return new DelegatedModule(this.options.source, resolved, this.options.type, request); + return new DelegatedModule(this.options.source, resolved, this.options.type, request, module); } } return module; diff --git a/node_modules/webpack/lib/DelegatedPlugin.js b/node_modules/webpack/lib/DelegatedPlugin.js index 709ede204..67894d9bd 100644 --- a/node_modules/webpack/lib/DelegatedPlugin.js +++ b/node_modules/webpack/lib/DelegatedPlugin.js @@ -7,6 +7,8 @@ const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin"); const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency"); +const DelegatedExportsDependency = require("./dependencies/DelegatedExportsDependency"); +const NullFactory = require("./NullFactory"); class DelegatedPlugin { constructor(options) { @@ -16,6 +18,7 @@ class DelegatedPlugin { apply(compiler) { compiler.plugin("compilation", (compilation, params) => { compilation.dependencyFactories.set(DelegatedSourceDependency, params.normalModuleFactory); + compilation.dependencyFactories.set(DelegatedExportsDependency, new NullFactory()); }); compiler.plugin("compile", (params) => { diff --git a/node_modules/webpack/lib/DllReferencePlugin.js b/node_modules/webpack/lib/DllReferencePlugin.js index 39289db61..cd2ef28a6 100644 --- a/node_modules/webpack/lib/DllReferencePlugin.js +++ b/node_modules/webpack/lib/DllReferencePlugin.js @@ -7,6 +7,8 @@ const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency"); const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin"); const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin"); +const DelegatedExportsDependency = require("./dependencies/DelegatedExportsDependency"); +const NullFactory = require("./NullFactory"); class DllReferencePlugin { constructor(options) { @@ -17,6 +19,7 @@ class DllReferencePlugin { compiler.plugin("compilation", (compilation, params) => { const normalModuleFactory = params.normalModuleFactory; compilation.dependencyFactories.set(DelegatedSourceDependency, normalModuleFactory); + compilation.dependencyFactories.set(DelegatedExportsDependency, new NullFactory()); }); compiler.plugin("before-compile", (params, callback) => { diff --git a/node_modules/webpack/lib/EntryOptionPlugin.js b/node_modules/webpack/lib/EntryOptionPlugin.js index 49b1c798a..03692edd4 100644 --- a/node_modules/webpack/lib/EntryOptionPlugin.js +++ b/node_modules/webpack/lib/EntryOptionPlugin.js @@ -1,27 +1,27 @@ /* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra - */ +*/ "use strict"; const SingleEntryPlugin = require("./SingleEntryPlugin"); const MultiEntryPlugin = require("./MultiEntryPlugin"); const DynamicEntryPlugin = require("./DynamicEntryPlugin"); +function itemToPlugin(context, item, name) { + if(Array.isArray(item)) { + return new MultiEntryPlugin(context, item, name); + } + return new SingleEntryPlugin(context, item, name); +} + module.exports = class EntryOptionPlugin { apply(compiler) { compiler.plugin("entry-option", (context, entry) => { - function itemToPlugin(item, name) { - if(Array.isArray(item)) { - return new MultiEntryPlugin(context, item, name); - } else { - return new SingleEntryPlugin(context, item, name); - } - } if(typeof entry === "string" || Array.isArray(entry)) { - compiler.apply(itemToPlugin(entry, "main")); + compiler.apply(itemToPlugin(context, entry, "main")); } else if(typeof entry === "object") { - Object.keys(entry).forEach(name => compiler.apply(itemToPlugin(entry[name], name))); + Object.keys(entry).forEach(name => compiler.apply(itemToPlugin(context, entry[name], name))); } else if(typeof entry === "function") { compiler.apply(new DynamicEntryPlugin(context, entry)); } diff --git a/node_modules/webpack/lib/EvalSourceMapDevToolModuleTemplatePlugin.js b/node_modules/webpack/lib/EvalSourceMapDevToolModuleTemplatePlugin.js index 31c44492a..85aece2f7 100644 --- a/node_modules/webpack/lib/EvalSourceMapDevToolModuleTemplatePlugin.js +++ b/node_modules/webpack/lib/EvalSourceMapDevToolModuleTemplatePlugin.js @@ -10,7 +10,7 @@ const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); class EvalSourceMapDevToolModuleTemplatePlugin { constructor(compilation, options) { this.compilation = compilation; - this.sourceMapComment = options.append || "//# sourceMappingURL=[url]"; + this.sourceMapComment = options.append || "//# sourceURL=[module]\n//# sourceMappingURL=[url]"; this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack:///[resource-path]?[hash]"; this.options = options; } @@ -61,13 +61,14 @@ class EvalSourceMapDevToolModuleTemplatePlugin { sourceMap.sourceRoot = options.sourceRoot || ""; sourceMap.file = `${module.id}.js`; - const footer = self.sourceMapComment.replace(/\[url\]/g, `data:application/json;charset=utf-8;base64,${new Buffer(JSON.stringify(sourceMap), "utf8").toString("base64")}`); //eslint-disable-line + const footer = self.sourceMapComment.replace(/\[url\]/g, `data:application/json;charset=utf-8;base64,${new Buffer(JSON.stringify(sourceMap), "utf8").toString("base64")}`) + //eslint-disable-line + `\n//# sourceURL=webpack-internal:///${module.id}\n`; // workaround for chrome bug source.__EvalSourceMapDevToolData = new RawSource(`eval(${JSON.stringify(content + footer)});`); return source.__EvalSourceMapDevToolData; }); moduleTemplate.plugin("hash", function(hash) { hash.update("eval-source-map"); - hash.update("1"); + hash.update("2"); }); } } diff --git a/node_modules/webpack/lib/ExportPropertyMainTemplatePlugin.js b/node_modules/webpack/lib/ExportPropertyMainTemplatePlugin.js new file mode 100644 index 000000000..8dd80901e --- /dev/null +++ b/node_modules/webpack/lib/ExportPropertyMainTemplatePlugin.js @@ -0,0 +1,31 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const ConcatSource = require("webpack-sources").ConcatSource; + +function accessorToObjectAccess(accessor) { + return accessor.map(a => `[${JSON.stringify(a)}]`).join(""); +} + +class ExportPropertyMainTemplatePlugin { + constructor(property) { + this.property = property; + } + + apply(compilation) { + const mainTemplate = compilation.mainTemplate; + compilation.templatesPlugin("render-with-entry", (source, chunk, hash) => { + const postfix = `${accessorToObjectAccess([].concat(this.property))}`; + return new ConcatSource(source, postfix); + }); + mainTemplate.plugin("hash", hash => { + hash.update("export property"); + hash.update(`${this.property}`); + }); + } +} + +module.exports = ExportPropertyMainTemplatePlugin; diff --git a/node_modules/webpack/lib/ExternalModule.js b/node_modules/webpack/lib/ExternalModule.js index 340d6b61e..2a8137ebc 100644 --- a/node_modules/webpack/lib/ExternalModule.js +++ b/node_modules/webpack/lib/ExternalModule.js @@ -10,14 +10,19 @@ const WebpackMissingModule = require("./dependencies/WebpackMissingModule"); const Template = require("./Template"); class ExternalModule extends Module { - constructor(request, type) { + constructor(request, type, userRequest) { super(); this.request = request; + this.userRequest = userRequest; this.type = type; this.built = false; this.external = true; } + libIdent() { + return this.userRequest; + } + chunkCondition(chunk) { return chunk.hasEntryModule(); } diff --git a/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js b/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js index 54cf0a28b..7066aae42 100644 --- a/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js +++ b/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js @@ -30,7 +30,7 @@ class ExternalModuleFactoryPlugin { type = value.substr(0, idx); value = value.substr(idx + 1); } - callback(null, new ExternalModule(value, type || globalType)); + callback(null, new ExternalModule(value, type || globalType, dependency.request)); return true; } (function handleExternals(externals, callback) { diff --git a/node_modules/webpack/lib/FlagDependencyExportsPlugin.js b/node_modules/webpack/lib/FlagDependencyExportsPlugin.js index 581c30fa0..ff5e11255 100644 --- a/node_modules/webpack/lib/FlagDependencyExportsPlugin.js +++ b/node_modules/webpack/lib/FlagDependencyExportsPlugin.js @@ -19,7 +19,7 @@ class FlagDependencyExportsPlugin { module = queue[i]; if(module.providedExports !== true) { - moduleWithExports = false; + moduleWithExports = module.meta && module.meta.harmonyModule; moduleProvidedExports = Array.isArray(module.providedExports) ? new Set(module.providedExports) : new Set(); processDependenciesBlock(module); if(!moduleWithExports) { diff --git a/node_modules/webpack/lib/FlagInitialModulesAsUsedPlugin.js b/node_modules/webpack/lib/FlagInitialModulesAsUsedPlugin.js index 8f68805ed..0356006ab 100644 --- a/node_modules/webpack/lib/FlagInitialModulesAsUsedPlugin.js +++ b/node_modules/webpack/lib/FlagInitialModulesAsUsedPlugin.js @@ -12,7 +12,7 @@ class FlagInitialModulesAsUsedPlugin { if(!chunk.isInitial()) { return; } - chunk.modules.forEach((module) => { + chunk.forEachModule((module) => { module.usedExports = true; }); }); diff --git a/node_modules/webpack/lib/FunctionModuleTemplatePlugin.js b/node_modules/webpack/lib/FunctionModuleTemplatePlugin.js index dd20b7867..72e214808 100644 --- a/node_modules/webpack/lib/FunctionModuleTemplatePlugin.js +++ b/node_modules/webpack/lib/FunctionModuleTemplatePlugin.js @@ -25,17 +25,23 @@ class FunctionModuleTemplatePlugin { if(this.outputOptions.pathinfo) { const source = new ConcatSource(); const req = module.readableIdentifier(this.requestShortener); + source.add("/*!****" + req.replace(/./g, "*") + "****!*\\\n"); + source.add(" !*** " + req.replace(/\*\//g, "*_/") + " ***!\n"); + source.add(" \\****" + req.replace(/./g, "*") + "****/\n"); if(Array.isArray(module.providedExports)) - source.add("/* exports provided: " + module.providedExports.join(", ") + " */\n"); + source.add("/*! exports provided: " + module.providedExports.join(", ") + " */\n"); else if(module.providedExports) - source.add("/* unknown exports provided */\n"); + source.add("/*! no static exports found */\n"); if(Array.isArray(module.usedExports)) - source.add("/* exports used: " + module.usedExports.join(", ") + " */\n"); + source.add("/*! exports used: " + module.usedExports.join(", ") + " */\n"); else if(module.usedExports) - source.add("/* all exports used */\n"); - source.add("/*!****" + req.replace(/./g, "*") + "****!*\\\n"); - source.add(" !*** " + req.replace(/\*\//g, "*_/") + " ***!\n"); - source.add(" \\****" + req.replace(/./g, "*") + "****/\n"); + source.add("/*! all exports used */\n"); + if(module.optimizationBailout) { + module.optimizationBailout.forEach(text => { + if(typeof text === "function") text = text(this.requestShortener); + source.add(`/*! ${text} */\n`); + }); + } source.add(moduleSource); return source; } diff --git a/node_modules/webpack/lib/HotModuleReplacement.runtime.js b/node_modules/webpack/lib/HotModuleReplacement.runtime.js index 7df072ea8..f537bfdd7 100644 --- a/node_modules/webpack/lib/HotModuleReplacement.runtime.js +++ b/node_modules/webpack/lib/HotModuleReplacement.runtime.js @@ -2,11 +2,12 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -/*global $hash$ installedModules $require$ hotDownloadManifest hotDownloadUpdateChunk hotDisposeChunk modules */ +/*global $hash$ $requestTimeout$ installedModules $require$ hotDownloadManifest hotDownloadUpdateChunk hotDisposeChunk modules */ module.exports = function() { var hotApplyOnUpdate = true; var hotCurrentHash = $hash$; // eslint-disable-line no-unused-vars + var hotRequestTimeout = $requestTimeout$; var hotCurrentModuleData = {}; var hotCurrentChildModule; // eslint-disable-line no-unused-vars var hotCurrentParents = []; // eslint-disable-line no-unused-vars @@ -167,7 +168,7 @@ module.exports = function() { if(hotStatus !== "idle") throw new Error("check() is only allowed in idle status"); hotApplyOnUpdate = apply; hotSetStatus("check"); - return hotDownloadManifest().then(function(update) { + return hotDownloadManifest(hotRequestTimeout).then(function(update) { if(!update) { hotSetStatus("idle"); return null; @@ -227,11 +228,19 @@ module.exports = function() { hotDeferred = null; if(!deferred) return; if(hotApplyOnUpdate) { - hotApply(hotApplyOnUpdate).then(function(result) { - deferred.resolve(result); - }, function(err) { - deferred.reject(err); - }); + // Wrap deferred object in Promise to mark it as a well-handled Promise to + // avoid triggering uncaught exception warning in Chrome. + // See https://bugs.chromium.org/p/chromium/issues/detail?id=465666 + Promise.resolve().then(function() { + return hotApply(hotApplyOnUpdate); + }).then( + function(result) { + deferred.resolve(result); + }, + function(err) { + deferred.reject(err); + } + ); } else { var outdatedModules = []; for(var id in hotUpdate) { @@ -453,6 +462,9 @@ module.exports = function() { // remove module from cache delete installedModules[moduleId]; + // when disposing there is no need to call dispose handler + delete outdatedDependencies[moduleId]; + // remove "parents" references from all children for(j = 0; j < module.children.length; j++) { var child = installedModules[module.children[j]]; @@ -498,30 +510,34 @@ module.exports = function() { for(moduleId in outdatedDependencies) { if(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) { module = installedModules[moduleId]; - moduleOutdatedDependencies = outdatedDependencies[moduleId]; - var callbacks = []; - for(i = 0; i < moduleOutdatedDependencies.length; i++) { - dependency = moduleOutdatedDependencies[i]; - cb = module.hot._acceptedDependencies[dependency]; - if(callbacks.indexOf(cb) >= 0) continue; - callbacks.push(cb); - } - for(i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - try { - cb(moduleOutdatedDependencies); - } catch(err) { - if(options.onErrored) { - options.onErrored({ - type: "accept-errored", - moduleId: moduleId, - dependencyId: moduleOutdatedDependencies[i], - error: err - }); + if(module) { + moduleOutdatedDependencies = outdatedDependencies[moduleId]; + var callbacks = []; + for(i = 0; i < moduleOutdatedDependencies.length; i++) { + dependency = moduleOutdatedDependencies[i]; + cb = module.hot._acceptedDependencies[dependency]; + if(cb) { + if(callbacks.indexOf(cb) >= 0) continue; + callbacks.push(cb); } - if(!options.ignoreErrored) { - if(!error) - error = err; + } + for(i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + try { + cb(moduleOutdatedDependencies); + } catch(err) { + if(options.onErrored) { + options.onErrored({ + type: "accept-errored", + moduleId: moduleId, + dependencyId: moduleOutdatedDependencies[i], + error: err + }); + } + if(!options.ignoreErrored) { + if(!error) + error = err; + } } } } diff --git a/node_modules/webpack/lib/HotModuleReplacementPlugin.js b/node_modules/webpack/lib/HotModuleReplacementPlugin.js index 640e05e9d..b6dbdd7f7 100644 --- a/node_modules/webpack/lib/HotModuleReplacementPlugin.js +++ b/node_modules/webpack/lib/HotModuleReplacementPlugin.js @@ -3,257 +3,249 @@ Author Tobias Koppers @sokra */ "use strict"; -var Template = require("./Template"); -var ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency"); -var ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency"); -var RawSource = require("webpack-sources").RawSource; -var ConstDependency = require("./dependencies/ConstDependency"); -var NullFactory = require("./NullFactory"); +const Template = require("./Template"); +const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency"); +const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency"); +const RawSource = require("webpack-sources").RawSource; +const ConstDependency = require("./dependencies/ConstDependency"); +const NullFactory = require("./NullFactory"); const ParserHelpers = require("./ParserHelpers"); -function HotModuleReplacementPlugin(options) { - options = options || {}; - this.multiStep = options.multiStep; - this.fullBuildTimeout = options.fullBuildTimeout || 200; -} -module.exports = HotModuleReplacementPlugin; - -HotModuleReplacementPlugin.prototype.apply = function(compiler) { - var multiStep = this.multiStep; - var fullBuildTimeout = this.fullBuildTimeout; - var hotUpdateChunkFilename = compiler.options.output.hotUpdateChunkFilename; - var hotUpdateMainFilename = compiler.options.output.hotUpdateMainFilename; - compiler.plugin("compilation", function(compilation, params) { - var hotUpdateChunkTemplate = compilation.hotUpdateChunkTemplate; - if(!hotUpdateChunkTemplate) return; - - var normalModuleFactory = params.normalModuleFactory; - - compilation.dependencyFactories.set(ConstDependency, new NullFactory()); - compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()); - - compilation.dependencyFactories.set(ModuleHotAcceptDependency, normalModuleFactory); - compilation.dependencyTemplates.set(ModuleHotAcceptDependency, new ModuleHotAcceptDependency.Template()); - - compilation.dependencyFactories.set(ModuleHotDeclineDependency, normalModuleFactory); - compilation.dependencyTemplates.set(ModuleHotDeclineDependency, new ModuleHotDeclineDependency.Template()); - - compilation.plugin("record", function(compilation, records) { - if(records.hash === this.hash) return; - records.hash = compilation.hash; - records.moduleHashs = {}; - this.modules.forEach(function(module) { - var identifier = module.identifier(); - var hash = require("crypto").createHash("md5"); - module.updateHash(hash); - records.moduleHashs[identifier] = hash.digest("hex"); +module.exports = class HotModuleReplacementPlugin { + constructor(options) { + this.options = options || {}; + this.multiStep = this.options.multiStep; + this.fullBuildTimeout = this.options.fullBuildTimeout || 200; + this.requestTimeout = this.options.requestTimeout || 10000; + } + + apply(compiler) { + const multiStep = this.multiStep; + const fullBuildTimeout = this.fullBuildTimeout; + const requestTimeout = this.requestTimeout; + const hotUpdateChunkFilename = compiler.options.output.hotUpdateChunkFilename; + const hotUpdateMainFilename = compiler.options.output.hotUpdateMainFilename; + compiler.plugin("compilation", (compilation, params) => { + const hotUpdateChunkTemplate = compilation.hotUpdateChunkTemplate; + if(!hotUpdateChunkTemplate) return; + + const normalModuleFactory = params.normalModuleFactory; + + compilation.dependencyFactories.set(ConstDependency, new NullFactory()); + compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()); + + compilation.dependencyFactories.set(ModuleHotAcceptDependency, normalModuleFactory); + compilation.dependencyTemplates.set(ModuleHotAcceptDependency, new ModuleHotAcceptDependency.Template()); + + compilation.dependencyFactories.set(ModuleHotDeclineDependency, normalModuleFactory); + compilation.dependencyTemplates.set(ModuleHotDeclineDependency, new ModuleHotDeclineDependency.Template()); + + compilation.plugin("record", function(compilation, records) { + if(records.hash === this.hash) return; + records.hash = compilation.hash; + records.moduleHashs = {}; + this.modules.forEach(module => { + const identifier = module.identifier(); + const hash = require("crypto").createHash("md5"); + module.updateHash(hash); + records.moduleHashs[identifier] = hash.digest("hex"); + }); + records.chunkHashs = {}; + this.chunks.forEach(chunk => { + records.chunkHashs[chunk.id] = chunk.hash; + }); + records.chunkModuleIds = {}; + this.chunks.forEach(chunk => { + records.chunkModuleIds[chunk.id] = chunk.mapModules(m => m.id); + }); + }); + let initialPass = false; + let recompilation = false; + compilation.plugin("after-hash", function() { + let records = this.records; + if(!records) { + initialPass = true; + return; + } + if(!records.hash) + initialPass = true; + const preHash = records.preHash || "x"; + const prepreHash = records.prepreHash || "x"; + if(preHash === this.hash) { + recompilation = true; + this.modifyHash(prepreHash); + return; + } + records.prepreHash = records.hash || "x"; + records.preHash = this.hash; + this.modifyHash(records.prepreHash); }); - records.chunkHashs = {}; - this.chunks.forEach(function(chunk) { - records.chunkHashs[chunk.id] = chunk.hash; + compilation.plugin("should-generate-chunk-assets", () => { + if(multiStep && !recompilation && !initialPass) + return false; }); - records.chunkModuleIds = {}; - this.chunks.forEach(function(chunk) { - records.chunkModuleIds[chunk.id] = chunk.modules.map(function(m) { - return m.id; - }); + compilation.plugin("need-additional-pass", () => { + if(multiStep && !recompilation && !initialPass) + return true; }); - }); - var initialPass = false; - var recompilation = false; - compilation.plugin("after-hash", function() { - var records = this.records; - if(!records) { - initialPass = true; - return; - } - if(!records.hash) - initialPass = true; - var preHash = records.preHash || "x"; - var prepreHash = records.prepreHash || "x"; - if(preHash === this.hash) { - recompilation = true; - this.modifyHash(prepreHash); - return; - } - records.prepreHash = records.hash || "x"; - records.preHash = this.hash; - this.modifyHash(records.prepreHash); - }); - compilation.plugin("should-generate-chunk-assets", function() { - if(multiStep && !recompilation && !initialPass) - return false; - }); - compilation.plugin("need-additional-pass", function() { - if(multiStep && !recompilation && !initialPass) - return true; - }); - compiler.plugin("additional-pass", function(callback) { - if(multiStep) - return setTimeout(callback, fullBuildTimeout); - return callback(); - }); - compilation.plugin("additional-chunk-assets", function() { - var records = this.records; - if(records.hash === this.hash) return; - if(!records.moduleHashs || !records.chunkHashs || !records.chunkModuleIds) return; - this.modules.forEach(function(module) { - var identifier = module.identifier(); - var hash = require("crypto").createHash("md5"); - module.updateHash(hash); - hash = hash.digest("hex"); - module.hotUpdate = records.moduleHashs[identifier] !== hash; + compiler.plugin("additional-pass", callback => { + if(multiStep) + return setTimeout(callback, fullBuildTimeout); + return callback(); }); - var hotUpdateMainContent = { - h: this.hash, - c: {} - }; - Object.keys(records.chunkHashs).forEach(function(chunkId) { - chunkId = isNaN(+chunkId) ? chunkId : +chunkId; - var currentChunk = this.chunks.find(chunk => chunk.id === chunkId); - if(currentChunk) { - var newModules = currentChunk.modules.filter(function(module) { - return module.hotUpdate; - }); - var allModules = {}; - currentChunk.modules.forEach(function(module) { - allModules[module.id] = true; - }); - var removedModules = records.chunkModuleIds[chunkId].filter(function(id) { - return !allModules[id]; - }); - if(newModules.length > 0 || removedModules.length > 0) { - var source = hotUpdateChunkTemplate.render(chunkId, newModules, removedModules, this.hash, this.moduleTemplate, this.dependencyTemplates); - var filename = this.getPath(hotUpdateChunkFilename, { - hash: records.hash, - chunk: currentChunk + compilation.plugin("additional-chunk-assets", function() { + const records = this.records; + if(records.hash === this.hash) return; + if(!records.moduleHashs || !records.chunkHashs || !records.chunkModuleIds) return; + this.modules.forEach(module => { + const identifier = module.identifier(); + let hash = require("crypto").createHash("md5"); + module.updateHash(hash); + hash = hash.digest("hex"); + module.hotUpdate = records.moduleHashs[identifier] !== hash; + }); + const hotUpdateMainContent = { + h: this.hash, + c: {}, + }; + Object.keys(records.chunkHashs).forEach(function(chunkId) { + chunkId = isNaN(+chunkId) ? chunkId : +chunkId; + const currentChunk = this.chunks.find(chunk => chunk.id === chunkId); + if(currentChunk) { + const newModules = currentChunk.getModules().filter(module => module.hotUpdate); + const allModules = {}; + currentChunk.forEachModule(module => { + allModules[module.id] = true; }); - this.additionalChunkAssets.push(filename); - this.assets[filename] = source; - hotUpdateMainContent.c[chunkId] = true; - currentChunk.files.push(filename); - this.applyPlugins("chunk-asset", currentChunk, filename); + const removedModules = records.chunkModuleIds[chunkId].filter(id => !allModules[id]); + if(newModules.length > 0 || removedModules.length > 0) { + const source = hotUpdateChunkTemplate.render(chunkId, newModules, removedModules, this.hash, this.moduleTemplate, this.dependencyTemplates); + const filename = this.getPath(hotUpdateChunkFilename, { + hash: records.hash, + chunk: currentChunk + }); + this.additionalChunkAssets.push(filename); + this.assets[filename] = source; + hotUpdateMainContent.c[chunkId] = true; + currentChunk.files.push(filename); + this.applyPlugins("chunk-asset", currentChunk, filename); + } + } else { + hotUpdateMainContent.c[chunkId] = false; } - } else { - hotUpdateMainContent.c[chunkId] = false; - } - }, this); - var source = new RawSource(JSON.stringify(hotUpdateMainContent)); - var filename = this.getPath(hotUpdateMainFilename, { - hash: records.hash + }, this); + const source = new RawSource(JSON.stringify(hotUpdateMainContent)); + const filename = this.getPath(hotUpdateMainFilename, { + hash: records.hash + }); + this.assets[filename] = source; }); - this.assets[filename] = source; - }); - compilation.mainTemplate.plugin("hash", function(hash) { - hash.update("HotMainTemplateDecorator"); - }); - - compilation.mainTemplate.plugin("module-require", function(_, chunk, hash, varModuleId) { - return "hotCreateRequire(" + varModuleId + ")"; - }); + compilation.mainTemplate.plugin("hash", hash => { + hash.update("HotMainTemplateDecorator"); + }); - compilation.mainTemplate.plugin("require-extensions", function(source) { - var buf = [source]; - buf.push(""); - buf.push("// __webpack_hash__"); - buf.push(this.requireFn + ".h = function() { return hotCurrentHash; };"); - return this.asString(buf); - }); + compilation.mainTemplate.plugin("module-require", (_, chunk, hash, varModuleId) => { + return `hotCreateRequire(${varModuleId})`; + }); - compilation.mainTemplate.plugin("bootstrap", function(source, chunk, hash) { - source = this.applyPluginsWaterfall("hot-bootstrap", source, chunk, hash); - return this.asString([ - source, - "", - hotInitCode - .replace(/\$require\$/g, this.requireFn) - .replace(/\$hash\$/g, JSON.stringify(hash)) - .replace(/\/\*foreachInstalledChunks\*\//g, chunk.chunks.length > 0 ? "for(var chunkId in installedChunks)" : "var chunkId = " + JSON.stringify(chunk.id) + ";") - ]); - }); + compilation.mainTemplate.plugin("require-extensions", function(source) { + const buf = [source]; + buf.push(""); + buf.push("// __webpack_hash__"); + buf.push(this.requireFn + ".h = function() { return hotCurrentHash; };"); + return this.asString(buf); + }); - compilation.mainTemplate.plugin("global-hash", function() { - return true; - }); + compilation.mainTemplate.plugin("bootstrap", function(source, chunk, hash) { + source = this.applyPluginsWaterfall("hot-bootstrap", source, chunk, hash); + return this.asString([ + source, + "", + hotInitCode + .replace(/\$require\$/g, this.requireFn) + .replace(/\$hash\$/g, JSON.stringify(hash)) + .replace(/\$requestTimeout\$/g, requestTimeout) + .replace(/\/\*foreachInstalledChunks\*\//g, chunk.chunks.length > 0 ? "for(var chunkId in installedChunks)" : `var chunkId = ${JSON.stringify(chunk.id)};`) + ]); + }); - compilation.mainTemplate.plugin("current-hash", function(_, length) { - if(isFinite(length)) - return "hotCurrentHash.substr(0, " + length + ")"; - else - return "hotCurrentHash"; - }); + compilation.mainTemplate.plugin("global-hash", () => true); - compilation.mainTemplate.plugin("module-obj", function(source, chunk, hash, varModuleId) { - return this.asString([ - source + ",", - "hot: hotCreateModule(" + varModuleId + "),", - "parents: (hotCurrentParentsTemp = hotCurrentParents, hotCurrentParents = [], hotCurrentParentsTemp),", - "children: []" - ]); - }); + compilation.mainTemplate.plugin("current-hash", (_, length) => { + if(isFinite(length)) + return `hotCurrentHash.substr(0, ${length})`; + else + return "hotCurrentHash"; + }); - params.normalModuleFactory.plugin("parser", function(parser, parserOptions) { - parser.plugin("expression __webpack_hash__", ParserHelpers.toConstantDependency("__webpack_require__.h()")); - parser.plugin("evaluate typeof __webpack_hash__", ParserHelpers.evaluateToString("string")); - parser.plugin("evaluate Identifier module.hot", function(expr) { - return ParserHelpers.evaluateToBoolean(!!this.state.compilation.hotUpdateChunkTemplate)(expr); + compilation.mainTemplate.plugin("module-obj", function(source, chunk, hash, varModuleId) { + return this.asString([ + `${source},`, + `hot: hotCreateModule(${varModuleId}),`, + "parents: (hotCurrentParentsTemp = hotCurrentParents, hotCurrentParents = [], hotCurrentParentsTemp),", + "children: []" + ]); }); - parser.plugin("call module.hot.accept", function(expr) { - if(!this.state.compilation.hotUpdateChunkTemplate) return false; - if(expr.arguments.length >= 1) { - var arg = this.evaluateExpression(expr.arguments[0]); - var params = [], - requests = []; - if(arg.isString()) { - params = [arg]; - } else if(arg.isArray()) { - params = arg.items.filter(function(param) { - return param.isString(); - }); + + params.normalModuleFactory.plugin("parser", (parser, parserOptions) => { + parser.plugin("expression __webpack_hash__", ParserHelpers.toConstantDependency("__webpack_require__.h()")); + parser.plugin("evaluate typeof __webpack_hash__", ParserHelpers.evaluateToString("string")); + parser.plugin("evaluate Identifier module.hot", function(expr) { + return ParserHelpers.evaluateToIdentifier("module.hot", !!this.state.compilation.hotUpdateChunkTemplate)(expr); + }); + parser.plugin("call module.hot.accept", function(expr) { + if(!this.state.compilation.hotUpdateChunkTemplate) return false; + if(expr.arguments.length >= 1) { + const arg = this.evaluateExpression(expr.arguments[0]); + let params = []; + let requests = []; + if(arg.isString()) { + params = [arg]; + } else if(arg.isArray()) { + params = arg.items.filter(param => param.isString()); + } + if(params.length > 0) { + params.forEach((param, idx) => { + const request = param.string; + const dep = new ModuleHotAcceptDependency(request, param.range); + dep.optional = true; + dep.loc = Object.create(expr.loc); + dep.loc.index = idx; + this.state.module.addDependency(dep); + requests.push(request); + }); + if(expr.arguments.length > 1) + this.applyPluginsBailResult("hot accept callback", expr.arguments[1], requests); + else + this.applyPluginsBailResult("hot accept without callback", expr, requests); + } } - if(params.length > 0) { - params.forEach(function(param, idx) { - var request = param.string; - var dep = new ModuleHotAcceptDependency(request, param.range); + }); + parser.plugin("call module.hot.decline", function(expr) { + if(!this.state.compilation.hotUpdateChunkTemplate) return false; + if(expr.arguments.length === 1) { + const arg = this.evaluateExpression(expr.arguments[0]); + let params = []; + if(arg.isString()) { + params = [arg]; + } else if(arg.isArray()) { + params = arg.items.filter(param => param.isString()); + } + params.forEach((param, idx) => { + const dep = new ModuleHotDeclineDependency(param.string, param.range); dep.optional = true; dep.loc = Object.create(expr.loc); dep.loc.index = idx; this.state.module.addDependency(dep); - requests.push(request); - }.bind(this)); - if(expr.arguments.length > 1) - this.applyPluginsBailResult("hot accept callback", expr.arguments[1], requests); - else - this.applyPluginsBailResult("hot accept without callback", expr, requests); - } - } - }); - parser.plugin("call module.hot.decline", function(expr) { - if(!this.state.compilation.hotUpdateChunkTemplate) return false; - if(expr.arguments.length === 1) { - var arg = this.evaluateExpression(expr.arguments[0]); - var params = []; - if(arg.isString()) { - params = [arg]; - } else if(arg.isArray()) { - params = arg.items.filter(function(param) { - return param.isString(); }); } - params.forEach(function(param, idx) { - var dep = new ModuleHotDeclineDependency(param.string, param.range); - dep.optional = true; - dep.loc = Object.create(expr.loc); - dep.loc.index = idx; - this.state.module.addDependency(dep); - }.bind(this)); - } + }); + parser.plugin("expression module.hot", ParserHelpers.skipTraversal); }); - parser.plugin("expression module.hot", ParserHelpers.skipTraversal); }); - }); + } }; -var hotInitCode = Template.getFunctionContent(require("./HotModuleReplacement.runtime.js")); +const hotInitCode = Template.getFunctionContent(require("./HotModuleReplacement.runtime.js")); diff --git a/node_modules/webpack/lib/HotUpdateChunkTemplate.js b/node_modules/webpack/lib/HotUpdateChunkTemplate.js index 89cda0b69..0a83c9a85 100644 --- a/node_modules/webpack/lib/HotUpdateChunkTemplate.js +++ b/node_modules/webpack/lib/HotUpdateChunkTemplate.js @@ -5,6 +5,7 @@ "use strict"; const Template = require("./Template"); +const Chunk = require("./Chunk"); module.exports = class HotUpdateChunkTemplate extends Template { constructor(outputOptions) { @@ -12,11 +13,11 @@ module.exports = class HotUpdateChunkTemplate extends Template { } render(id, modules, removedModules, hash, moduleTemplate, dependencyTemplates) { - const modulesSource = this.renderChunkModules({ - id: id, - modules: modules, - removedModules: removedModules - }, moduleTemplate, dependencyTemplates); + const hotUpdateChunk = new Chunk(); + hotUpdateChunk.id = id; + hotUpdateChunk.setModules(modules); + hotUpdateChunk.removedModules = removedModules; + const modulesSource = this.renderChunkModules(hotUpdateChunk, moduleTemplate, dependencyTemplates); const core = this.applyPluginsWaterfall("modules", modulesSource, modules, removedModules, moduleTemplate, dependencyTemplates); const source = this.applyPluginsWaterfall("render", core, modules, removedModules, hash, id, moduleTemplate, dependencyTemplates); return source; diff --git a/node_modules/webpack/lib/JsonpMainTemplate.runtime.js b/node_modules/webpack/lib/JsonpMainTemplate.runtime.js index dc177376e..bd0e7ba3b 100644 --- a/node_modules/webpack/lib/JsonpMainTemplate.runtime.js +++ b/node_modules/webpack/lib/JsonpMainTemplate.runtime.js @@ -18,7 +18,8 @@ module.exports = function() { head.appendChild(script); } - function hotDownloadManifest() { // eslint-disable-line no-unused-vars + function hotDownloadManifest(requestTimeout) { // eslint-disable-line no-unused-vars + requestTimeout = requestTimeout || 10000; return new Promise(function(resolve, reject) { if(typeof XMLHttpRequest === "undefined") return reject(new Error("No browser support")); @@ -26,7 +27,7 @@ module.exports = function() { var request = new XMLHttpRequest(); var requestPath = $require$.p + $hotMainFilename$; request.open("GET", requestPath, true); - request.timeout = 10000; + request.timeout = requestTimeout; request.send(null); } catch(err) { return reject(err); diff --git a/node_modules/webpack/lib/JsonpMainTemplatePlugin.js b/node_modules/webpack/lib/JsonpMainTemplatePlugin.js index daba5b3e3..9a80e099d 100644 --- a/node_modules/webpack/lib/JsonpMainTemplatePlugin.js +++ b/node_modules/webpack/lib/JsonpMainTemplatePlugin.js @@ -19,9 +19,7 @@ class JsonpMainTemplatePlugin { this.indent( chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(",\n") ), - "};", - "", - "var resolvedPromise = new Promise(function(resolve) { resolve(); });" + "};" ]); } return source; @@ -81,26 +79,27 @@ class JsonpMainTemplatePlugin { }); mainTemplate.plugin("require-ensure", function(_, chunk, hash) { return this.asString([ - "if(installedChunks[chunkId] === 0) {", + "var installedChunkData = installedChunks[chunkId];", + "if(installedChunkData === 0) {", this.indent([ - "return resolvedPromise;" + "return new Promise(function(resolve) { resolve(); });" ]), "}", "", "// a Promise means \"currently loading\".", - "if(installedChunks[chunkId]) {", + "if(installedChunkData) {", this.indent([ - "return installedChunks[chunkId][2];" + "return installedChunkData[2];" ]), "}", "", "// setup Promise in chunk cache", "var promise = new Promise(function(resolve, reject) {", this.indent([ - "installedChunks[chunkId] = [resolve, reject];" + "installedChunkData = installedChunks[chunkId] = [resolve, reject];" ]), "});", - "installedChunks[chunkId][2] = promise;", + "installedChunkData[2] = promise;", "", "// start chunk loading", "var head = document.getElementsByTagName('head')[0];", diff --git a/node_modules/webpack/lib/LibManifestPlugin.js b/node_modules/webpack/lib/LibManifestPlugin.js index 59558f406..dc2f0ae14 100644 --- a/node_modules/webpack/lib/LibManifestPlugin.js +++ b/node_modules/webpack/lib/LibManifestPlugin.js @@ -30,21 +30,26 @@ class LibManifestPlugin { const manifest = { name, type: this.options.type, - content: chunk.modules.reduce((obj, module) => { + content: chunk.mapModules(module => { if(module.libIdent) { const ident = module.libIdent({ context: this.options.context || compiler.options.context }); if(ident) { - obj[ident] = { - id: module.id, - meta: module.meta, - exports: Array.isArray(module.providedExports) ? module.providedExports : undefined + return { + ident, + data: { + id: module.id, + meta: module.meta, + exports: Array.isArray(module.providedExports) ? module.providedExports : undefined + } }; } } + }).filter(Boolean).reduce((obj, item) => { + obj[item.ident] = item.data; return obj; - }, {}) + }, Object.create(null)) }; const content = new Buffer(JSON.stringify(manifest), "utf8"); //eslint-disable-line compiler.outputFileSystem.mkdirp(path.dirname(targetPath), err => { diff --git a/node_modules/webpack/lib/LibraryTemplatePlugin.js b/node_modules/webpack/lib/LibraryTemplatePlugin.js index 6e389053d..11ab06074 100644 --- a/node_modules/webpack/lib/LibraryTemplatePlugin.js +++ b/node_modules/webpack/lib/LibraryTemplatePlugin.js @@ -26,15 +26,20 @@ function accessorAccess(base, accessor, joinWith) { class LibraryTemplatePlugin { - constructor(name, target, umdNamedDefine, auxiliaryComment) { + constructor(name, target, umdNamedDefine, auxiliaryComment, exportProperty) { this.name = name; this.target = target; this.umdNamedDefine = umdNamedDefine; this.auxiliaryComment = auxiliaryComment; + this.exportProperty = exportProperty; } apply(compiler) { compiler.plugin("this-compilation", (compilation) => { + if(this.exportProperty) { + var ExportPropertyMainTemplatePlugin = require("./ExportPropertyMainTemplatePlugin"); + compilation.apply(new ExportPropertyMainTemplatePlugin(this.exportProperty)); + } switch(this.target) { case "var": compilation.apply(new SetVarMainTemplatePlugin(`var ${accessorAccess(false, this.name)}`)); diff --git a/node_modules/webpack/lib/MainTemplate.js b/node_modules/webpack/lib/MainTemplate.js index d14883d15..58a3409d5 100644 --- a/node_modules/webpack/lib/MainTemplate.js +++ b/node_modules/webpack/lib/MainTemplate.js @@ -114,10 +114,6 @@ module.exports = class MainTemplate extends Template { buf.push("// expose the module cache"); buf.push(`${this.requireFn}.c = installedModules;`); - buf.push(""); - buf.push("// identity function for calling harmony imports with the correct context"); - buf.push(`${this.requireFn}.i = function(value) { return value; };`); - buf.push(""); buf.push("// define getter function for harmony exports"); buf.push(`${this.requireFn}.d = function(exports, name, getter) {`); diff --git a/node_modules/webpack/lib/Module.js b/node_modules/webpack/lib/Module.js index 8ce9c85ad..26977e63f 100644 --- a/node_modules/webpack/lib/Module.js +++ b/node_modules/webpack/lib/Module.js @@ -4,30 +4,30 @@ */ "use strict"; +const util = require("util"); + const DependenciesBlock = require("./DependenciesBlock"); const ModuleReason = require("./ModuleReason"); +const SortableSet = require("./util/SortableSet"); const Template = require("./Template"); -function addToSet(set, items) { - for(let item of items) { - if(set.indexOf(item) < 0) - set.push(item); - } -} +let debugId = 1000; -function byId(a, b) { +const sortById = (a, b) => { return a.id - b.id; -} +}; -let debugId = 1000; +const sortByDebugId = (a, b) => { + return a.debugId - b.debugId; +}; class Module extends DependenciesBlock { + constructor() { super(); this.context = null; this.reasons = []; this.debugId = debugId++; - this.lastId = -1; this.id = null; this.portableId = null; this.index = null; @@ -36,18 +36,19 @@ class Module extends DependenciesBlock { this.used = null; this.usedExports = null; this.providedExports = null; - this.chunks = []; + this._chunks = new SortableSet(undefined, sortById); + this._chunksDebugIdent = undefined; this.warnings = []; this.dependenciesWarnings = []; this.errors = []; this.dependenciesErrors = []; this.strict = false; this.meta = {}; + this.optimizationBailout = []; } disconnect() { this.reasons.length = 0; - this.lastId = this.id; this.id = null; this.index = null; this.index2 = null; @@ -55,36 +56,91 @@ class Module extends DependenciesBlock { this.used = null; this.usedExports = null; this.providedExports = null; - this.chunks.length = 0; + this._chunks.clear(); + this._chunksDebugIdent = undefined; super.disconnect(); } unseal() { - this.lastId = this.id; this.id = null; this.index = null; this.index2 = null; this.depth = null; - this.chunks.length = 0; + this._chunks.clear(); + this._chunksDebugIdent = undefined; super.unseal(); } + setChunks(chunks) { + this._chunks = new SortableSet(chunks, sortById); + } + addChunk(chunk) { - let idx = this.chunks.indexOf(chunk); - if(idx < 0) - this.chunks.push(chunk); + this._chunks.add(chunk); + this._chunksDebugIdent = undefined; } removeChunk(chunk) { - let idx = this.chunks.indexOf(chunk); - if(idx >= 0) { - this.chunks.splice(idx, 1); + if(this._chunks.delete(chunk)) { + this._chunksDebugIdent = undefined; chunk.removeModule(this); return true; } return false; } + isInChunk(chunk) { + return this._chunks.has(chunk); + } + + getChunkIdsIdent() { + if(this._chunksDebugIdent !== undefined) return this._chunksDebugIdent; + this._chunks.sortWith(sortByDebugId); + const chunks = this._chunks; + const list = []; + for(const chunk of chunks) { + const debugId = chunk.debugId; + + if(typeof debugId !== "number") { + return this._chunksDebugIdent = null; + } + + list.push(debugId); + } + + return this._chunksDebugIdent = list.join(","); + } + + forEachChunk(fn) { + this._chunks.forEach(fn); + } + + mapChunks(fn) { + return Array.from(this._chunks, fn); + } + + getChunks() { + return Array.from(this._chunks); + } + + getNumberOfChunks() { + return this._chunks.size; + } + + hasEqualsChunks(otherModule) { + if(this._chunks.size !== otherModule._chunks.size) return false; + this._chunks.sortWith(sortByDebugId); + otherModule._chunks.sortWith(sortByDebugId); + const a = this._chunks[Symbol.iterator](); + const b = otherModule._chunks[Symbol.iterator](); + while(true) { // eslint-disable-line + const aItem = a.next(); + const bItem = b.next(); + if(aItem.done) return true; + if(aItem.value !== bItem.value) return false; + } + } + addReason(module, dependency) { this.reasons.push(new ModuleReason(module, dependency)); } @@ -101,28 +157,17 @@ class Module extends DependenciesBlock { } hasReasonForChunk(chunk) { - for(let r of this.reasons) { - if(r.chunks) { - if(r.chunks.indexOf(chunk) >= 0) - return true; - } else if(r.module.chunks.indexOf(chunk) >= 0) + for(let i = 0; i < this.reasons.length; i++) { + if(this.reasons[i].hasChunk(chunk)) return true; } return false; } rewriteChunkInReasons(oldChunk, newChunks) { - this.reasons.forEach(r => { - if(!r.chunks) { - if(r.module.chunks.indexOf(oldChunk) < 0) - return; - r.chunks = r.module.chunks; - } - r.chunks = r.chunks.reduce((arr, c) => { - addToSet(arr, c !== oldChunk ? [c] : newChunks); - return arr; - }, []); - }); + for(let i = 0; i < this.reasons.length; i++) { + this.reasons[i].rewriteChunks(oldChunk, newChunks); + } } isUsed(exportName) { @@ -158,10 +203,14 @@ class Module extends DependenciesBlock { super.updateHash(hash); } - sortItems() { + sortItems(sortChunks) { super.sortItems(); - this.chunks.sort(byId); - this.reasons.sort((a, b) => byId(a.module, b.module)); + if(sortChunks) + this._chunks.sort(); + this.reasons.sort((a, b) => sortById(a.module, b.module)); + if(Array.isArray(this.usedExports)) { + this.usedExports.sort(); + } } unbuild() { @@ -178,6 +227,17 @@ Object.defineProperty(Module.prototype, "entry", { throw new Error("Module.entry was removed. Use Chunk.entryModule"); } }); + +Object.defineProperty(Module.prototype, "chunks", { + configurable: false, + get: util.deprecate(function() { + return Array.from(this._chunks); + }, "Module.chunks: Use Module.forEachChunk/mapChunks/getNumberOfChunks/isInChunk/addChunk/removeChunk instead"), + set() { + throw new Error("Readonly. Use Module.addChunk/removeChunk to modify chunks."); + } +}); + Module.prototype.identifier = null; Module.prototype.readableIdentifier = null; Module.prototype.build = null; diff --git a/node_modules/webpack/lib/ModuleFilenameHelpers.js b/node_modules/webpack/lib/ModuleFilenameHelpers.js index 5deda6e17..f61358b07 100644 --- a/node_modules/webpack/lib/ModuleFilenameHelpers.js +++ b/node_modules/webpack/lib/ModuleFilenameHelpers.js @@ -112,7 +112,7 @@ ModuleFilenameHelpers.createFooter = function createFooter(module, requestShorte "// WEBPACK FOOTER", `// ${module.readableIdentifier(requestShortener)}`, `// module id = ${module.id}`, - `// module chunks = ${module.chunks.map(c => c.id).join(" ")}` + `// module chunks = ${module.mapChunks(c => c.id).join(" ")}` ].join("\n"); } }; diff --git a/node_modules/webpack/lib/ModuleReason.js b/node_modules/webpack/lib/ModuleReason.js index 999952069..52f539d01 100644 --- a/node_modules/webpack/lib/ModuleReason.js +++ b/node_modules/webpack/lib/ModuleReason.js @@ -4,9 +4,47 @@ */ "use strict"; -module.exports = class ModuleReason { +const util = require("util"); + +class ModuleReason { constructor(module, dependency) { this.module = module; this.dependency = dependency; + this._chunks = null; + } + + hasChunk(chunk) { + if(this._chunks) { + if(this._chunks.has(chunk)) + return true; + } else if(this.module._chunks.has(chunk)) + return true; + return false; + } + + rewriteChunks(oldChunk, newChunks) { + if(!this._chunks) { + if(!this.module._chunks.has(oldChunk)) + return; + this._chunks = new Set(this.module._chunks); + } + if(this._chunks.has(oldChunk)) { + this._chunks.delete(oldChunk); + for(let i = 0; i < newChunks.length; i++) { + this._chunks.add(newChunks[i]); + } + } + } +} + +Object.defineProperty(ModuleReason.prototype, "chunks", { + configurable: false, + get: util.deprecate(function() { + return this._chunks ? Array.from(this._chunks) : null; + }, "ModuleReason.chunks: Use ModuleReason.hasChunk/rewriteChunks instead"), + set() { + throw new Error("Readonly. Use ModuleReason.rewriteChunks to modify chunks."); } -}; +}); + +module.exports = ModuleReason; diff --git a/node_modules/webpack/lib/MultiCompiler.js b/node_modules/webpack/lib/MultiCompiler.js index d04ef778f..8c9b8c183 100644 --- a/node_modules/webpack/lib/MultiCompiler.js +++ b/node_modules/webpack/lib/MultiCompiler.js @@ -2,175 +2,163 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -var Tapable = require("tapable"); -var asyncLib = require("async"); -var MultiWatching = require("./MultiWatching"); -var MultiStats = require("./MultiStats"); +"use strict"; -function MultiCompiler(compilers) { - Tapable.call(this); - if(!Array.isArray(compilers)) { - compilers = Object.keys(compilers).map(function(name) { - compilers[name].name = name; - return compilers[name]; - }); - } - this.compilers = compilers; +const Tapable = require("tapable"); +const asyncLib = require("async"); +const MultiWatching = require("./MultiWatching"); +const MultiStats = require("./MultiStats"); - function delegateProperty(name) { - Object.defineProperty(this, name, { - configurable: false, - get: function() { - throw new Error("Cannot read " + name + " of a MultiCompiler"); - }, - set: function(value) { - this.compilers.forEach(function(compiler) { - compiler[name] = value; - }); - }.bind(this) - }); +module.exports = class MultiCompiler extends Tapable { + constructor(compilers) { + super(); + if(!Array.isArray(compilers)) { + compilers = Object.keys(compilers).map((name) => { + compilers[name].name = name; + return compilers[name]; + }); + } + this.compilers = compilers; + let doneCompilers = 0; + let compilerStats = []; + this.compilers.forEach((compiler, idx) => { + let compilerDone = false; + compiler.plugin("done", stats => { + if(!compilerDone) { + compilerDone = true; + doneCompilers++; + } + compilerStats[idx] = stats; + if(doneCompilers === this.compilers.length) { + this.applyPlugins("done", new MultiStats(compilerStats)); + } + }); + compiler.plugin("invalid", () => { + if(compilerDone) { + compilerDone = false; + doneCompilers--; + } + this.applyPlugins("invalid"); + }); + }, this); } - delegateProperty.call(this, "outputFileSystem"); - delegateProperty.call(this, "inputFileSystem"); - Object.defineProperty(this, "outputPath", { - configurable: false, - get: function() { - var commonPath = compilers[0].outputPath; - for(var i = 1; i < compilers.length; i++) { - while(compilers[i].outputPath.indexOf(commonPath) !== 0 && /[\/\\]/.test(commonPath)) { - commonPath = commonPath.replace(/[\/\\][^\/\\]*$/, ""); - } + get outputPath() { + let commonPath = this.compilers[0].outputPath; + for(const compiler of this.compilers) { + while(compiler.outputPath.indexOf(commonPath) !== 0 && /[/\\]/.test(commonPath)) { + commonPath = commonPath.replace(/[/\\][^/\\]*$/, ""); } - if(!commonPath && compilers[0].outputPath[0] === "/") return "/"; - return commonPath; } - }); - var doneCompilers = 0; - var compilerStats = []; - this.compilers.forEach(function(compiler, idx) { - var compilerDone = false; - compiler.plugin("done", function(stats) { - if(!compilerDone) { - compilerDone = true; - doneCompilers++; - } - compilerStats[idx] = stats; - if(doneCompilers === this.compilers.length) { - this.applyPlugins("done", new MultiStats(compilerStats)); - } - }.bind(this)); - compiler.plugin("invalid", function() { - if(compilerDone) { - compilerDone = false; - doneCompilers--; - } - this.applyPlugins("invalid"); - }.bind(this)); - }, this); -} -module.exports = MultiCompiler; + if(!commonPath && this.compilers[0].outputPath[0] === "/") return "/"; + return commonPath; + } -MultiCompiler.prototype = Object.create(Tapable.prototype); -MultiCompiler.prototype.constructor = MultiCompiler; + get inputFileSystem() { + throw new Error("Cannot read inputFileSystem of a MultiCompiler"); + } -function runWithDependencies(compilers, fn, callback) { - var fulfilledNames = {}; - var remainingCompilers = compilers; + get outputFileSystem() { + throw new Error("Cannot read outputFileSystem of a MultiCompiler"); + } - function isDependencyFulfilled(d) { - return fulfilledNames[d]; + set inputFileSystem(value) { + this.compilers.forEach(compiler => { + compiler.inputFileSystem = value; + }); } - function getReadyCompilers() { - var readyCompilers = []; - var list = remainingCompilers; - remainingCompilers = []; - for(var i = 0; i < list.length; i++) { - var c = list[i]; - var ready = !c.dependencies || c.dependencies.every(isDependencyFulfilled); - if(ready) - readyCompilers.push(c); - else - remainingCompilers.push(c); - } - return readyCompilers; + set outputFileSystem(value) { + this.compilers.forEach(compiler => { + compiler.outputFileSystem = value; + }); } - function runCompilers(callback) { - if(remainingCompilers.length === 0) return callback(); - asyncLib.map(getReadyCompilers(), function(compiler, callback) { - fn(compiler, function(err) { - if(err) return callback(err); - fulfilledNames[compiler.name] = true; - runCompilers(callback); - }); - }, callback); + runWithDependencies(compilers, fn, callback) { + let fulfilledNames = {}; + let remainingCompilers = compilers; + const isDependencyFulfilled = (d) => fulfilledNames[d]; + const getReadyCompilers = () => { + let readyCompilers = []; + let list = remainingCompilers; + remainingCompilers = []; + for(const c of list) { + const ready = !c.dependencies || c.dependencies.every(isDependencyFulfilled); + if(ready) + readyCompilers.push(c); + else + remainingCompilers.push(c); + } + return readyCompilers; + }; + const runCompilers = (callback) => { + if(remainingCompilers.length === 0) return callback(); + asyncLib.map(getReadyCompilers(), (compiler, callback) => { + fn(compiler, (err) => { + if(err) return callback(err); + fulfilledNames[compiler.name] = true; + runCompilers(callback); + }); + }, callback); + }; + runCompilers(callback); } - runCompilers(callback); -} -MultiCompiler.prototype.watch = function(watchOptions, handler) { - var watchings = []; - var allStats = this.compilers.map(function() { - return null; - }); - var compilerStatus = this.compilers.map(function() { - return false; - }); - runWithDependencies(this.compilers, function(compiler, callback) { - var compilerIdx = this.compilers.indexOf(compiler); - var firstRun = true; - var watching = compiler.watch(Array.isArray(watchOptions) ? watchOptions[compilerIdx] : watchOptions, function(err, stats) { - if(err) - handler(err); - if(stats) { - allStats[compilerIdx] = stats; - compilerStatus[compilerIdx] = "new"; - if(compilerStatus.every(Boolean)) { - var freshStats = allStats.filter(function(s, idx) { - return compilerStatus[idx] === "new"; - }); - compilerStatus.fill(true); - var multiStats = new MultiStats(freshStats); - handler(null, multiStats); + watch(watchOptions, handler) { + let watchings = []; + let allStats = this.compilers.map(() => null); + let compilerStatus = this.compilers.map(() => false); + this.runWithDependencies(this.compilers, (compiler, callback) => { + const compilerIdx = this.compilers.indexOf(compiler); + let firstRun = true; + let watching = compiler.watch(Array.isArray(watchOptions) ? watchOptions[compilerIdx] : watchOptions, (err, stats) => { + if(err) + handler(err); + if(stats) { + allStats[compilerIdx] = stats; + compilerStatus[compilerIdx] = "new"; + if(compilerStatus.every(Boolean)) { + const freshStats = allStats.filter((s, idx) => { + return compilerStatus[idx] === "new"; + }); + compilerStatus.fill(true); + const multiStats = new MultiStats(freshStats); + handler(null, multiStats); + } } - } - if(firstRun && !err) { - firstRun = false; - callback(); - } + if(firstRun && !err) { + firstRun = false; + callback(); + } + }); + watchings.push(watching); + }, () => { + // ignore }); - watchings.push(watching); - }.bind(this), function() { - // ignore - }); - return new MultiWatching(watchings, this); -}; - -MultiCompiler.prototype.run = function(callback) { - var allStats = this.compilers.map(function() { - return null; - }); + return new MultiWatching(watchings, this); + } - runWithDependencies(this.compilers, function(compiler, callback) { - var compilerIdx = this.compilers.indexOf(compiler); - compiler.run(function(err, stats) { + run(callback) { + const allStats = this.compilers.map(() => null); + this.runWithDependencies(this.compilers, ((compiler, callback) => { + const compilerIdx = this.compilers.indexOf(compiler); + compiler.run((err, stats) => { + if(err) return callback(err); + allStats[compilerIdx] = stats; + callback(); + }); + }), (err) => { if(err) return callback(err); - allStats[compilerIdx] = stats; - callback(); + callback(null, new MultiStats(allStats)); }); - }.bind(this), function(err) { - if(err) return callback(err); - callback(null, new MultiStats(allStats)); - }); -}; + } -MultiCompiler.prototype.purgeInputFileSystem = function() { - this.compilers.forEach(function(compiler) { - if(compiler.inputFileSystem && compiler.inputFileSystem.purge) - compiler.inputFileSystem.purge(); - }); + purgeInputFileSystem() { + this.compilers.forEach((compiler) => { + if(compiler.inputFileSystem && compiler.inputFileSystem.purge) + compiler.inputFileSystem.purge(); + }); + } }; diff --git a/node_modules/webpack/lib/NodeStuffPlugin.js b/node_modules/webpack/lib/NodeStuffPlugin.js index 07a63d1cc..b18ed173c 100644 --- a/node_modules/webpack/lib/NodeStuffPlugin.js +++ b/node_modules/webpack/lib/NodeStuffPlugin.js @@ -77,7 +77,7 @@ class NodeStuffPlugin { if(!isHarmony) return true; }); - parser.plugin("evaluate Identifier module.hot", ParserHelpers.evaluateToBoolean(false)); + parser.plugin("evaluate Identifier module.hot", ParserHelpers.evaluateToIdentifier("module.hot", false)); parser.plugin("expression module", function() { const module = this.state.module; const isHarmony = module.meta && module.meta.harmonyModule; diff --git a/node_modules/webpack/lib/NormalModule.js b/node_modules/webpack/lib/NormalModule.js index b3dda7e5a..d150fc767 100644 --- a/node_modules/webpack/lib/NormalModule.js +++ b/node_modules/webpack/lib/NormalModule.js @@ -54,6 +54,8 @@ class NonErrorEmittedError extends WebpackError { } } +const dependencyTemplatesHashMap = new WeakMap(); + class NormalModule extends Module { constructor(request, userRequest, rawRequest, loaders, resource, parser) { @@ -224,6 +226,10 @@ class NormalModule extends Module { if(typeof rule === "string") { return content.indexOf(rule) === 0; } + + if(typeof rule === "function") { + return rule(content); + } // we assume rule is a regexp return rule.test(content); } @@ -301,9 +307,11 @@ class NormalModule extends Module { }); } - getHashDigest() { + getHashDigest(dependencyTemplates) { + let dtHash = dependencyTemplatesHashMap.get("hash"); const hash = crypto.createHash("md5"); this.updateHash(hash); + hash.update(`${dtHash}`); return hash.digest("hex"); } @@ -384,9 +392,16 @@ class NormalModule extends Module { * These will contain the variable name and its expression. * The name will be added as a paramter in a IIFE the expression as its value. */ - const vars = block.variables.map((variable) => this.sourceVariables( - variable, availableVars, dependencyTemplates, outputOptions, requestShortener)) - .filter(Boolean); + const vars = block.variables.reduce((result, value) => { + const variable = this.sourceVariables( + value, availableVars, dependencyTemplates, outputOptions, requestShortener); + + if(variable) { + result.push(variable); + } + + return result; + }, []); /** * if we actually have variables @@ -412,15 +427,22 @@ class NormalModule extends Module { const injectionVariableChunks = this.splitVariablesInUniqueNamedChunks(vars); // create all the beginnings of IIFEs - const functionWrapperStarts = injectionVariableChunks.map((variableChunk) => variableChunk.map(variable => variable.name)) - .map(names => this.variableInjectionFunctionWrapperStartCode(names)); + const functionWrapperStarts = injectionVariableChunks.map((variableChunk) => { + return this.variableInjectionFunctionWrapperStartCode( + variableChunk.map(variable => variable.name) + ); + }); // and all the ends - const functionWrapperEnds = injectionVariableChunks.map((variableChunk) => variableChunk.map(variable => variable.expression)) - .map(expressions => this.variableInjectionFunctionWrapperEndCode(expressions, block)); + const functionWrapperEnds = injectionVariableChunks.map((variableChunk) => { + return this.variableInjectionFunctionWrapperEndCode( + variableChunk.map(variable => variable.expression), block + ); + }); // join them to one big string const varStartCode = functionWrapperStarts.join(""); + // reverse the ends first before joining them, as the last added must be the inner most const varEndCode = functionWrapperEnds.reverse().join(""); @@ -432,12 +454,21 @@ class NormalModule extends Module { source.insert(end + 0.5, "\n/* WEBPACK VAR INJECTION */" + varEndCode); } } - block.blocks.forEach((block) => this.sourceBlock( - block, availableVars.concat(vars), dependencyTemplates, source, outputOptions, requestShortener)); + + block.blocks.forEach((block) => + this.sourceBlock( + block, + availableVars.concat(vars), + dependencyTemplates, + source, + outputOptions, + requestShortener + ) + ); } source(dependencyTemplates, outputOptions, requestShortener) { - const hashDigest = this.getHashDigest(); + const hashDigest = this.getHashDigest(dependencyTemplates); if(this._cachedSource && this._cachedSource.hash === hashDigest) { return this._cachedSource.source; } diff --git a/node_modules/webpack/lib/NormalModuleFactory.js b/node_modules/webpack/lib/NormalModuleFactory.js index 170afb1c3..138b87d18 100644 --- a/node_modules/webpack/lib/NormalModuleFactory.js +++ b/node_modules/webpack/lib/NormalModuleFactory.js @@ -50,173 +50,161 @@ class NormalModuleFactory extends Tapable { this.cachePredicate = typeof options.unsafeCache === "function" ? options.unsafeCache : Boolean.bind(null, options.unsafeCache); this.context = context || ""; this.parserCache = {}; - this.plugin("factory", function() { - /* beautify preserve:start */ - // js-beautify consider to concat "return" and "(" - // but it сontradicts eslint rule (keyword-spacing) - return (result, callback) => { - /* beautify preserve:end */ - let resolver = this.applyPluginsWaterfall0("resolver", null); + this.plugin("factory", () => (result, callback) => { + let resolver = this.applyPluginsWaterfall0("resolver", null); - // Ignored - if(!resolver) return callback(); - - resolver(result, (err, data) => { - if(err) return callback(err); + // Ignored + if(!resolver) return callback(); - // Ignored - if(!data) return callback(); + resolver(result, (err, data) => { + if(err) return callback(err); - // direct module - if(typeof data.source === "function") - return callback(null, data); + // Ignored + if(!data) return callback(); - this.applyPluginsAsyncWaterfall("after-resolve", data, (err, result) => { - if(err) return callback(err); + // direct module + if(typeof data.source === "function") + return callback(null, data); - // Ignored - if(!result) return callback(); + this.applyPluginsAsyncWaterfall("after-resolve", data, (err, result) => { + if(err) return callback(err); - let createdModule = this.applyPluginsBailResult("create-module", result); - if(!createdModule) { + // Ignored + if(!result) return callback(); - if(!result.request) { - return callback(new Error("Empty dependency (no request)")); - } + let createdModule = this.applyPluginsBailResult("create-module", result); + if(!createdModule) { - createdModule = new NormalModule( - result.request, - result.userRequest, - result.rawRequest, - result.loaders, - result.resource, - result.parser - ); + if(!result.request) { + return callback(new Error("Empty dependency (no request)")); } - createdModule = this.applyPluginsWaterfall0("module", createdModule); + createdModule = new NormalModule( + result.request, + result.userRequest, + result.rawRequest, + result.loaders, + result.resource, + result.parser + ); + } - return callback(null, createdModule); - }); + createdModule = this.applyPluginsWaterfall0("module", createdModule); + + return callback(null, createdModule); }); - }; + }); }); - this.plugin("resolver", function() { - /* beautify preserve:start */ - // js-beautify consider to concat "return" and "(" - // but it сontradicts eslint rule (keyword-spacing) - return (data, callback) => { - /* beautify preserve:end */ - const contextInfo = data.contextInfo; - const context = data.context; - const request = data.request; - - const noAutoLoaders = /^-?!/.test(request); - const noPrePostAutoLoaders = /^!!/.test(request); - const noPostAutoLoaders = /^-!/.test(request); - let elements = request.replace(/^-?!+/, "").replace(/!!+/g, "!").split("!"); - let resource = elements.pop(); - elements = elements.map(identToLoaderRequest); - - asyncLib.parallel([ - callback => this.resolveRequestArray(contextInfo, context, elements, this.resolvers.loader, callback), - callback => { - if(resource === "" || resource[0] === "?") - return callback(null, { - resource - }); - - this.resolvers.normal.resolve(contextInfo, context, resource, (err, resource, resourceResolveData) => { - if(err) return callback(err); - callback(null, { - resourceResolveData, - resource - }); + this.plugin("resolver", () => (data, callback) => { + const contextInfo = data.contextInfo; + const context = data.context; + const request = data.request; + + const noAutoLoaders = /^-?!/.test(request); + const noPrePostAutoLoaders = /^!!/.test(request); + const noPostAutoLoaders = /^-!/.test(request); + let elements = request.replace(/^-?!+/, "").replace(/!!+/g, "!").split("!"); + let resource = elements.pop(); + elements = elements.map(identToLoaderRequest); + + asyncLib.parallel([ + callback => this.resolveRequestArray(contextInfo, context, elements, this.resolvers.loader, callback), + callback => { + if(resource === "" || resource[0] === "?") + return callback(null, { + resource }); - } - ], (err, results) => { - if(err) return callback(err); - let loaders = results[0]; - const resourceResolveData = results[1].resourceResolveData; - resource = results[1].resource; - - // translate option idents - try { - loaders.forEach(item => { - if(typeof item.options === "string" && /^\?/.test(item.options)) { - item.options = this.ruleSet.findOptionsByIdent(item.options.substr(1)); - } + + this.resolvers.normal.resolve(contextInfo, context, resource, (err, resource, resourceResolveData) => { + if(err) return callback(err); + callback(null, { + resourceResolveData, + resource }); - } catch(e) { - return callback(e); - } + }); + } + ], (err, results) => { + if(err) return callback(err); + let loaders = results[0]; + const resourceResolveData = results[1].resourceResolveData; + resource = results[1].resource; + + // translate option idents + try { + loaders.forEach(item => { + if(typeof item.options === "string" && /^\?/.test(item.options)) { + item.options = this.ruleSet.findOptionsByIdent(item.options.substr(1)); + } + }); + } catch(e) { + return callback(e); + } - if(resource === false) { - // ignored - return callback(null, - new RawModule( - "/* (ignored) */", - `ignored ${context} ${request}`, - `${request} (ignored)` - ) - ); - } + if(resource === false) { + // ignored + return callback(null, + new RawModule( + "/* (ignored) */", + `ignored ${context} ${request}`, + `${request} (ignored)` + ) + ); + } - const userRequest = loaders.map(loaderToIdent).concat([resource]).join("!"); + const userRequest = loaders.map(loaderToIdent).concat([resource]).join("!"); - let resourcePath = resource; - let resourceQuery = ""; - const queryIndex = resourcePath.indexOf("?"); - if(queryIndex >= 0) { - resourceQuery = resourcePath.substr(queryIndex); - resourcePath = resourcePath.substr(0, queryIndex); - } + let resourcePath = resource; + let resourceQuery = ""; + const queryIndex = resourcePath.indexOf("?"); + if(queryIndex >= 0) { + resourceQuery = resourcePath.substr(queryIndex); + resourcePath = resourcePath.substr(0, queryIndex); + } - const result = this.ruleSet.exec({ - resource: resourcePath, - resourceQuery, - issuer: contextInfo.issuer, - compiler: contextInfo.compiler - }); - const settings = {}; - const useLoadersPost = []; - const useLoaders = []; - const useLoadersPre = []; - result.forEach(r => { - if(r.type === "use") { - if(r.enforce === "post" && !noPostAutoLoaders && !noPrePostAutoLoaders) - useLoadersPost.push(r.value); - else if(r.enforce === "pre" && !noPrePostAutoLoaders) - useLoadersPre.push(r.value); - else if(!r.enforce && !noAutoLoaders && !noPrePostAutoLoaders) - useLoaders.push(r.value); - } else { - settings[r.type] = r.value; - } - }); - asyncLib.parallel([ - this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPost, this.resolvers.loader), - this.resolveRequestArray.bind(this, contextInfo, this.context, useLoaders, this.resolvers.loader), - this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPre, this.resolvers.loader) - ], (err, results) => { - if(err) return callback(err); - loaders = results[0].concat(loaders, results[1], results[2]); - process.nextTick(() => { - callback(null, { - context: context, - request: loaders.map(loaderToIdent).concat([resource]).join("!"), - dependencies: data.dependencies, - userRequest, - rawRequest: request, - loaders, - resource, - resourceResolveData, - parser: this.getParser(settings.parser) - }); + const result = this.ruleSet.exec({ + resource: resourcePath, + resourceQuery, + issuer: contextInfo.issuer, + compiler: contextInfo.compiler + }); + const settings = {}; + const useLoadersPost = []; + const useLoaders = []; + const useLoadersPre = []; + result.forEach(r => { + if(r.type === "use") { + if(r.enforce === "post" && !noPostAutoLoaders && !noPrePostAutoLoaders) + useLoadersPost.push(r.value); + else if(r.enforce === "pre" && !noPrePostAutoLoaders) + useLoadersPre.push(r.value); + else if(!r.enforce && !noAutoLoaders && !noPrePostAutoLoaders) + useLoaders.push(r.value); + } else { + settings[r.type] = r.value; + } + }); + asyncLib.parallel([ + this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPost, this.resolvers.loader), + this.resolveRequestArray.bind(this, contextInfo, this.context, useLoaders, this.resolvers.loader), + this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPre, this.resolvers.loader) + ], (err, results) => { + if(err) return callback(err); + loaders = results[0].concat(loaders, results[1], results[2]); + process.nextTick(() => { + callback(null, { + context: context, + request: loaders.map(loaderToIdent).concat([resource]).join("!"), + dependencies: data.dependencies, + userRequest, + rawRequest: request, + loaders, + resource, + resourceResolveData, + parser: this.getParser(settings.parser) }); }); }); - }; + }); }); } diff --git a/node_modules/webpack/lib/Parser.js b/node_modules/webpack/lib/Parser.js index bd81b55ab..88f9b65db 100644 --- a/node_modules/webpack/lib/Parser.js +++ b/node_modules/webpack/lib/Parser.js @@ -17,10 +17,12 @@ function joinRanges(startRange, endRange) { return [startRange[0], endRange[1]]; } +const ECMA_VERSION = 2017; + const POSSIBLE_AST_OPTIONS = [{ ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -28,7 +30,7 @@ const POSSIBLE_AST_OPTIONS = [{ }, { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "script", plugins: { dynamicImport: true @@ -212,19 +214,10 @@ class Parser extends Tapable { } } if(expr.argument.type === "MemberExpression") { - let expression = expr.argument; - let exprName = []; - while(expression.type === "MemberExpression" && !expression.computed) { - exprName.unshift(this.scope.renames["$" + expression.property.name] || expression.property.name); - expression = expression.object; - } - if(expression.type === "Identifier") { - exprName.unshift(this.scope.renames["$" + expression.name] || expression.name); - if(this.scope.definitions.indexOf(name) === -1) { - exprName = exprName.join("."); - res = this.applyPluginsBailResult1("evaluate typeof " + exprName, expr); - if(res !== undefined) return res; - } + const exprName = this.getNameForExpression(expr.argument); + if(exprName && exprName.free) { + res = this.applyPluginsBailResult1("evaluate typeof " + exprName.name, expr); + if(res !== undefined) return res; } } if(expr.argument.type === "FunctionExpression") { @@ -240,6 +233,10 @@ class Parser extends Tapable { if(!argument) return; if(argument.isBoolean()) { return new BasicEvaluatedExpression().setBoolean(!argument.bool).setRange(expr.range); + } else if(argument.isTruthy()) { + return new BasicEvaluatedExpression().setBoolean(false).setRange(expr.range); + } else if(argument.isFalsy()) { + return new BasicEvaluatedExpression().setBoolean(true).setRange(expr.range); } else if(argument.isString()) { return new BasicEvaluatedExpression().setBoolean(!argument.string).setRange(expr.range); } else if(argument.isNumber()) { @@ -260,25 +257,23 @@ class Parser extends Tapable { return this.applyPluginsBailResult1("evaluate defined Identifier " + name, expr); } }); - this.plugin("evaluate MemberExpression", function(expression) { - let expr = expression; - let exprName = []; - while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) { - exprName.unshift(expr.property.name || expr.property.value); - expr = expr.object; + this.plugin("evaluate ThisExpression", function(expr) { + const name = this.scope.renames.$this; + if(name) { + const result = this.applyPluginsBailResult1("evaluate Identifier " + name, expr); + if(result) return result; + return new BasicEvaluatedExpression().setIdentifier(name).setRange(expr.range); } - if(expr.type === "Identifier") { - const name = this.scope.renames["$" + expr.name] || expr.name; - if(this.scope.definitions.indexOf(name) === -1) { - exprName.unshift(name); - exprName = exprName.join("."); - if(this.scope.definitions.indexOf(expr.name) === -1) { - const result = this.applyPluginsBailResult1("evaluate Identifier " + exprName, expression); - if(result) return result; - return new BasicEvaluatedExpression().setIdentifier(exprName).setRange(expression.range); - } else { - return this.applyPluginsBailResult1("evaluate defined Identifier " + exprName, expression); - } + }); + this.plugin("evaluate MemberExpression", function(expression) { + let exprName = this.getNameForExpression(expression); + if(exprName) { + if(exprName.free) { + const result = this.applyPluginsBailResult1("evaluate Identifier " + exprName.name, expression); + if(result) return result; + return new BasicEvaluatedExpression().setIdentifier(exprName.name).setRange(expression.range); + } else { + return this.applyPluginsBailResult1("evaluate defined Identifier " + exprName.name, expression); } } }); @@ -639,14 +634,14 @@ class Parser extends Tapable { statement.params.forEach(param => { this.walkPattern(param); }); - this.inScope(statement.params, function() { + this.inScope(statement.params, () => { if(statement.body.type === "BlockStatement") { this.prewalkStatement(statement.body); this.walkStatement(statement.body); } else { this.walkExpression(statement.body); } - }.bind(this)); + }); } prewalkImportDeclaration(statement) { @@ -789,10 +784,10 @@ class Parser extends Tapable { } walkCatchClause(catchClause) { - this.inScope([catchClause.param], function() { + this.inScope([catchClause.param], () => { this.prewalkStatement(catchClause.body); this.walkStatement(catchClause.body); - }.bind(this)); + }); } prewalkVariableDeclarators(declarators) { @@ -921,28 +916,28 @@ class Parser extends Tapable { expression.params.forEach(param => { this.walkPattern(param); }); - this.inScope(expression.params, function() { + this.inScope(expression.params, () => { if(expression.body.type === "BlockStatement") { this.prewalkStatement(expression.body); this.walkStatement(expression.body); } else { this.walkExpression(expression.body); } - }.bind(this)); + }); } walkArrowFunctionExpression(expression) { expression.params.forEach(param => { this.walkPattern(param); }); - this.inScope(expression.params, function() { + this.inScope(expression.params, () => { if(expression.body.type === "BlockStatement") { this.prewalkStatement(expression.body); this.walkStatement(expression.body); } else { this.walkExpression(expression.body); } - }.bind(this)); + }); } walkSequenceExpression(expression) { @@ -956,16 +951,9 @@ class Parser extends Tapable { walkUnaryExpression(expression) { if(expression.operator === "typeof") { - let expr = expression.argument; - let exprName = []; - while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) { - exprName.unshift(expr.property.name || expr.property.value); - expr = expr.object; - } - if(expr.type === "Identifier" && this.scope.definitions.indexOf(expr.name) === -1) { - exprName.unshift(this.scope.renames["$" + expr.name] || expr.name); - exprName = exprName.join("."); - const result = this.applyPluginsBailResult1("typeof " + exprName, expression); + const exprName = this.getNameForExpression(expression.argument); + if(exprName && exprName.free) { + const result = this.applyPluginsBailResult1("typeof " + exprName.name, expression); if(result === true) return; } @@ -1057,19 +1045,24 @@ class Parser extends Tapable { walkCallExpression(expression) { let result; - function walkIIFE(functionExpression, options) { - const params = functionExpression.params; - const args = options.map(function(arg) { - const renameIdentifier = this.getRenameIdentifier(arg); - if(renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, arg)) { - if(!this.applyPluginsBailResult1("rename " + renameIdentifier, arg)) + function walkIIFE(functionExpression, options, currentThis) { + function renameArgOrThis(argOrThis) { + const renameIdentifier = this.getRenameIdentifier(argOrThis); + if(renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, argOrThis)) { + if(!this.applyPluginsBailResult1("rename " + renameIdentifier, argOrThis)) return renameIdentifier; } - this.walkExpression(arg); - }, this); + this.walkExpression(argOrThis); + } + const params = functionExpression.params; + const renameThis = currentThis ? renameArgOrThis.call(this, currentThis) : null; + const args = options.map(renameArgOrThis, this); this.inScope(params.filter(function(identifier, idx) { return !args[idx]; - }), function() { + }), () => { + if(renameThis) { + this.scope.renames.$this = renameThis; + } for(let i = 0; i < args.length; i++) { const param = args[i]; if(!param) continue; @@ -1081,18 +1074,17 @@ class Parser extends Tapable { this.walkStatement(functionExpression.body); } else this.walkExpression(functionExpression.body); - }.bind(this)); + }); } if(expression.callee.type === "MemberExpression" && expression.callee.object.type === "FunctionExpression" && !expression.callee.computed && (["call", "bind"]).indexOf(expression.callee.property.name) >= 0 && expression.arguments && - expression.arguments.length > 1 + expression.arguments.length > 0 ) { // (function(...) { }.call/bind(?, ...)) - walkIIFE.call(this, expression.callee.object, expression.arguments.slice(1)); - this.walkExpression(expression.arguments[0]); + walkIIFE.call(this, expression.callee.object, expression.arguments.slice(1), expression.arguments[0]); } else if(expression.callee.type === "FunctionExpression" && expression.arguments) { // (function(...) { }(...)) walkIIFE.call(this, expression.callee, expression.arguments); @@ -1110,6 +1102,12 @@ class Parser extends Tapable { result = this.applyPluginsBailResult1("call " + callee.identifier, expression); if(result === true) return; + let identifier = callee.identifier.replace(/\.[^.]+$/, ".*"); + if(identifier !== callee.identifier) { + result = this.applyPluginsBailResult1("call " + identifier, expression); + if(result === true) + return; + } } if(expression.callee) @@ -1120,19 +1118,12 @@ class Parser extends Tapable { } walkMemberExpression(expression) { - let expr = expression; - let exprName = []; - while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) { - exprName.unshift(expr.property.name || expr.property.value); - expr = expr.object; - } - if(expr.type === "Identifier" && this.scope.definitions.indexOf(expr.name) === -1) { - exprName.unshift(this.scope.renames["$" + expr.name] || expr.name); - let result = this.applyPluginsBailResult1("expression " + exprName.join("."), expression); + const exprName = this.getNameForExpression(expression); + if(exprName && exprName.free) { + let result = this.applyPluginsBailResult1("expression " + exprName.name, expression); if(result === true) return; - exprName[exprName.length - 1] = "*"; - result = this.applyPluginsBailResult1("expression " + exprName.join("."), expression); + result = this.applyPluginsBailResult1("expression " + exprName.nameGeneral, expression); if(result === true) return; } @@ -1158,6 +1149,8 @@ class Parser extends Tapable { renames: Object.create(oldScope.renames) }; + this.scope.renames.$this = undefined; + for(let paramIndex = 0, len = params.length; paramIndex < len; paramIndex++) { const param = params[paramIndex]; @@ -1335,7 +1328,7 @@ class Parser extends Tapable { ast = acorn.parse(source, { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -1369,7 +1362,7 @@ class Parser extends Tapable { const ast = acorn.parse("(" + source + ")", { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -1399,6 +1392,40 @@ class Parser extends Tapable { return options.reduce((o, i) => Object.assign(o, i), {}); } + getNameForExpression(expression) { + let expr = expression; + const exprName = []; + while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) { + exprName.push(expr.computed ? expr.property.value : expr.property.name); + expr = expr.object; + } + let free; + if(expr.type === "Identifier") { + free = this.scope.definitions.indexOf(expr.name) === -1; + exprName.push(this.scope.renames["$" + expr.name] || expr.name); + } else if(expr.type === "ThisExpression" && this.scope.renames.$this) { + free = true; + exprName.push(this.scope.renames.$this); + } else if(expr.type === "ThisExpression") { + free = false; + exprName.push("this"); + } else { + return null; + } + let prefix = ""; + for(let i = exprName.length - 1; i >= 1; i--) + prefix += exprName[i] + "."; + const name = prefix + exprName[0]; + const nameGeneral = prefix + "*"; + return { + name, + nameGeneral, + free + }; + } + } +Parser.ECMA_VERSION = ECMA_VERSION; + module.exports = Parser; diff --git a/node_modules/webpack/lib/ParserHelpers.js b/node_modules/webpack/lib/ParserHelpers.js index 944c54820..64a0e9996 100644 --- a/node_modules/webpack/lib/ParserHelpers.js +++ b/node_modules/webpack/lib/ParserHelpers.js @@ -56,6 +56,15 @@ ParserHelpers.evaluateToBoolean = function(value) { }; }; +ParserHelpers.evaluateToIdentifier = function(identifier, truthy) { + return function identifierExpression(expr) { + let evex = new BasicEvaluatedExpression().setIdentifier(identifier).setRange(expr.range); + if(truthy === true) evex = evex.setTruthy(); + else if(truthy === false) evex = evex.setFalsy(); + return evex; + }; +}; + ParserHelpers.expressionIsUnsupported = function(message) { return function unsupportedExpression(expr) { var dep = new ConstDependency("(void 0)", expr.range); diff --git a/node_modules/webpack/lib/ProgressPlugin.js b/node_modules/webpack/lib/ProgressPlugin.js index 5bb256f4b..b0828d8a8 100644 --- a/node_modules/webpack/lib/ProgressPlugin.js +++ b/node_modules/webpack/lib/ProgressPlugin.js @@ -82,17 +82,19 @@ class ProgressPlugin { "optimize-chunks": [0.77, "chunk optimization"], "optimize-chunks-advanced": [0.78, "advanced chunk optimization"], // optimize-tree - "revive-modules": [0.80, "module reviving"], - "optimize-module-order": [0.81, "module order optimization"], - "optimize-module-ids": [0.82, "module id optimization"], - "revive-chunks": [0.83, "chunk reviving"], - "optimize-chunk-order": [0.84, "chunk order optimization"], - "optimize-chunk-ids": [0.85, "chunk id optimization"], - "before-hash": [0.86, "hashing"], - "before-module-assets": [0.87, "module assets processing"], - "before-chunk-assets": [0.88, "chunk assets processing"], - "additional-chunk-assets": [0.89, "additional chunk assets processing"], - "record": [0.90, "recording"] + "optimize-chunk-modules": [0.80, "chunk modules optimization"], + "optimize-chunk-modules-advanced": [0.81, "advanced chunk modules optimization"], + "revive-modules": [0.82, "module reviving"], + "optimize-module-order": [0.83, "module order optimization"], + "optimize-module-ids": [0.84, "module id optimization"], + "revive-chunks": [0.85, "chunk reviving"], + "optimize-chunk-order": [0.86, "chunk order optimization"], + "optimize-chunk-ids": [0.87, "chunk id optimization"], + "before-hash": [0.88, "hashing"], + "before-module-assets": [0.89, "module assets processing"], + "before-chunk-assets": [0.90, "chunk assets processing"], + "additional-chunk-assets": [0.91, "additional chunk assets processing"], + "record": [0.92, "recording"] }; Object.keys(syncHooks).forEach(name => { let pass = 0; diff --git a/node_modules/webpack/lib/RawModule.js b/node_modules/webpack/lib/RawModule.js index 3d29cdb98..d937cafc0 100644 --- a/node_modules/webpack/lib/RawModule.js +++ b/node_modules/webpack/lib/RawModule.js @@ -47,4 +47,8 @@ module.exports = class RawModule extends Module { return new RawSource(this.sourceStr); } + updateHash(hash) { + hash.update(this.sourceStr); + super.updateHash(hash); + } }; diff --git a/node_modules/webpack/lib/RecordIdsPlugin.js b/node_modules/webpack/lib/RecordIdsPlugin.js index 735288f40..a4d53085b 100644 --- a/node_modules/webpack/lib/RecordIdsPlugin.js +++ b/node_modules/webpack/lib/RecordIdsPlugin.js @@ -47,12 +47,12 @@ class RecordIdsPlugin { const p = block.parent; const idx = p.blocks.indexOf(block); const l = p.blocks.length - 1; - ident.unshift(`${idx}/${l}`); + ident.push(`${idx}/${l}`); block = block.parent; } if(!block.identifier) return null; - ident.unshift(identifierUtils.makePathsRelative(compiler.context, block.identifier())); - return ident.join(":"); + ident.push(identifierUtils.makePathsRelative(compiler.context, block.identifier())); + return ident.reverse().join(":"); } compilation.plugin("record-chunks", (chunks, records) => { records.nextFreeChunkId = compilation.nextFreeChunkId; diff --git a/node_modules/webpack/lib/RequestShortener.js b/node_modules/webpack/lib/RequestShortener.js index 369e44334..0dd27a7d2 100644 --- a/node_modules/webpack/lib/RequestShortener.js +++ b/node_modules/webpack/lib/RequestShortener.js @@ -5,40 +5,48 @@ "use strict"; const path = require("path"); +const NORMALIZE_SLASH_DIRECTION_REGEXP = /\\/g; +const PATH_CHARS_REGEXP = /[-[\]{}()*+?.,\\^$|#\s]/g; +const SEPARATOR_REGEXP = /[/\\]$/; +const FRONT_OR_BACK_BANG_REGEXP = /^!|!$/g; +const INDEX_JS_REGEXP = /\/index.js(!|\?|\(query\))/g; + +const normalizeBackSlashDirection = (request) => { + return request.replace(NORMALIZE_SLASH_DIRECTION_REGEXP, "/"); +}; + +const createRegExpForPath = (path) => { + const regexpTypePartial = path.replace(PATH_CHARS_REGEXP, "\\$&"); + return new RegExp(`(^|!)${regexpTypePartial}`, "g"); +}; class RequestShortener { constructor(directory) { - directory = directory.replace(/\\/g, "/"); - if(/[\/\\]$/.test(directory)) directory = directory.substr(0, directory.length - 1); + directory = normalizeBackSlashDirection(directory); + if(SEPARATOR_REGEXP.test(directory)) directory = directory.substr(0, directory.length - 1); if(directory) { - const currentDirectoryRegExpString = directory.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - this.currentDirectoryRegExp = new RegExp("^" + currentDirectoryRegExpString + "|(!)" + currentDirectoryRegExpString, "g"); + this.currentDirectoryRegExp = createRegExpForPath(directory); } const dirname = path.dirname(directory); - const endsWithSeperator = /[\/\\]$/.test(dirname); + const endsWithSeperator = SEPARATOR_REGEXP.test(dirname); const parentDirectory = endsWithSeperator ? dirname.substr(0, dirname.length - 1) : dirname; if(parentDirectory && parentDirectory !== directory) { - const parentDirectoryRegExpString = parentDirectory.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - this.parentDirectoryRegExp = new RegExp("^" + parentDirectoryRegExpString + "|(!)" + parentDirectoryRegExpString, "g"); + this.parentDirectoryRegExp = createRegExpForPath(parentDirectory); } if(__dirname.length >= 2) { - const buildins = path.join(__dirname, "..").replace(/\\/g, "/"); + const buildins = normalizeBackSlashDirection(path.join(__dirname, "..")); const buildinsAsModule = this.currentDirectoryRegExp && this.currentDirectoryRegExp.test(buildins); this.buildinsAsModule = buildinsAsModule; - const buildinsRegExpString = buildins.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - this.buildinsRegExp = new RegExp("^" + buildinsRegExpString + "|(!)" + buildinsRegExpString, "g"); + this.buildinsRegExp = createRegExpForPath(buildins); } - - this.nodeModulesRegExp = /\/node_modules\//g; - this.indexJsRegExp = /\/index.js(!|\?|\(query\))/g; } shorten(request) { if(!request) return request; - request = request.replace(/\\/g, "/"); + request = normalizeBackSlashDirection(request); if(this.buildinsAsModule && this.buildinsRegExp) request = request.replace(this.buildinsRegExp, "!(webpack)"); if(this.currentDirectoryRegExp) @@ -47,9 +55,8 @@ class RequestShortener { request = request.replace(this.parentDirectoryRegExp, "!.."); if(!this.buildinsAsModule && this.buildinsRegExp) request = request.replace(this.buildinsRegExp, "!(webpack)"); - request = request.replace(this.nodeModulesRegExp, "/~/"); - request = request.replace(this.indexJsRegExp, "$1"); - return request.replace(/^!|!$/, ""); + request = request.replace(INDEX_JS_REGEXP, "$1"); + return request.replace(FRONT_OR_BACK_BANG_REGEXP, ""); } } diff --git a/node_modules/webpack/lib/RequireJsStuffPlugin.js b/node_modules/webpack/lib/RequireJsStuffPlugin.js index 0bd6aa7d5..92bc3fc91 100644 --- a/node_modules/webpack/lib/RequireJsStuffPlugin.js +++ b/node_modules/webpack/lib/RequireJsStuffPlugin.js @@ -23,7 +23,7 @@ module.exports = class RequireJsStuffPlugin { parser.plugin("call requirejs.config", ParserHelpers.toConstantDependency("undefined")); parser.plugin("expression require.version", ParserHelpers.toConstantDependency(JSON.stringify("0.0.0"))); - parser.plugin("expression requirejs.onError", ParserHelpers.toConstantDependency(JSON.stringify("__webpack_require__.oe"))); + parser.plugin("expression requirejs.onError", ParserHelpers.toConstantDependency("__webpack_require__.oe")); }); }); } diff --git a/node_modules/webpack/lib/RuleSet.js b/node_modules/webpack/lib/RuleSet.js index c52226b84..cb679b5f6 100644 --- a/node_modules/webpack/lib/RuleSet.js +++ b/node_modules/webpack/lib/RuleSet.js @@ -104,7 +104,7 @@ module.exports = class RuleSet { if(typeof rule !== "object") throw new Error("Unexcepted " + typeof rule + " when object was expected as rule (" + rule + ")"); - let newRule = {}; + const newRule = {}; let useSource; let resourceSource; let condition; @@ -265,7 +265,7 @@ module.exports = class RuleSet { return RuleSet.normalizeUseItemString(item); } - let newItem = {}; + const newItem = {}; if(item.options && item.query) throw new Error("Provided options and query in use"); @@ -312,7 +312,7 @@ module.exports = class RuleSet { if(typeof condition !== "object") throw Error("Unexcepted " + typeof condition + " when condition was expected (" + condition + ")"); - let matchers = []; + const matchers = []; Object.keys(condition).forEach(key => { const value = condition[key]; switch(key) { diff --git a/node_modules/webpack/lib/SourceMapDevToolPlugin.js b/node_modules/webpack/lib/SourceMapDevToolPlugin.js index 53645fb4e..abd8d5ee3 100644 --- a/node_modules/webpack/lib/SourceMapDevToolPlugin.js +++ b/node_modules/webpack/lib/SourceMapDevToolPlugin.js @@ -5,6 +5,7 @@ "use strict"; const path = require("path"); +const crypto = require("crypto"); const RequestShortener = require("./RequestShortener"); const ConcatSource = require("webpack-sources").ConcatSource; const RawSource = require("webpack-sources").RawSource; @@ -16,6 +17,38 @@ const basename = (name) => { return name.substr(name.lastIndexOf("/") + 1); }; +function getTaskForFile(file, chunk, options, compilation) { + const asset = compilation.assets[file]; + if(asset.__SourceMapDevToolFile === file && asset.__SourceMapDevToolData) { + const data = asset.__SourceMapDevToolData; + for(const cachedFile in data) { + compilation.assets[cachedFile] = data[cachedFile]; + if(cachedFile !== file) + chunk.files.push(cachedFile); + } + return; + } + let source, sourceMap; + if(asset.sourceAndMap) { + const sourceAndMap = asset.sourceAndMap(options); + sourceMap = sourceAndMap.map; + source = sourceAndMap.source; + } else { + sourceMap = asset.map(options); + source = asset.source(); + } + if(sourceMap) { + return { + chunk, + file, + asset, + source, + sourceMap, + modules: undefined + }; + } +} + class SourceMapDevToolPlugin { constructor(options) { if(arguments.length > 1) @@ -42,81 +75,85 @@ class SourceMapDevToolPlugin { const requestShortener = new RequestShortener(compiler.context); const options = this.options; options.test = options.test || /\.(js|css)($|\?)/i; + + const matchObject = ModuleFilenameHelpers.matchObject.bind(undefined, options); + compiler.plugin("compilation", compilation => { new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation); + compilation.plugin("after-optimize-chunk-assets", function(chunks) { - let allModules = []; - let allModuleFilenames = []; + const moduleToSourceNameMapping = new Map(); const tasks = []; + chunks.forEach(function(chunk) { - chunk.files.filter(ModuleFilenameHelpers.matchObject.bind(undefined, options)).map(function(file) { - const asset = compilation.assets[file]; - if(asset.__SourceMapDevToolFile === file && asset.__SourceMapDevToolData) { - const data = asset.__SourceMapDevToolData; - for(const cachedFile in data) { - compilation.assets[cachedFile] = data[cachedFile]; - if(cachedFile !== file) - chunk.files.push(cachedFile); + chunk.files.forEach(file => { + if(matchObject(file)) { + const task = getTaskForFile(file, chunk, options, compilation); + + if(task) { + const modules = task.sourceMap.sources.map(source => { + const module = compilation.findModule(source); + return module || source; + }); + + for(const module of modules) { + if(!moduleToSourceNameMapping.get(module)) { + moduleToSourceNameMapping.set(module, ModuleFilenameHelpers.createFilename(module, moduleFilenameTemplate, requestShortener)); + } + } + + task.modules = modules; + + tasks.push(task); } - return; } - let source, sourceMap; - if(asset.sourceAndMap) { - const sourceAndMap = asset.sourceAndMap(options); - sourceMap = sourceAndMap.map; - source = sourceAndMap.source; - } else { - sourceMap = asset.map(options); - source = asset.source(); - } - if(sourceMap) { - return { - chunk, - file, - asset, - source, - sourceMap - }; - } - }).filter(Boolean).map(task => { - const modules = task.sourceMap.sources.map(source => { - const module = compilation.findModule(source); - return module || source; - }); - const moduleFilenames = modules.map(module => ModuleFilenameHelpers.createFilename(module, moduleFilenameTemplate, requestShortener)); - task.modules = modules; - task.moduleFilenames = moduleFilenames; - return task; - }).forEach(task => { - allModules = allModules.concat(task.modules); - allModuleFilenames = allModuleFilenames.concat(task.moduleFilenames); - tasks.push(task); }); }); - allModuleFilenames = ModuleFilenameHelpers.replaceDuplicates(allModuleFilenames, (filename, i) => ModuleFilenameHelpers.createFilename(allModules[i], fallbackModuleFilenameTemplate, requestShortener), (ai, bi) => { - let a = allModules[ai]; - let b = allModules[bi]; - a = !a ? "" : typeof a === "string" ? a : a.identifier(); - b = !b ? "" : typeof b === "string" ? b : b.identifier(); - return a.length - b.length; - }); - allModuleFilenames = ModuleFilenameHelpers.replaceDuplicates(allModuleFilenames, (filename, i, n) => { - for(let j = 0; j < n; j++) - filename += "*"; - return filename; - }); - tasks.forEach(task => { - task.moduleFilenames = allModuleFilenames.slice(0, task.moduleFilenames.length); - allModuleFilenames = allModuleFilenames.slice(task.moduleFilenames.length); + + const usedNamesSet = new Set(moduleToSourceNameMapping.values()); + const conflictDetectionSet = new Set(); + + // all modules in defined order (longest identifier first) + const allModules = Array.from(moduleToSourceNameMapping.keys()).sort((a, b) => { + const ai = typeof a === "string" ? a : a.identifier(); + const bi = typeof b === "string" ? b : b.identifier(); + return ai.length - bi.length; }); + + // find modules with conflicting source names + for(const module of allModules) { + let sourceName = moduleToSourceNameMapping.get(module); + let hasName = conflictDetectionSet.has(sourceName); + if(!hasName) { + conflictDetectionSet.add(sourceName); + continue; + } + + // try the fallback name first + sourceName = ModuleFilenameHelpers.createFilename(module, fallbackModuleFilenameTemplate, requestShortener); + hasName = usedNamesSet.has(sourceName); + if(!hasName) { + moduleToSourceNameMapping.set(module, sourceName); + usedNamesSet.add(sourceName); + continue; + } + + // elsewise just append stars until we have a valid name + while(hasName) { + sourceName += "*"; + hasName = usedNamesSet.has(sourceName); + } + moduleToSourceNameMapping.set(module, sourceName); + usedNamesSet.add(sourceName); + } tasks.forEach(function(task) { const chunk = task.chunk; const file = task.file; const asset = task.asset; const sourceMap = task.sourceMap; const source = task.source; - const moduleFilenames = task.moduleFilenames; const modules = task.modules; + const moduleFilenames = modules.map(m => moduleToSourceNameMapping.get(m)); sourceMap.sources = moduleFilenames; if(sourceMap.sourcesContent && !options.noSources) { sourceMap.sourcesContent = sourceMap.sourcesContent.map((content, i) => `${content}\n\n\n${ModuleFilenameHelpers.createFooter(modules[i], requestShortener)}`); @@ -131,6 +168,7 @@ class SourceMapDevToolPlugin { if(currentSourceMappingURLComment !== false && /\.css($|\?)/i.test(file)) { currentSourceMappingURLComment = currentSourceMappingURLComment.replace(/^\n\/\/(.*)$/, "\n/*$1*/"); } + const sourceMapString = JSON.stringify(sourceMap); if(sourceMapFilename) { let filename = file; let query = ""; @@ -139,22 +177,25 @@ class SourceMapDevToolPlugin { query = filename.substr(idx); filename = filename.substr(0, idx); } - const sourceMapFile = compilation.getPath(sourceMapFilename, { + let sourceMapFile = compilation.getPath(sourceMapFilename, { chunk, filename, query, basename: basename(filename) }); + if(sourceMapFile.indexOf("[contenthash]") !== -1) { + sourceMapFile = sourceMapFile.replace(/\[contenthash\]/g, crypto.createHash("md5").update(sourceMapString).digest("hex")); + } const sourceMapUrl = path.relative(path.dirname(file), sourceMapFile).replace(/\\/g, "/"); if(currentSourceMappingURLComment !== false) { asset.__SourceMapDevToolData[file] = compilation.assets[file] = new ConcatSource(new RawSource(source), currentSourceMappingURLComment.replace(/\[url\]/g, sourceMapUrl)); } - asset.__SourceMapDevToolData[sourceMapFile] = compilation.assets[sourceMapFile] = new RawSource(JSON.stringify(sourceMap)); + asset.__SourceMapDevToolData[sourceMapFile] = compilation.assets[sourceMapFile] = new RawSource(sourceMapString); chunk.files.push(sourceMapFile); } else { asset.__SourceMapDevToolData[file] = compilation.assets[file] = new ConcatSource(new RawSource(source), currentSourceMappingURLComment - .replace(/\[map\]/g, () => JSON.stringify(sourceMap)) - .replace(/\[url\]/g, () => `data:application/json;charset=utf-8;base64,${new Buffer(JSON.stringify(sourceMap), "utf-8").toString("base64")}`) // eslint-disable-line + .replace(/\[map\]/g, () => sourceMapString) + .replace(/\[url\]/g, () => `data:application/json;charset=utf-8;base64,${new Buffer(sourceMapString, "utf-8").toString("base64")}`) // eslint-disable-line ); } }); diff --git a/node_modules/webpack/lib/Stats.js b/node_modules/webpack/lib/Stats.js index 0b88faa64..16c191714 100644 --- a/node_modules/webpack/lib/Stats.js +++ b/node_modules/webpack/lib/Stats.js @@ -7,8 +7,13 @@ const RequestShortener = require("./RequestShortener"); const SizeFormatHelpers = require("./SizeFormatHelpers"); const formatLocation = require("./formatLocation"); +const identifierUtils = require("./util/identifier"); -const optionOrFallback = (optionValue, fallbackValue) => optionValue !== undefined ? optionValue : fallbackValue; +const optionsOrFallback = function() { + let optionValues = []; + optionValues.push.apply(optionValues, arguments); + return optionValues.find(optionValue => typeof optionValue !== "undefined"); +}; class Stats { constructor(compilation) { @@ -75,50 +80,66 @@ class Stats { options = {}; } + const optionOrLocalFallback = (v, def) => + typeof v !== "undefined" ? v : + typeof options.all !== "undefined" ? options.all : def; + + const testAgainstGivenOption = (item) => { + if(typeof item === "string") { + const regExp = new RegExp(`[\\\\/]${item.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")}([\\\\/]|$|!|\\?)`); // eslint-disable-line no-useless-escape + return ident => regExp.test(ident); + } + if(item && typeof item === "object" && typeof item.test === "function") + return ident => item.test(ident); + if(typeof item === "function") + return item; + }; + const compilation = this.compilation; - const requestShortener = new RequestShortener(optionOrFallback(options.context, process.cwd())); - const showPerformance = optionOrFallback(options.performance, true); - const showHash = optionOrFallback(options.hash, true); - const showVersion = optionOrFallback(options.version, true); - const showTimings = optionOrFallback(options.timings, true); - const showAssets = optionOrFallback(options.assets, true); - const showEntrypoints = optionOrFallback(options.entrypoints, !forToString); - const showChunks = optionOrFallback(options.chunks, true); - const showChunkModules = optionOrFallback(options.chunkModules, !!forToString); - const showChunkOrigins = optionOrFallback(options.chunkOrigins, !forToString); - const showModules = optionOrFallback(options.modules, !forToString); - const showDepth = optionOrFallback(options.depth, !forToString); - const showCachedModules = optionOrFallback(options.cached, true); - const showCachedAssets = optionOrFallback(options.cachedAssets, true); - const showReasons = optionOrFallback(options.reasons, !forToString); - const showUsedExports = optionOrFallback(options.usedExports, !forToString); - const showProvidedExports = optionOrFallback(options.providedExports, !forToString); - const showChildren = optionOrFallback(options.children, true); - const showSource = optionOrFallback(options.source, !forToString); - const showModuleTrace = optionOrFallback(options.moduleTrace, true); - const showErrors = optionOrFallback(options.errors, true); - const showErrorDetails = optionOrFallback(options.errorDetails, !forToString); - const showWarnings = optionOrFallback(options.warnings, true); - const warningsFilter = optionOrFallback(options.warningsFilter, null); - const showPublicPath = optionOrFallback(options.publicPath, !forToString); - const excludeModules = [].concat(optionOrFallback(options.exclude, [])).map(str => { - if(typeof str !== "string") return str; - return new RegExp(`[\\\\/]${str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")}([\\\\/]|$|!|\\?)`); - }); - const maxModules = optionOrFallback(options.maxModules, forToString ? 15 : Infinity); - const sortModules = optionOrFallback(options.modulesSort, "id"); - const sortChunks = optionOrFallback(options.chunksSort, "id"); - const sortAssets = optionOrFallback(options.assetsSort, ""); + const context = optionsOrFallback(options.context, process.cwd()); + const requestShortener = new RequestShortener(context); + const showPerformance = optionOrLocalFallback(options.performance, true); + const showHash = optionOrLocalFallback(options.hash, true); + const showVersion = optionOrLocalFallback(options.version, true); + const showTimings = optionOrLocalFallback(options.timings, true); + const showAssets = optionOrLocalFallback(options.assets, true); + const showEntrypoints = optionOrLocalFallback(options.entrypoints, !forToString); + const showChunks = optionOrLocalFallback(options.chunks, !forToString); + const showChunkModules = optionOrLocalFallback(options.chunkModules, true); + const showChunkOrigins = optionOrLocalFallback(options.chunkOrigins, !forToString); + const showModules = optionOrLocalFallback(options.modules, true); + const showDepth = optionOrLocalFallback(options.depth, !forToString); + const showCachedModules = optionOrLocalFallback(options.cached, true); + const showCachedAssets = optionOrLocalFallback(options.cachedAssets, true); + const showReasons = optionOrLocalFallback(options.reasons, !forToString); + const showUsedExports = optionOrLocalFallback(options.usedExports, !forToString); + const showProvidedExports = optionOrLocalFallback(options.providedExports, !forToString); + const showOptimizationBailout = optionOrLocalFallback(options.optimizationBailout, !forToString); + const showChildren = optionOrLocalFallback(options.children, true); + const showSource = optionOrLocalFallback(options.source, !forToString); + const showModuleTrace = optionOrLocalFallback(options.moduleTrace, true); + const showErrors = optionOrLocalFallback(options.errors, true); + const showErrorDetails = optionOrLocalFallback(options.errorDetails, !forToString); + const showWarnings = optionOrLocalFallback(options.warnings, true); + const warningsFilter = optionsOrFallback(options.warningsFilter, null); + const showPublicPath = optionOrLocalFallback(options.publicPath, !forToString); + const excludeModules = [].concat(optionsOrFallback(options.excludeModules, options.exclude, [])).map(testAgainstGivenOption); + const excludeAssets = [].concat(optionsOrFallback(options.excludeAssets, [])).map(testAgainstGivenOption); + const maxModules = optionsOrFallback(options.maxModules, forToString ? 15 : Infinity); + const sortModules = optionsOrFallback(options.modulesSort, "id"); + const sortChunks = optionsOrFallback(options.chunksSort, "id"); + const sortAssets = optionsOrFallback(options.assetsSort, ""); + + if(!showCachedModules) { + excludeModules.push((ident, module) => !module.built); + } const createModuleFilter = () => { let i = 0; return module => { - if(!showCachedModules && !module.built) { - return false; - } if(excludeModules.length > 0) { const ident = requestShortener.shorten(module.resource); - const excluded = excludeModules.some(regExp => regExp.test(ident)); + const excluded = excludeModules.some(fn => fn(ident, module)); if(excluded) return false; } @@ -126,6 +147,18 @@ class Stats { }; }; + const createAssetFilter = () => { + return asset => { + if(excludeAssets.length > 0) { + const ident = asset.name; + const excluded = excludeAssets.some(fn => fn(ident, asset)); + if(excluded) + return false; + } + return showCachedAssets || asset.emitted; + }; + }; + const sortByFieldAndOrder = (fieldKey, a, b) => { if(a[fieldKey] === null && b[fieldKey] === null) return 0; if(a[fieldKey] === null) return 1; @@ -217,8 +250,9 @@ class Stats { } if(showAssets) { const assetsByFile = {}; + const compilationAssets = Object.keys(compilation.assets); obj.assetsByChunkName = {}; - obj.assets = Object.keys(compilation.assets).map(asset => { + obj.assets = compilationAssets.map(asset => { const obj = { name: asset, size: compilation.assets[asset].size(), @@ -233,7 +267,8 @@ class Stats { assetsByFile[asset] = obj; return obj; - }).filter(asset => showCachedAssets || asset.emitted); + }).filter(createAssetFilter()); + obj.filteredAssets = compilationAssets.length - obj.assets.length; compilation.chunks.forEach(chunk => { chunk.files.forEach(asset => { @@ -280,7 +315,7 @@ class Stats { built: !!module.built, optional: !!module.optional, prefetched: !!module.prefetched, - chunks: module.chunks.map(chunk => chunk.id), + chunks: module.mapChunks(chunk => chunk.id), assets: Object.keys(module.assets || {}), issuer: module.issuer && module.issuer.identifier(), issuerId: module.issuer && module.issuer.id, @@ -311,6 +346,12 @@ class Stats { if(showProvidedExports) { obj.providedExports = Array.isArray(module.providedExports) ? module.providedExports : null; } + if(showOptimizationBailout) { + obj.optimizationBailout = module.optimizationBailout.map(item => { + if(typeof item === "function") return item(requestShortener); + return item; + }); + } if(showDepth) { obj.depth = module.depth; } @@ -328,19 +369,19 @@ class Stats { entry: chunk.hasRuntime(), recorded: chunk.recorded, extraAsync: !!chunk.extraAsync, - size: chunk.modules.reduce((size, module) => size + module.size(), 0), + size: chunk.mapModules(m => m.size()).reduce((size, moduleSize) => size + moduleSize, 0), names: chunk.name ? [chunk.name] : [], files: chunk.files.slice(), hash: chunk.renderedHash, parents: chunk.parents.map(c => c.id) }; if(showChunkModules) { - obj.modules = chunk.modules - .slice() + obj.modules = chunk + .getModules() .sort(sortByField("depth")) .filter(createModuleFilter()) .map(fnModule); - obj.filteredModules = chunk.modules.length - obj.modules.length; + obj.filteredModules = chunk.getNumberOfModules() - obj.modules.length; obj.modules.sort(sortByField(sortModules)); } if(showChunkOrigins) { @@ -373,7 +414,8 @@ class Stats { const obj = new Stats(child).toJson(childOptions, forToString); delete obj.hash; delete obj.version; - obj.name = child.name; + if(child.name) + obj.name = identifierUtils.makePathsRelative(context, child.name, compilation.cache); return obj; }); } @@ -388,7 +430,7 @@ class Stats { options = {}; } - const useColors = optionOrFallback(options.colors, false); + const useColors = optionsOrFallback(options.colors, false); const obj = this.toJson(options, true); @@ -555,6 +597,16 @@ class Stats { }); table(t, "rrrlll"); } + if(obj.filteredAssets > 0) { + colors.normal(" "); + if(obj.assets.length > 0) + colors.normal("+ "); + colors.normal(obj.filteredAssets); + if(obj.assets.length > 0) + colors.normal(" hidden"); + colors.normal(obj.filteredAssets !== 1 ? " assets" : " asset"); + newline(); + } if(obj.entrypoints) { Object.keys(obj.entrypoints).forEach(name => { const ep = obj.entrypoints[name]; @@ -623,19 +675,29 @@ class Stats { const processModuleContent = (module, prefix) => { if(Array.isArray(module.providedExports)) { colors.normal(prefix); - colors.cyan(`[exports: ${module.providedExports.join(", ")}]`); + if(module.providedExports.length === 0) + colors.cyan("[no exports]"); + else + colors.cyan(`[exports: ${module.providedExports.join(", ")}]`); newline(); } if(module.usedExports !== undefined) { if(module.usedExports !== true) { colors.normal(prefix); - if(module.usedExports === false) + if(module.usedExports === false || module.usedExports.length === 0) colors.cyan("[no exports used]"); else colors.cyan(`[only some exports used: ${module.usedExports.join(", ")}]`); newline(); } } + if(Array.isArray(module.optimizationBailout)) { + module.optimizationBailout.forEach(item => { + colors.normal(prefix); + colors.yellow(item); + newline(); + }); + } if(module.reasons) { module.reasons.forEach(reason => { colors.normal(prefix); @@ -659,9 +721,9 @@ class Stats { const path = []; let current = module; while(current.issuer) { - path.unshift(current = current.issuer); + path.push(current = current.issuer); } - path.forEach(module => { + path.reverse().forEach(module => { colors.normal("["); colors.normal(module.id); colors.normal("] "); @@ -685,6 +747,35 @@ class Stats { } }; + const processModulesList = (obj, prefix) => { + if(obj.modules) { + obj.modules.forEach(module => { + colors.normal(prefix); + if(module.id < 1000) colors.normal(" "); + if(module.id < 100) colors.normal(" "); + if(module.id < 10) colors.normal(" "); + colors.normal("["); + colors.normal(module.id); + colors.normal("] "); + colors.bold(module.name || module.identifier); + processModuleAttributes(module); + newline(); + processModuleContent(module, prefix + " "); + }); + if(obj.filteredModules > 0) { + colors.normal(prefix); + colors.normal(" "); + if(obj.modules.length > 0) + colors.normal(" + "); + colors.normal(obj.filteredModules); + if(obj.modules.length > 0) + colors.normal(" hidden"); + colors.normal(obj.filteredModules !== 1 ? " modules" : " module"); + newline(); + } + } + }; + if(obj.chunks) { obj.chunks.forEach(chunk => { colors.normal("chunk "); @@ -746,45 +837,11 @@ class Stats { newline(); }); } - if(chunk.modules) { - chunk.modules.forEach(module => { - colors.normal(" "); - if(module.id < 1000) colors.normal(" "); - if(module.id < 100) colors.normal(" "); - if(module.id < 10) colors.normal(" "); - colors.normal("["); - colors.normal(module.id); - colors.normal("] "); - colors.bold(module.name); - processModuleAttributes(module); - newline(); - processModuleContent(module, " "); - }); - if(chunk.filteredModules > 0) { - colors.normal(` + ${chunk.filteredModules} hidden modules`); - newline(); - } - } + processModulesList(chunk, " "); }); } - if(obj.modules) { - obj.modules.forEach(module => { - if(module.id < 1000) colors.normal(" "); - if(module.id < 100) colors.normal(" "); - if(module.id < 10) colors.normal(" "); - colors.normal("["); - colors.normal(module.id); - colors.normal("] "); - colors.bold(module.name || module.identifier); - processModuleAttributes(module); - newline(); - processModuleContent(module, " "); - }); - if(obj.filteredModules > 0) { - colors.normal(` + ${obj.filteredModules} hidden modules`); - newline(); - } - } + + processModulesList(obj, ""); if(obj._showWarnings && obj.warnings) { obj.warnings.forEach(warning => { @@ -827,51 +884,63 @@ class Stats { } static presetToOptions(name) { - //Accepted values: none, errors-only, minimal, normal, verbose - //Any other falsy value will behave as 'none', truthy values as 'normal' - const pn = (typeof name === "string") && name.toLowerCase() || name; - if(pn === "none" || !pn) { - return { - hash: false, - version: false, - timings: false, - assets: false, - entrypoints: false, - chunks: false, - chunkModules: false, - modules: false, - reasons: false, - depth: false, - usedExports: false, - providedExports: false, - children: false, - source: false, - errors: false, - errorDetails: false, - warnings: false, - publicPath: false, - performance: false - }; - } else { - return { - hash: pn !== "errors-only" && pn !== "minimal", - version: pn === "verbose", - timings: pn !== "errors-only" && pn !== "minimal", - assets: pn === "verbose", - entrypoints: pn === "verbose", - chunks: pn !== "errors-only", - chunkModules: pn === "verbose", - //warnings: pn !== "errors-only", - errorDetails: pn !== "errors-only" && pn !== "minimal", - reasons: pn === "verbose", - depth: pn === "verbose", - usedExports: pn === "verbose", - providedExports: pn === "verbose", - colors: true, - performance: true - }; + // Accepted values: none, errors-only, minimal, normal, detailed, verbose + // Any other falsy value will behave as 'none', truthy values as 'normal' + const pn = (typeof name === "string") && name.toLowerCase() || name || "none"; + switch(pn) { + case "none": + return { + all: false + }; + case "verbose": + return { + entrypoints: true, + modules: false, + chunks: true, + chunkModules: true, + chunkOrigins: true, + depth: true, + reasons: true, + usedExports: true, + providedExports: true, + optimizationBailout: true, + errorDetails: true, + publicPath: true, + exclude: () => false, + maxModules: Infinity, + }; + case "detailed": + return { + entrypoints: true, + chunks: true, + chunkModules: false, + chunkOrigins: true, + depth: true, + usedExports: true, + providedExports: true, + optimizationBailout: true, + errorDetails: true, + publicPath: true, + exclude: () => false, + maxModules: Infinity, + }; + case "minimal": + return { + all: false, + modules: true, + maxModules: 0, + errors: true, + warnings: true, + }; + case "errors-only": + return { + all: false, + errors: true, + moduleTrace: true, + }; + default: + return {}; } - } static getChildOptions(options, idx) { diff --git a/node_modules/webpack/lib/Template.js b/node_modules/webpack/lib/Template.js index 461a03679..b3e17a823 100644 --- a/node_modules/webpack/lib/Template.js +++ b/node_modules/webpack/lib/Template.js @@ -28,7 +28,7 @@ module.exports = class Template extends Tapable { static toPath(str) { if(typeof str !== "string") return ""; - return str.replace(/[^a-zA-Z0-9_!§$()=\-\^°]+/g, "-").replace(/^-|-$/, ""); + return str.replace(/[^a-zA-Z0-9_!§$()=\-^°]+/g, "-").replace(/^-|-$/, ""); } // map number to a single character a-z, A-Z or <_ + number> if number is too big @@ -99,12 +99,12 @@ module.exports = class Template extends Tapable { renderChunkModules(chunk, moduleTemplate, dependencyTemplates, prefix) { if(!prefix) prefix = ""; var source = new ConcatSource(); - if(chunk.modules.length === 0) { + if(chunk.getNumberOfModules() === 0) { source.add("[]"); return source; } var removedModules = chunk.removedModules; - var allModules = chunk.modules.map(function(module) { + var allModules = chunk.mapModules(function(module) { return { id: module.id, source: moduleTemplate.render(module, dependencyTemplates, chunk) @@ -118,7 +118,7 @@ module.exports = class Template extends Tapable { }); }); } - var bounds = this.getModulesArrayBounds(chunk.modules); + var bounds = this.getModulesArrayBounds(allModules); if(bounds) { // Render a spare array diff --git a/node_modules/webpack/lib/UmdMainTemplatePlugin.js b/node_modules/webpack/lib/UmdMainTemplatePlugin.js index 81873305a..3ddb98d23 100644 --- a/node_modules/webpack/lib/UmdMainTemplatePlugin.js +++ b/node_modules/webpack/lib/UmdMainTemplatePlugin.js @@ -23,7 +23,17 @@ function accessorAccess(base, accessor) { class UmdMainTemplatePlugin { constructor(name, options) { - this.name = name; + if(typeof name === "object" && !Array.isArray(name)) { + this.name = name.root || name.amd || name.commonjs; + this.names = name; + } else { + this.name = name; + this.names = { + commonjs: name, + root: name, + amd: name + }; + } this.optionalAmdExternalAsGlobal = options.optionalAmdExternalAsGlobal; this.namedDefine = options.namedDefine; this.auxiliaryComment = options.auxiliaryComment; @@ -31,8 +41,8 @@ class UmdMainTemplatePlugin { apply(compilation) { const mainTemplate = compilation.mainTemplate; - compilation.templatesPlugin("render-with-entry", function(source, chunk, hash) { - let externals = chunk.modules.filter(m => m.external); + compilation.templatesPlugin("render-with-entry", (source, chunk, hash) => { + let externals = chunk.getModules().filter(m => m.external); const optionalExternals = []; let requiredExternals = []; if(this.optionalAmdExternalAsGlobal) { @@ -72,6 +82,7 @@ class UmdMainTemplatePlugin { let expr; let request = m.request; if(typeof request === "object") request = request[type]; + if(typeof request === "undefined") throw new Error("Missing external configuration for type:" + type); if(Array.isArray(request)) { expr = `require(${JSON.stringify(request[0])})${accessorToObjectAccess(request.slice(1))}`; } else @@ -124,16 +135,16 @@ class UmdMainTemplatePlugin { ) + " else if(typeof define === 'function' && define.amd)\n" + (requiredExternals.length > 0 ? - (this.name && this.namedDefine === true ? - " define(" + libraryName(this.name) + ", " + externalsDepsArray(requiredExternals) + ", " + amdFactory + ");\n" : + (this.names.amd && this.namedDefine === true ? + " define(" + libraryName(this.names.amd) + ", " + externalsDepsArray(requiredExternals) + ", " + amdFactory + ");\n" : " define(" + externalsDepsArray(requiredExternals) + ", " + amdFactory + ");\n" ) : - (this.name && this.namedDefine === true ? - " define(" + libraryName(this.name) + ", [], " + amdFactory + ");\n" : + (this.names.amd && this.namedDefine === true ? + " define(" + libraryName(this.names.amd) + ", [], " + amdFactory + ");\n" : " define([], " + amdFactory + ");\n" ) ) + - (this.name ? + (this.names.root || this.names.commonjs ? (this.auxiliaryComment && typeof this.auxiliaryComment === "string" ? " //" + this.auxiliaryComment + "\n" : @@ -142,7 +153,7 @@ class UmdMainTemplatePlugin { "" ) + " else if(typeof exports === 'object')\n" + - " exports[" + libraryName(this.name) + "] = factory(" + externalsRequireArray("commonjs") + ");\n" + + " exports[" + libraryName(this.names.commonjs || this.names.root) + "] = factory(" + externalsRequireArray("commonjs") + ");\n" + (this.auxiliaryComment && typeof this.auxiliaryComment === "string" ? " //" + this.auxiliaryComment + "\n" : @@ -151,7 +162,7 @@ class UmdMainTemplatePlugin { "" ) + " else\n" + - " " + replaceKeys(accessorAccess("root", this.name)) + " = factory(" + externalsRootArray(externals) + ");\n" : + " " + replaceKeys(accessorAccess("root", this.names.root || this.names.commonjs)) + " = factory(" + externalsRootArray(externals) + ");\n" : " else {\n" + (externals.length > 0 ? " var a = typeof exports === 'object' ? factory(" + externalsRequireArray("commonjs") + ") : factory(" + externalsRootArray(externals) + ");\n" : @@ -161,15 +172,19 @@ class UmdMainTemplatePlugin { " }\n" ) + "})(this, function(" + externalsArguments(externals) + ") {\nreturn ", "webpack/universalModuleDefinition"), source, ";\n})"); - }.bind(this)); - mainTemplate.plugin("global-hash-paths", function(paths) { - if(this.name) paths = paths.concat(this.name); + }); + mainTemplate.plugin("global-hash-paths", (paths) => { + if(this.names.root) paths = paths.concat(this.names.root); + if(this.names.amd) paths = paths.concat(this.names.amd); + if(this.names.commonjs) paths = paths.concat(this.names.commonjs); return paths; - }.bind(this)); - mainTemplate.plugin("hash", function(hash) { + }); + mainTemplate.plugin("hash", (hash) => { hash.update("umd"); - hash.update(`${this.name}`); - }.bind(this)); + hash.update(`${this.names.root}`); + hash.update(`${this.names.amd}`); + hash.update(`${this.names.commonjs}`); + }); } } diff --git a/node_modules/webpack/lib/WebpackOptionsApply.js b/node_modules/webpack/lib/WebpackOptionsApply.js index e9231447c..ebddba717 100644 --- a/node_modules/webpack/lib/WebpackOptionsApply.js +++ b/node_modules/webpack/lib/WebpackOptionsApply.js @@ -73,7 +73,7 @@ class WebpackOptionsApply extends OptionsApply { new JsonpTemplatePlugin(options.output), new FunctionModulePlugin(options.output), new NodeSourcePlugin(options.node), - new LoaderTargetPlugin("web") + new LoaderTargetPlugin(options.target) ); break; case "webworker": @@ -84,7 +84,7 @@ class WebpackOptionsApply extends OptionsApply { new WebWorkerTemplatePlugin(), new FunctionModulePlugin(options.output), new NodeSourcePlugin(options.node), - new LoaderTargetPlugin("webworker") + new LoaderTargetPlugin(options.target) ); break; } @@ -110,7 +110,7 @@ class WebpackOptionsApply extends OptionsApply { new FunctionModulePlugin(options.output), new NodeTargetPlugin(), new ExternalsPlugin("commonjs", "nw.gui"), - new LoaderTargetPlugin("node-webkit") + new LoaderTargetPlugin(options.target) ); break; case "atom": @@ -187,7 +187,7 @@ class WebpackOptionsApply extends OptionsApply { if(options.output.library || options.output.libraryTarget !== "var") { let LibraryTemplatePlugin = require("./LibraryTemplatePlugin"); - compiler.apply(new LibraryTemplatePlugin(options.output.library, options.output.libraryTarget, options.output.umdNamedDefine, options.output.auxiliaryComment || "")); + compiler.apply(new LibraryTemplatePlugin(options.output.library, options.output.libraryTarget, options.output.umdNamedDefine, options.output.auxiliaryComment || "", options.output.libraryExport)); } if(options.externals) { ExternalsPlugin = require("./ExternalsPlugin"); @@ -247,7 +247,7 @@ class WebpackOptionsApply extends OptionsApply { new UseStrictPlugin(), new RequireIncludePlugin(), new RequireEnsurePlugin(), - new RequireContextPlugin(options.resolve.modules, options.resolve.extensions), + new RequireContextPlugin(options.resolve.modules, options.resolve.extensions, options.resolve.mainFiles), new ImportPlugin(options.module), new SystemPlugin(options.module) ); diff --git a/node_modules/webpack/lib/WebpackOptionsDefaulter.js b/node_modules/webpack/lib/WebpackOptionsDefaulter.js index 48d8d472d..24bb42321 100644 --- a/node_modules/webpack/lib/WebpackOptionsDefaulter.js +++ b/node_modules/webpack/lib/WebpackOptionsDefaulter.js @@ -28,6 +28,7 @@ class WebpackOptionsDefaulter extends OptionsDefaulter { this.set("module.wrappedContextRecursive", true); this.set("module.wrappedContextCritical", false); this.set("module.strictExportPresence", false); + this.set("module.strictThisContextOnImports", false); this.set("module.unsafeCache", true); @@ -84,6 +85,7 @@ class WebpackOptionsDefaulter extends OptionsDefaulter { this.set("resolve.unsafeCache", true); this.set("resolve.modules", ["node_modules"]); this.set("resolve.extensions", [".js", ".json"]); + this.set("resolve.mainFiles", ["index"]); this.set("resolve.aliasFields", "make", (options) => { if(options.target === "web" || options.target === "webworker") return ["browser"]; @@ -96,10 +98,17 @@ class WebpackOptionsDefaulter extends OptionsDefaulter { else return ["module", "main"]; }); + this.set("resolve.cacheWithContext", "make", (options) => { + return Array.isArray(options.resolve.plugins) && options.resolve.plugins.length > 0; + }); this.set("resolveLoader", {}); this.set("resolveLoader.unsafeCache", true); this.set("resolveLoader.mainFields", ["loader", "main"]); this.set("resolveLoader.extensions", [".js", ".json"]); + this.set("resolveLoader.mainFiles", ["index"]); + this.set("resolveLoader.cacheWithContext", "make", (options) => { + return Array.isArray(options.resolveLoader.plugins) && options.resolveLoader.plugins.length > 0; + }); } } diff --git a/node_modules/webpack/lib/dependencies/AMDPlugin.js b/node_modules/webpack/lib/dependencies/AMDPlugin.js index d1d5cf09e..944241c23 100644 --- a/node_modules/webpack/lib/dependencies/AMDPlugin.js +++ b/node_modules/webpack/lib/dependencies/AMDPlugin.js @@ -82,8 +82,8 @@ class AMDPlugin { parser.state.current.addVariable("__webpack_amd_options__", JSON.stringify(amdOptions))); parser.plugin("evaluate typeof define.amd", ParserHelpers.evaluateToString(typeof amdOptions)); parser.plugin("evaluate typeof require.amd", ParserHelpers.evaluateToString(typeof amdOptions)); - parser.plugin("evaluate Identifier define.amd", ParserHelpers.evaluateToBoolean(true)); - parser.plugin("evaluate Identifier require.amd", ParserHelpers.evaluateToBoolean(true)); + parser.plugin("evaluate Identifier define.amd", ParserHelpers.evaluateToIdentifier("define.amd", true)); + parser.plugin("evaluate Identifier require.amd", ParserHelpers.evaluateToIdentifier("require.amd", true)); parser.plugin("typeof define", ParserHelpers.toConstantDependency(JSON.stringify("function"))); parser.plugin("evaluate typeof define", ParserHelpers.evaluateToString("function")); parser.plugin("can-rename define", ParserHelpers.approve); diff --git a/node_modules/webpack/lib/dependencies/CommonJsPlugin.js b/node_modules/webpack/lib/dependencies/CommonJsPlugin.js index e514fd99e..218cddb3d 100644 --- a/node_modules/webpack/lib/dependencies/CommonJsPlugin.js +++ b/node_modules/webpack/lib/dependencies/CommonJsPlugin.js @@ -54,8 +54,9 @@ class CommonJsPlugin { const requireExpressions = ["require", "require.resolve", "require.resolveWeak"]; for(let expression of requireExpressions) { - parser.plugin(`typeof ${expression}`, ParserHelpers.toConstantDependency("function")); + parser.plugin(`typeof ${expression}`, ParserHelpers.toConstantDependency(JSON.stringify("function"))); parser.plugin(`evaluate typeof ${expression}`, ParserHelpers.evaluateToString("function")); + parser.plugin(`evaluate Identifier ${expression}`, ParserHelpers.evaluateToIdentifier(expression, true)); } parser.plugin("evaluate typeof module", ParserHelpers.evaluateToString("object")); diff --git a/node_modules/webpack/lib/dependencies/DelegatedExportsDependency.js b/node_modules/webpack/lib/dependencies/DelegatedExportsDependency.js new file mode 100644 index 000000000..ad36acbe4 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/DelegatedExportsDependency.js @@ -0,0 +1,33 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; +const NullDependency = require("./NullDependency"); + +class DelegatedExportsDependency extends NullDependency { + constructor(originModule, exports) { + super(); + this.originModule = originModule; + this.exports = exports; + } + + get type() { + return "delegated exports"; + } + + getReference() { + return { + module: this.originModule, + importedNames: true + }; + } + + getExports() { + return { + exports: this.exports + }; + } +} + +module.exports = DelegatedExportsDependency; diff --git a/node_modules/webpack/lib/dependencies/DepBlockHelpers.js b/node_modules/webpack/lib/dependencies/DepBlockHelpers.js index d4a4014ec..c1e48a3a5 100644 --- a/node_modules/webpack/lib/dependencies/DepBlockHelpers.js +++ b/node_modules/webpack/lib/dependencies/DepBlockHelpers.js @@ -2,10 +2,12 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -var DepBlockHelpers = exports; +"use strict"; -DepBlockHelpers.getLoadDepBlockWrapper = function(depBlock, outputOptions, requestShortener, name) { - var promiseCode = DepBlockHelpers.getDepBlockPromise(depBlock, outputOptions, requestShortener, name); +const DepBlockHelpers = exports; + +DepBlockHelpers.getLoadDepBlockWrapper = (depBlock, outputOptions, requestShortener, name) => { + const promiseCode = DepBlockHelpers.getDepBlockPromise(depBlock, outputOptions, requestShortener, name); return [ promiseCode + ".then(", ").catch(", @@ -13,24 +15,19 @@ DepBlockHelpers.getLoadDepBlockWrapper = function(depBlock, outputOptions, reque ]; }; -DepBlockHelpers.getDepBlockPromise = function(depBlock, outputOptions, requestShortener, name) { +DepBlockHelpers.getDepBlockPromise = (depBlock, outputOptions, requestShortener, name) => { if(depBlock.chunks) { - var chunks = depBlock.chunks.filter(function(chunk) { - return !chunk.hasRuntime() && chunk.id !== null; - }); + const chunks = depBlock.chunks.filter(chunk => !chunk.hasRuntime() && chunk.id !== null); + const pathChunkCheck = outputOptions.pathinfo && depBlock.chunkName; + const shortChunkName = requestShortener.shorten(depBlock.chunkName); + const chunkReason = asComment(depBlock.chunkReason); + const requireChunkId = chunk => "__webpack_require__.e(" + JSON.stringify(chunk.id) + ")"; + name = asComment(name); if(chunks.length === 1) { - var chunk = chunks[0]; - return "__webpack_require__.e" + asComment(name) + "(" + JSON.stringify(chunk.id) + "" + - (outputOptions.pathinfo && depBlock.chunkName ? "/*! " + requestShortener.shorten(depBlock.chunkName) + " */" : "") + - asComment(depBlock.chunkReason) + ")"; + const chunkId = JSON.stringify(chunks[0].id); + return `__webpack_require__.e${name}(${chunkId}${pathChunkCheck ? "/*! " + shortChunkName + " */" : ""}${chunkReason})`; } else if(chunks.length > 0) { - return "Promise.all" + asComment(name) + "(" + - (outputOptions.pathinfo && depBlock.chunkName ? "/*! " + requestShortener.shorten(depBlock.chunkName) + " */" : "") + - "[" + - chunks.map(function(chunk) { - return "__webpack_require__.e(" + JSON.stringify(chunk.id) + ")"; - }).join(", ") + - "])"; + return `Promise.all${name}(${pathChunkCheck ? "/*! " + shortChunkName + " */" : ""}[${chunks.map(requireChunkId).join(", ")}])`; } } return "new Promise(function(resolve) { resolve(); })"; @@ -38,5 +35,5 @@ DepBlockHelpers.getDepBlockPromise = function(depBlock, outputOptions, requestSh function asComment(str) { if(!str) return ""; - return "/* " + str + " */"; + return `/* ${str} */`; } diff --git a/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js b/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js index 9407499dc..8bd7bb708 100644 --- a/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js +++ b/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js @@ -21,7 +21,7 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate const usedExports = dep.originModule.usedExports; if(usedExports && !Array.isArray(usedExports)) { const exportName = dep.originModule.exportsArgument || "exports"; - const content = `Object.defineProperty(${exportName}, \"__esModule\", { value: true });\n`; + const content = `Object.defineProperty(${exportName}, "__esModule", { value: true });\n`; source.insert(-10, content); } } diff --git a/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js index 973383551..d756688d2 100644 --- a/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js +++ b/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js @@ -13,6 +13,7 @@ const HarmonyModulesHelpers = require("./HarmonyModulesHelpers"); module.exports = class HarmonyImportDependencyParserPlugin { constructor(moduleOptions) { this.strictExportPresence = moduleOptions.strictExportPresence; + this.strictThisContextOnImports = moduleOptions.strictThisContextOnImports; } apply(parser) { @@ -52,6 +53,24 @@ module.exports = class HarmonyImportDependencyParserPlugin { parser.state.current.addDependency(dep); return true; }); + if(this.strictThisContextOnImports) { + // only in case when we strictly follow the spec we need a special case here + parser.plugin("call imported var.*", (expr) => { + const name = expr.callee.object.name; + const settings = parser.state.harmonySpecifier[`$${name}`]; + if(settings[2] !== null) + return false; + const dep = new HarmonyImportSpecifierDependency(settings[0], settings[1], expr.callee.property.name || expr.callee.property.value, name, expr.callee.range, this.strictExportPresence); + dep.shorthand = parser.scope.inShorthand; + dep.directImport = false; + dep.namespaceObjectAsContext = true; + dep.loc = expr.callee.loc; + parser.state.current.addDependency(dep); + if(expr.arguments) + parser.walkExpressions(expr.arguments); + return true; + }); + } parser.plugin("call imported var", (expr) => { const args = expr.arguments; const fullExpr = expr; diff --git a/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js b/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js index 01290b962..083019291 100644 --- a/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js +++ b/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js @@ -14,6 +14,10 @@ class HarmonyImportSpecifierDependency extends NullDependency { this.name = name; this.range = range; this.strictExportPresence = strictExportPresence; + this.namespaceObjectAsContext = false; + this.callArgs = undefined; + this.call = undefined; + this.directImport = undefined; } get type() { @@ -24,7 +28,7 @@ class HarmonyImportSpecifierDependency extends NullDependency { if(!this.importDependency.module) return null; return { module: this.importDependency.module, - importedNames: this.id ? [this.id] : true + importedNames: this.id && !this.namespaceObjectAsContext ? [this.id] : true }; } @@ -93,7 +97,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen } if(dep.call && dep.id) { - return `${shortHandPrefix}__webpack_require__.i(${importedVar}${importedVarSuffix})`; + return `${shortHandPrefix}Object(${importedVar}${importedVarSuffix})`; } return `${shortHandPrefix}${importedVar}${importedVarSuffix}`; diff --git a/node_modules/webpack/lib/dependencies/HarmonyModulesHelpers.js b/node_modules/webpack/lib/dependencies/HarmonyModulesHelpers.js index cd3b63115..1f3387fe1 100644 --- a/node_modules/webpack/lib/dependencies/HarmonyModulesHelpers.js +++ b/node_modules/webpack/lib/dependencies/HarmonyModulesHelpers.js @@ -8,12 +8,12 @@ class HarmonyModulesHelpers { static getModuleVar(state, request) { if(!state.harmonyModules) state.harmonyModules = []; - var idx = state.harmonyModules.indexOf(request); + let idx = state.harmonyModules.indexOf(request); if(idx < 0) { idx = state.harmonyModules.length; state.harmonyModules.push(request); } - return "__WEBPACK_IMPORTED_MODULE_" + idx + "_" + request.replace(/[^A-Za-z0-9_]/g, "_").replace(/__+/g, "_") + "__"; + return `__WEBPACK_IMPORTED_MODULE_${idx}_${request.replace(/[^A-Za-z0-9_]/g, "_").replace(/__+/g, "_")}__`; } static getNewModuleVar(state, request) { @@ -31,17 +31,17 @@ class HarmonyModulesHelpers { // checks if an harmony dependency is active in a module according to // precedence rules. static isActive(module, depInQuestion) { - var desc = depInQuestion.describeHarmonyExport(); + const desc = depInQuestion.describeHarmonyExport(); if(!desc.exportedName) return true; - var before = true; - for(var i = 0; i < module.dependencies.length; i++) { - var dep = module.dependencies[i]; + let before = true; + for(const moduleDependency of module.dependencies) { + const dep = moduleDependency; if(dep === depInQuestion) { before = false; continue; } if(!dep.describeHarmonyExport) continue; - var d = dep.describeHarmonyExport(); + const d = dep.describeHarmonyExport(); if(!d || !d.exportedName) continue; if(d.exportedName === desc.exportedName) { if(d.precedence < desc.precedence) { @@ -58,7 +58,7 @@ class HarmonyModulesHelpers { // get a list of named exports defined in a module // doesn't include * reexports. static getActiveExports(module, currentDependency) { - var desc = currentDependency && currentDependency.describeHarmonyExport(); + const desc = currentDependency && currentDependency.describeHarmonyExport(); var currentIndex = currentDependency ? module.dependencies.indexOf(currentDependency) : -1; return module.dependencies.map((dep, idx) => { return { @@ -66,9 +66,9 @@ class HarmonyModulesHelpers { idx: idx }; }).reduce((arr, data) => { - var dep = data.dep; + const dep = data.dep; if(!dep.describeHarmonyExport) return arr; - var d = dep.describeHarmonyExport(); + const d = dep.describeHarmonyExport(); if(!d) return arr; if(!desc || (d.precedence < desc.precedence) || (d.precedence === desc.precedence && data.idx < currentIndex)) { var names = [].concat(d.exportedName); diff --git a/node_modules/webpack/lib/dependencies/ImportParserPlugin.js b/node_modules/webpack/lib/dependencies/ImportParserPlugin.js index d97355dc7..a775571b2 100644 --- a/node_modules/webpack/lib/dependencies/ImportParserPlugin.js +++ b/node_modules/webpack/lib/dependencies/ImportParserPlugin.js @@ -5,6 +5,8 @@ "use strict"; const ImportEagerContextDependency = require("./ImportEagerContextDependency"); +const ImportWeakDependency = require("./ImportWeakDependency"); +const ImportWeakContextDependency = require("./ImportWeakContextDependency"); const ImportLazyOnceContextDependency = require("./ImportLazyOnceContextDependency"); const ImportLazyContextDependency = require("./ImportLazyContextDependency"); const ImportDependenciesBlock = require("./ImportDependenciesBlock"); @@ -46,26 +48,31 @@ class ImportParserPlugin { } if(param.isString()) { - if(mode !== "lazy" && mode !== "eager") { - parser.state.module.warnings.push(new UnsupportedFeatureWarning(parser.state.module, `\`webpackMode\` expected 'lazy' or 'eager', but received: ${mode}.`)); + if(mode !== "lazy" && mode !== "eager" && mode !== "weak") { + parser.state.module.warnings.push(new UnsupportedFeatureWarning(parser.state.module, `\`webpackMode\` expected 'lazy', 'eager' or 'weak', but received: ${mode}.`)); } if(mode === "eager") { const dep = new ImportEagerDependency(param.string, expr.range); parser.state.current.addDependency(dep); + } else if(mode === "weak") { + const dep = new ImportWeakDependency(param.string, expr.range); + parser.state.current.addDependency(dep); } else { const depBlock = new ImportDependenciesBlock(param.string, expr.range, chunkName, parser.state.module, expr.loc); parser.state.current.addBlock(depBlock); } return true; } else { - if(mode !== "lazy" && mode !== "lazy-once" && mode !== "eager") { - parser.state.module.warnings.push(new UnsupportedFeatureWarning(parser.state.module, `\`webpackMode\` expected 'lazy', 'lazy-once' or 'eager', but received: ${mode}.`)); + if(mode !== "lazy" && mode !== "lazy-once" && mode !== "eager" && mode !== "weak") { + parser.state.module.warnings.push(new UnsupportedFeatureWarning(parser.state.module, `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`)); } let Dep = ImportLazyContextDependency; if(mode === "eager") { Dep = ImportEagerContextDependency; + } else if(mode === "weak") { + Dep = ImportWeakContextDependency; } else if(mode === "lazy-once") { Dep = ImportLazyOnceContextDependency; } diff --git a/node_modules/webpack/lib/dependencies/ImportPlugin.js b/node_modules/webpack/lib/dependencies/ImportPlugin.js index 4905df183..27118bbcf 100644 --- a/node_modules/webpack/lib/dependencies/ImportPlugin.js +++ b/node_modules/webpack/lib/dependencies/ImportPlugin.js @@ -6,7 +6,9 @@ const ImportDependency = require("./ImportDependency"); const ImportEagerDependency = require("./ImportEagerDependency"); +const ImportWeakDependency = require("./ImportWeakDependency"); const ImportEagerContextDependency = require("./ImportEagerContextDependency"); +const ImportWeakContextDependency = require("./ImportWeakContextDependency"); const ImportLazyOnceContextDependency = require("./ImportLazyOnceContextDependency"); const ImportLazyContextDependency = require("./ImportLazyContextDependency"); const ImportParserPlugin = require("./ImportParserPlugin"); @@ -28,16 +30,22 @@ class ImportPlugin { compilation.dependencyFactories.set(ImportEagerDependency, normalModuleFactory); compilation.dependencyTemplates.set(ImportEagerDependency, new ImportEagerDependency.Template()); + compilation.dependencyFactories.set(ImportWeakDependency, normalModuleFactory); + compilation.dependencyTemplates.set(ImportWeakDependency, new ImportWeakDependency.Template()); + compilation.dependencyFactories.set(ImportEagerContextDependency, contextModuleFactory); compilation.dependencyTemplates.set(ImportEagerContextDependency, new ImportEagerContextDependency.Template()); + compilation.dependencyFactories.set(ImportWeakContextDependency, contextModuleFactory); + compilation.dependencyTemplates.set(ImportWeakContextDependency, new ImportWeakContextDependency.Template()); + compilation.dependencyFactories.set(ImportLazyOnceContextDependency, contextModuleFactory); compilation.dependencyTemplates.set(ImportLazyOnceContextDependency, new ImportLazyOnceContextDependency.Template()); compilation.dependencyFactories.set(ImportLazyContextDependency, contextModuleFactory); compilation.dependencyTemplates.set(ImportLazyContextDependency, new ImportLazyContextDependency.Template()); - params.normalModuleFactory.plugin("parser", (parser, parserOptions) => { + normalModuleFactory.plugin("parser", (parser, parserOptions) => { if(typeof parserOptions.import !== "undefined" && !parserOptions.import) return; diff --git a/node_modules/webpack/lib/dependencies/ImportWeakContextDependency.js b/node_modules/webpack/lib/dependencies/ImportWeakContextDependency.js new file mode 100644 index 000000000..f6c19613e --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportWeakContextDependency.js @@ -0,0 +1,22 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; +const ImportContextDependency = require("./ImportContextDependency"); +const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall"); + +class ImportWeakContextDependency extends ImportContextDependency { + constructor(request, recursive, regExp, range, valueRange, chunkName) { + super(request, recursive, regExp, range, valueRange, chunkName); + this.async = "async-weak"; + } + + get type() { + return "import() context weak"; + } +} + +ImportWeakContextDependency.Template = ContextDependencyTemplateAsRequireCall; + +module.exports = ImportWeakContextDependency; diff --git a/node_modules/webpack/lib/dependencies/ImportWeakDependency.js b/node_modules/webpack/lib/dependencies/ImportWeakDependency.js new file mode 100644 index 000000000..ccad2d92c --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportWeakDependency.js @@ -0,0 +1,47 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; +const ModuleDependency = require("./ModuleDependency"); +const webpackMissingPromiseModule = require("./WebpackMissingModule").promise; + +class ImportWeakDependency extends ModuleDependency { + constructor(request, range) { + super(request); + this.range = range; + this.weak = true; + } + + get type() { + return "import() weak"; + } +} + +ImportWeakDependency.Template = class ImportDependencyTemplate { + apply(dep, source, outputOptions, requestShortener) { + const comment = this.getOptionalComment(outputOptions.pathinfo, requestShortener.shorten(dep.request)); + + const content = this.getContent(dep, comment); + source.replace(dep.range[0], dep.range[1] - 1, content); + } + + getOptionalComment(pathinfo, shortenedRequest) { + if(!pathinfo) { + return ""; + } + + return `/*! ${shortenedRequest} */ `; + } + + getContent(dep, comment) { + if(dep.module) { + const stringifiedId = JSON.stringify(dep.module.id); + return `Promise.resolve(${comment}${stringifiedId}).then(function(id) { if(!__webpack_require__.m[id]) throw new Error("Module '" + id + "' is not available (weak dependency)"); return __webpack_require__(id); })`; + } + + return webpackMissingPromiseModule(dep.request); + } +}; + +module.exports = ImportWeakDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireContextDependency.js b/node_modules/webpack/lib/dependencies/RequireContextDependency.js index c0f6bdc75..e37b1b54c 100644 --- a/node_modules/webpack/lib/dependencies/RequireContextDependency.js +++ b/node_modules/webpack/lib/dependencies/RequireContextDependency.js @@ -7,9 +7,13 @@ const ContextDependency = require("./ContextDependency"); const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId"); class RequireContextDependency extends ContextDependency { - constructor(request, recursive, regExp, range) { + constructor(request, recursive, regExp, asyncMode, range) { super(request, recursive, regExp); this.range = range; + + if(asyncMode) { + this.async = asyncMode; + } } get type() { diff --git a/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js index 8587fba8d..04a8b25b9 100644 --- a/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js +++ b/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js @@ -11,7 +11,15 @@ module.exports = class RequireContextDependencyParserPlugin { parser.plugin("call require.context", expr => { let regExp = /^\.\/.*$/; let recursive = true; + let asyncMode; switch(expr.arguments.length) { + case 4: + { + const asyncModeExpr = parser.evaluateExpression(expr.arguments[3]); + if(!asyncModeExpr.isString()) return; + asyncMode = asyncModeExpr.string; + } + // falls through case 3: { const regExpExpr = parser.evaluateExpression(expr.arguments[2]); @@ -30,7 +38,7 @@ module.exports = class RequireContextDependencyParserPlugin { { const requestExpr = parser.evaluateExpression(expr.arguments[0]); if(!requestExpr.isString()) return; - const dep = new RequireContextDependency(requestExpr.string, recursive, regExp, expr.range); + const dep = new RequireContextDependency(requestExpr.string, recursive, regExp, asyncMode, expr.range); dep.loc = expr.loc; dep.optional = parser.scope.inTry; parser.state.current.addDependency(dep); diff --git a/node_modules/webpack/lib/dependencies/RequireContextPlugin.js b/node_modules/webpack/lib/dependencies/RequireContextPlugin.js index 57acda586..3e08729d3 100644 --- a/node_modules/webpack/lib/dependencies/RequireContextPlugin.js +++ b/node_modules/webpack/lib/dependencies/RequireContextPlugin.js @@ -10,18 +10,17 @@ const ContextElementDependency = require("./ContextElementDependency"); const RequireContextDependencyParserPlugin = require("./RequireContextDependencyParserPlugin"); class RequireContextPlugin { - constructor(modulesDirectories, extensions) { + constructor(modulesDirectories, extensions, mainFiles) { if(!Array.isArray(modulesDirectories)) throw new Error("modulesDirectories must be an array"); if(!Array.isArray(extensions)) throw new Error("extensions must be an array"); this.modulesDirectories = modulesDirectories; this.extensions = extensions; + this.mainFiles = mainFiles; } apply(compiler) { - const modulesDirectories = this.modulesDirectories; - const extensions = this.extensions; compiler.plugin("compilation", (compilation, params) => { const contextModuleFactory = params.contextModuleFactory; const normalModuleFactory = params.normalModuleFactory; @@ -43,7 +42,7 @@ class RequireContextPlugin { if(items.length === 0) return callback(null, items); callback(null, items.map((obj) => { - return extensions.filter((ext) => { + return this.extensions.filter((ext) => { const l = obj.request.length; return l > ext.length && obj.request.substr(l - ext.length, l) === ext; }).map((ext) => { @@ -60,8 +59,28 @@ class RequireContextPlugin { if(items.length === 0) return callback(null, items); callback(null, items.map((obj) => { - for(let i = 0; i < modulesDirectories.length; i++) { - const dir = modulesDirectories[i]; + return this.mainFiles.filter((mainFile) => { + const l = obj.request.length; + return l > mainFile.length + 1 && obj.request.substr(l - mainFile.length - 1, l) === "/" + mainFile; + }).map((mainFile) => { + const l = obj.request.length; + return [{ + context: obj.context, + request: obj.request.substr(0, l - mainFile.length) + }, { + context: obj.context, + request: obj.request.substr(0, l - mainFile.length - 1) + }]; + }).reduce((a, b) => a.concat(b), []).concat(obj); + }).reduce((a, b) => a.concat(b), [])); + }); + + params.contextModuleFactory.plugin("alternatives", (items, callback) => { + if(items.length === 0) return callback(null, items); + + callback(null, items.map((obj) => { + for(let i = 0; i < this.modulesDirectories.length; i++) { + const dir = this.modulesDirectories[i]; const idx = obj.request.indexOf("./" + dir + "/"); if(idx === 0) { obj.request = obj.request.slice(dir.length + 3); diff --git a/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js b/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js index 4b3a378e9..4d72b07ab 100644 --- a/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js +++ b/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js @@ -11,14 +11,8 @@ module.exports = class RequireEnsureDependenciesBlock extends AsyncDependenciesB super(chunkName, module, loc); this.expr = expr; const successBodyRange = successExpression && successExpression.body && successExpression.body.range; - const errorBodyRange = errorExpression && errorExpression.body && errorExpression.body.range; - this.range = null; if(successBodyRange) { - if(errorBodyRange) { - this.range = [successBodyRange[0] + 1, errorBodyRange[1] - 1]; - } else { - this.range = [successBodyRange[0] + 1, successBodyRange[1] - 1]; - } + this.range = [successBodyRange[0] + 1, successBodyRange[1] - 1]; } this.chunkNameRange = chunkNameRange; const dep = new RequireEnsureDependency(this); diff --git a/node_modules/webpack/lib/dependencies/RequireResolveDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/RequireResolveDependencyParserPlugin.js index 09dd60788..85451cf95 100644 --- a/node_modules/webpack/lib/dependencies/RequireResolveDependencyParserPlugin.js +++ b/node_modules/webpack/lib/dependencies/RequireResolveDependencyParserPlugin.js @@ -62,7 +62,7 @@ class RequireResolveDependencyParserPlugin { if(!dep) return; dep.loc = expr.loc; dep.optional = !!parser.scope.inTry; - dep.weak = weak; + dep.async = weak ? "weak" : false; parser.state.current.addDependency(dep); return true; }); diff --git a/node_modules/webpack/lib/node/NodeMainTemplatePlugin.js b/node_modules/webpack/lib/node/NodeMainTemplatePlugin.js index d4660dac1..9a64b57b5 100644 --- a/node_modules/webpack/lib/node/NodeMainTemplatePlugin.js +++ b/node_modules/webpack/lib/node/NodeMainTemplatePlugin.js @@ -2,190 +2,182 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -var Template = require("../Template"); +"use strict"; -function NodeMainTemplatePlugin(asyncChunkLoading) { - this.asyncChunkLoading = asyncChunkLoading; -} -module.exports = NodeMainTemplatePlugin; -NodeMainTemplatePlugin.prototype.apply = function(mainTemplate) { - var self = this; - mainTemplate.plugin("local-vars", function(source, chunk) { - if(chunk.chunks.length > 0) { - return this.asString([ - source, - "", - "// object to store loaded chunks", - "// \"0\" means \"already loaded\"", - "var installedChunks = {", - this.indent( - chunk.ids.map(function(id) { - return id + ": 0"; - }).join(",\n") - ), - "};" - ]); - } - return source; - }); - mainTemplate.plugin("require-extensions", function(source, chunk) { - if(chunk.chunks.length > 0) { - return this.asString([ - source, - "", - "// uncatched error handler for webpack runtime", - this.requireFn + ".oe = function(err) {", - this.indent([ - "process.nextTick(function() {", - this.indent("throw err; // catch this error by using System.import().catch()"), - "});" - ]), - "};" - ]); - } - return source; - }); - mainTemplate.plugin("require-ensure", function(_, chunk, hash) { - var chunkFilename = this.outputOptions.chunkFilename; - var chunkMaps = chunk.getChunkMaps(); - var insertMoreModules = [ - "var moreModules = chunk.modules, chunkIds = chunk.ids;", - "for(var moduleId in moreModules) {", - this.indent(this.renderAddModule(hash, chunk, "moduleId", "moreModules[moduleId]")), - "}" - ]; - if(self.asyncChunkLoading) { - return this.asString([ - "// \"0\" is the signal for \"already loaded\"", - "if(installedChunks[chunkId] === 0)", - this.indent([ - "return Promise.resolve();" - ]), - "// array of [resolve, reject, promise] means \"currently loading\"", - "if(installedChunks[chunkId])", - this.indent([ - "return installedChunks[chunkId][2];" - ]), - "// load the chunk and return promise to it", - "var promise = new Promise(function(resolve, reject) {", - this.indent([ - "installedChunks[chunkId] = [resolve, reject];", - "var filename = __dirname + " + this.applyPluginsWaterfall("asset-path", JSON.stringify("/" + chunkFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function(length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this), - chunk: { - id: "\" + chunkId + \"", - hash: "\" + " + JSON.stringify(chunkMaps.hash) + "[chunkId] + \"", - hashWithLength: function(length) { - var shortChunkHashMap = {}; - Object.keys(chunkMaps.hash).forEach(function(chunkId) { - if(typeof chunkMaps.hash[chunkId] === "string") - shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(0, length); - }); - return "\" + " + JSON.stringify(shortChunkHashMap) + "[chunkId] + \""; - }, - name: "\" + (" + JSON.stringify(chunkMaps.name) + "[chunkId]||chunkId) + \"" - } - }) + ";", - "require('fs').readFile(filename, 'utf-8', function(err, content) {", +const Template = require("../Template"); + +module.exports = class NodeMainTemplatePlugin { + constructor(asyncChunkLoading) { + this.asyncChunkLoading = asyncChunkLoading; + } + + apply(mainTemplate) { + const asyncChunkLoading = this.asyncChunkLoading; + mainTemplate.plugin("local-vars", function(source, chunk) { + if(chunk.chunks.length > 0) { + return this.asString([ + source, + "", + "// object to store loaded chunks", + "// \"0\" means \"already loaded\"", + "var installedChunks = {", + this.indent(chunk.ids.map((id) => `${id}: 0`).join(",\n")), + "};" + ]); + } + return source; + }); + mainTemplate.plugin("require-extensions", function(source, chunk) { + if(chunk.chunks.length > 0) { + return this.asString([ + source, + "", + "// uncatched error handler for webpack runtime", + `${this.requireFn}.oe = function(err) {`, this.indent([ - "if(err) return reject(err);", - "var chunk = {};", - "require('vm').runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)" + - "(chunk, require, require('path').dirname(filename), filename);" - ].concat(insertMoreModules).concat([ - "var callbacks = [];", - "for(var i = 0; i < chunkIds.length; i++) {", + "process.nextTick(function() {", + this.indent("throw err; // catch this error by using System.import().catch()"), + "});" + ]), + "};" + ]); + } + return source; + }); + mainTemplate.plugin("require-ensure", function(_, chunk, hash) { + const chunkFilename = this.outputOptions.chunkFilename; + const chunkMaps = chunk.getChunkMaps(); + const insertMoreModules = [ + "var moreModules = chunk.modules, chunkIds = chunk.ids;", + "for(var moduleId in moreModules) {", + this.indent(this.renderAddModule(hash, chunk, "moduleId", "moreModules[moduleId]")), + "}" + ]; + if(asyncChunkLoading) { + return this.asString([ + "// \"0\" is the signal for \"already loaded\"", + "if(installedChunks[chunkId] === 0)", + this.indent([ + "return Promise.resolve();" + ]), + "// array of [resolve, reject, promise] means \"currently loading\"", + "if(installedChunks[chunkId])", + this.indent([ + "return installedChunks[chunkId][2];" + ]), + "// load the chunk and return promise to it", + "var promise = new Promise(function(resolve, reject) {", + this.indent([ + "installedChunks[chunkId] = [resolve, reject];", + "var filename = __dirname + " + this.applyPluginsWaterfall("asset-path", JSON.stringify(`/${chunkFilename}`), { + hash: `" + ${this.renderCurrentHashCode(hash)} + "`, + hashWithLength: (length) => `" + ${this.renderCurrentHashCode(hash, length)} + "`, + chunk: { + id: "\" + chunkId + \"", + hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`, + hashWithLength: (length) => { + const shortChunkHashMap = {}; + Object.keys(chunkMaps.hash).forEach((chunkId) => { + if(typeof chunkMaps.hash[chunkId] === "string") + shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(0, length); + }); + return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`; + }, + name: `" + (${JSON.stringify(chunkMaps.name)}[chunkId]||chunkId) + "` + } + }) + ";", + "require('fs').readFile(filename, 'utf-8', function(err, content) {", this.indent([ - "if(installedChunks[chunkIds[i]])", + "if(err) return reject(err);", + "var chunk = {};", + "require('vm').runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)" + + "(chunk, require, require('path').dirname(filename), filename);" + ].concat(insertMoreModules).concat([ + "var callbacks = [];", + "for(var i = 0; i < chunkIds.length; i++) {", this.indent([ - "callbacks = callbacks.concat(installedChunks[chunkIds[i]][0]);" + "if(installedChunks[chunkIds[i]])", + this.indent([ + "callbacks = callbacks.concat(installedChunks[chunkIds[i]][0]);" + ]), + "installedChunks[chunkIds[i]] = 0;" ]), - "installedChunks[chunkIds[i]] = 0;" - ]), - "}", - "for(i = 0; i < callbacks.length; i++)", - this.indent("callbacks[i]();") + "}", + "for(i = 0; i < callbacks.length; i++)", + this.indent("callbacks[i]();") + ])), + "});" + ]), + "});", + "return installedChunks[chunkId][2] = promise;" + ]); + } else { + const request = this.applyPluginsWaterfall("asset-path", JSON.stringify(`./${chunkFilename}`), { + hash: `" + ${this.renderCurrentHashCode(hash)} + "`, + hashWithLength: (length) => `" + ${this.renderCurrentHashCode(hash, length)} + "`, + chunk: { + id: "\" + chunkId + \"", + hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`, + hashWithLength: (length) => { + const shortChunkHashMap = {}; + Object.keys(chunkMaps.hash).forEach((chunkId) => { + if(typeof chunkMaps.hash[chunkId] === "string") + shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(0, length); + }); + return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`; + }, + name: `" + (${JSON.stringify(chunkMaps.name)}[chunkId]||chunkId) + "` + } + }); + return this.asString([ + "// \"0\" is the signal for \"already loaded\"", + "if(installedChunks[chunkId] !== 0) {", + this.indent([ + `var chunk = require(${request});` + ].concat(insertMoreModules).concat([ + "for(var i = 0; i < chunkIds.length; i++)", + this.indent("installedChunks[chunkIds[i]] = 0;") ])), - "});" - ]), - "});", - "return installedChunks[chunkId][2] = promise;" - ]); - } else { - var request = this.applyPluginsWaterfall("asset-path", JSON.stringify("./" + chunkFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function(length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this), + "}", + "return Promise.resolve();" + ]); + } + }); + mainTemplate.plugin("hot-bootstrap", function(source, chunk, hash) { + const hotUpdateChunkFilename = this.outputOptions.hotUpdateChunkFilename; + const hotUpdateMainFilename = this.outputOptions.hotUpdateMainFilename; + const chunkMaps = chunk.getChunkMaps(); + const currentHotUpdateChunkFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateChunkFilename), { + hash: `" + ${this.renderCurrentHashCode(hash)} + "`, + hashWithLength: (length) => `" + ${this.renderCurrentHashCode(hash, length)} + "`, chunk: { id: "\" + chunkId + \"", - hash: "\" + " + JSON.stringify(chunkMaps.hash) + "[chunkId] + \"", - hashWithLength: function(length) { - var shortChunkHashMap = {}; - Object.keys(chunkMaps.hash).forEach(function(chunkId) { + hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`, + hashWithLength: (length) => { + const shortChunkHashMap = {}; + Object.keys(chunkMaps.hash).forEach((chunkId) => { if(typeof chunkMaps.hash[chunkId] === "string") shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(0, length); }); - return "\" + " + JSON.stringify(shortChunkHashMap) + "[chunkId] + \""; + return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`; }, - name: "\" + (" + JSON.stringify(chunkMaps.name) + "[chunkId]||chunkId) + \"" + name: `" + (${JSON.stringify(chunkMaps.name)}[chunkId]||chunkId) + "` } }); - return this.asString([ - "// \"0\" is the signal for \"already loaded\"", - "if(installedChunks[chunkId] !== 0) {", - this.indent([ - "var chunk = require(" + request + ");" - ].concat(insertMoreModules).concat([ - "for(var i = 0; i < chunkIds.length; i++)", - this.indent("installedChunks[chunkIds[i]] = 0;") - ])), - "}", - "return Promise.resolve();" - ]); - } - }); - mainTemplate.plugin("hot-bootstrap", function(source, chunk, hash) { - var hotUpdateChunkFilename = this.outputOptions.hotUpdateChunkFilename; - var hotUpdateMainFilename = this.outputOptions.hotUpdateMainFilename; - var chunkMaps = chunk.getChunkMaps(); - var currentHotUpdateChunkFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateChunkFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function(length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this), - chunk: { - id: "\" + chunkId + \"", - hash: "\" + " + JSON.stringify(chunkMaps.hash) + "[chunkId] + \"", - hashWithLength: function(length) { - var shortChunkHashMap = {}; - Object.keys(chunkMaps.hash).forEach(function(chunkId) { - if(typeof chunkMaps.hash[chunkId] === "string") - shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(0, length); - }); - return "\" + " + JSON.stringify(shortChunkHashMap) + "[chunkId] + \""; - }, - name: "\" + (" + JSON.stringify(chunkMaps.name) + "[chunkId]||chunkId) + \"" - } + const currentHotUpdateMainFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateMainFilename), { + hash: `" + ${this.renderCurrentHashCode(hash)} + "`, + hashWithLength: (length) => `" + ${this.renderCurrentHashCode(hash, length)} + "` + }); + return Template.getFunctionContent(asyncChunkLoading ? require("./NodeMainTemplateAsync.runtime.js") : require("./NodeMainTemplate.runtime.js")) + .replace(/\$require\$/g, this.requireFn) + .replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename) + .replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename); }); - var currentHotUpdateMainFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateMainFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function(length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this) + mainTemplate.plugin("hash", function(hash) { + hash.update("node"); + hash.update("3"); + hash.update(this.outputOptions.filename + ""); + hash.update(this.outputOptions.chunkFilename + ""); }); - return Template.getFunctionContent(self.asyncChunkLoading ? require("./NodeMainTemplateAsync.runtime.js") : require("./NodeMainTemplate.runtime.js")) - .replace(/\$require\$/g, this.requireFn) - .replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename) - .replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename); - }); - mainTemplate.plugin("hash", function(hash) { - hash.update("node"); - hash.update("3"); - hash.update(this.outputOptions.filename + ""); - hash.update(this.outputOptions.chunkFilename + ""); - }); + } }; diff --git a/node_modules/webpack/lib/node/NodeSourcePlugin.js b/node_modules/webpack/lib/node/NodeSourcePlugin.js index 14a375445..986160028 100644 --- a/node_modules/webpack/lib/node/NodeSourcePlugin.js +++ b/node_modules/webpack/lib/node/NodeSourcePlugin.js @@ -13,6 +13,8 @@ module.exports = class NodeSourcePlugin { } apply(compiler) { const options = this.options; + if(options === false) // allow single kill switch to turn off this plugin + return; function getPathToModule(module, type) { if(type === true || (type === undefined && nodeLibsBrowser[module])) { diff --git a/node_modules/webpack/lib/node/NodeWatchFileSystem.js b/node_modules/webpack/lib/node/NodeWatchFileSystem.js index a4ff6c6b5..1c13a9b29 100644 --- a/node_modules/webpack/lib/node/NodeWatchFileSystem.js +++ b/node_modules/webpack/lib/node/NodeWatchFileSystem.js @@ -48,7 +48,7 @@ class NodeWatchFileSystem { changes.filter(file => missing.indexOf(file) >= 0).sort(), times, times); }); - this.watcher.watch(files.concat(missing), dirs, startTime); + this.watcher.watch(files.concat(missing), dirs.concat(missing), startTime); if(oldWatcher) { oldWatcher.close(); diff --git a/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js b/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js index 826a6baa9..dc14ac300 100644 --- a/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js +++ b/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js @@ -23,7 +23,7 @@ class AggressiveMergingPlugin { return a + b; }, 0); } - compiler.plugin("compilation", (compilation) => { + compiler.plugin("this-compilation", (compilation) => { compilation.plugin("optimize-chunks-advanced", (chunks) => { let combinations = []; chunks.forEach((a, idx) => { @@ -31,86 +31,80 @@ class AggressiveMergingPlugin { for(let i = 0; i < idx; i++) { const b = chunks[i]; if(b.isInitial()) continue; - combinations.push([b, a]); + combinations.push({ + a, + b, + improvement: undefined + }); } }); combinations.forEach((pair) => { - const a = pair[0].size({ + const a = pair.b.size({ chunkOverhead: 0 }); - const b = pair[1].size({ + const b = pair.a.size({ chunkOverhead: 0 }); - const ab = pair[0].integratedSize(pair[1], { + const ab = pair.b.integratedSize(pair.a, { chunkOverhead: 0 }); - pair.push({ - a: a, - b: b, - ab: ab - }); let newSize; if(ab === false) { - pair.unshift(false); + pair.improvement = false; + return; } else if(options.moveToParents) { const aOnly = ab - b; const bOnly = ab - a; const common = a + b - ab; - newSize = common + getParentsWeight(pair[0]) * aOnly + getParentsWeight(pair[1]) * bOnly; - pair.push({ - aOnly: aOnly, - bOnly: bOnly, - common: common, - newSize: newSize - }); + newSize = common + getParentsWeight(pair.b) * aOnly + getParentsWeight(pair.a) * bOnly; } else { newSize = ab; } - pair.unshift((a + b) / newSize); + pair.improvement = (a + b) / newSize; }); combinations = combinations.filter((pair) => { - return pair[0] !== false; + return pair.improvement !== false; }); combinations.sort((a, b) => { - return b[0] - a[0]; + return b.improvement - a.improvement; }); const pair = combinations[0]; if(!pair) return; - if(pair[0] < minSizeReduce) return; + if(pair.improvement < minSizeReduce) return; if(options.moveToParents) { - const commonModules = pair[1].modules.filter((m) => { - return pair[2].modules.indexOf(m) >= 0; + const commonModules = pair.b.modules.filter((m) => { + return pair.a.modules.indexOf(m) >= 0; }); - const aOnlyModules = pair[1].modules.filter((m) => { + const aOnlyModules = pair.b.modules.filter((m) => { return commonModules.indexOf(m) < 0; }); - const bOnlyModules = pair[2].modules.filter((m) => { + const bOnlyModules = pair.a.modules.filter((m) => { return commonModules.indexOf(m) < 0; }); aOnlyModules.forEach((m) => { - pair[1].removeModule(m); - m.removeChunk(pair[1]); - pair[1].parents.forEach((c) => { + pair.b.removeModule(m); + m.removeChunk(pair.b); + pair.b.parents.forEach((c) => { c.addModule(m); m.addChunk(c); }); }); bOnlyModules.forEach((m) => { - pair[2].removeModule(m); - m.removeChunk(pair[2]); - pair[2].parents.forEach((c) => { + pair.a.removeModule(m); + m.removeChunk(pair.a); + pair.a.parents.forEach((c) => { c.addModule(m); m.addChunk(c); }); }); } - if(pair[1].integrate(pair[2], "aggressive-merge")) { - chunks.splice(chunks.indexOf(pair[2]), 1); + if(pair.b.integrate(pair.a, "aggressive-merge")) { + chunks.splice(chunks.indexOf(pair.a), 1); return true; } }); diff --git a/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js b/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js index e05b3eb4c..b6f566a1c 100644 --- a/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js +++ b/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js @@ -6,18 +6,6 @@ const identifierUtils = require("../util/identifier"); -function toIndexOf(list) { - return function(item) { - return list.indexOf(item); - }; -} - -function toChunkModuleIndices(modules) { - return function(idx) { - return modules[idx]; - }; -} - function moveModuleBetween(oldChunk, newChunk) { return function(module) { oldChunk.moveModule(module, newChunk); @@ -49,8 +37,15 @@ class AggressiveSplittingPlugin { if(typeof this.options.entryChunkMultiplicator !== "number") this.options.entryChunkMultiplicator = 1; } apply(compiler) { - compiler.plugin("compilation", (compilation) => { + compiler.plugin("this-compilation", (compilation) => { compilation.plugin("optimize-chunks-advanced", (chunks) => { + // Precompute stuff + const nameToModuleMap = new Map(); + compilation.modules.forEach(m => { + const name = identifierUtils.makePathsRelative(compiler.context, m.identifier(), compilation.cache); + nameToModuleMap.set(name, m); + }); + const savedSplits = compilation.records && compilation.records.aggressiveSplits || []; const usedSplits = compilation._aggressiveSplittingSplits ? savedSplits.concat(compilation._aggressiveSplittingSplits) : savedSplits; @@ -60,50 +55,58 @@ class AggressiveSplittingPlugin { // 1. try to restore to recorded splitting for(let j = 0; j < usedSplits.length; j++) { const splitData = usedSplits[j]; - for(let i = 0; i < chunks.length; i++) { - const chunk = chunks[i]; - const chunkModuleNames = chunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())); + const selectedModules = splitData.modules.map(name => nameToModuleMap.get(name)); - if(chunkModuleNames.length < splitData.modules.length) - continue; - const moduleIndicies = splitData.modules.map(toIndexOf(chunkModuleNames)); - const hasAllModules = moduleIndicies.every((idx) => { - return idx >= 0; - }); - if(hasAllModules) { - if(chunkModuleNames.length > splitData.modules.length) { - const selectedModules = moduleIndicies.map(toChunkModuleIndices(chunk.modules)); - const newChunk = compilation.addChunk(); - selectedModules.forEach(moveModuleBetween(chunk, newChunk)); - chunk.split(newChunk); - chunk.name = null; - newChunk._fromAggressiveSplitting = true; - if(j < savedSplits.length) - newChunk._fromAggressiveSplittingIndex = j; - if(splitData.id !== null && splitData.id !== undefined) { - newChunk.id = splitData.id; - } - newChunk.origins = chunk.origins.map(copyWithReason); - chunk.origins = chunk.origins.map(copyWithReason); - return true; - } else { - if(j < savedSplits.length) - chunk._fromAggressiveSplittingIndex = j; - chunk.name = null; - if(splitData.id !== null && splitData.id !== undefined) { - chunk.id = splitData.id; + // Does the modules exist at all? + if(selectedModules.every(Boolean)) { + + // Find all chunks containing all modules in the split + for(let i = 0; i < chunks.length; i++) { + const chunk = chunks[i]; + + // Cheap check if chunk is suitable at all + if(chunk.getNumberOfModules() < splitData.modules.length) + continue; + + // Check if all modules are in the chunk + if(selectedModules.every(m => chunk.containsModule(m))) { + + // Is chunk identical to the split or do we need to split it? + if(chunk.getNumberOfModules() > splitData.modules.length) { + // split the chunk into two parts + const newChunk = compilation.addChunk(); + selectedModules.forEach(moveModuleBetween(chunk, newChunk)); + chunk.split(newChunk); + chunk.name = null; + newChunk._fromAggressiveSplitting = true; + if(j < savedSplits.length) + newChunk._fromAggressiveSplittingIndex = j; + if(splitData.id !== null && splitData.id !== undefined) { + newChunk.id = splitData.id; + } + newChunk.origins = chunk.origins.map(copyWithReason); + chunk.origins = chunk.origins.map(copyWithReason); + return true; + } else { // chunk is identical to the split + if(j < savedSplits.length) + chunk._fromAggressiveSplittingIndex = j; + chunk.name = null; + if(splitData.id !== null && splitData.id !== undefined) { + chunk.id = splitData.id; + } } } } } } + // 2. for any other chunk which isn't splitted yet, split it for(let i = 0; i < chunks.length; i++) { const chunk = chunks[i]; const size = chunk.size(this.options); - if(size > maxSize && chunk.modules.length > 1) { + if(size > maxSize && chunk.getNumberOfModules() > 1) { const newChunk = compilation.addChunk(); - const modules = chunk.modules + const modules = chunk.getModules() .filter(isNotAEntryModule(chunk.entryModule)) .sort((a, b) => { a = a.identifier(); @@ -131,13 +134,13 @@ class AggressiveSplittingPlugin { break; } } - if(newChunk.modules.length > 0) { + if(newChunk.getNumberOfModules() > 0) { chunk.split(newChunk); chunk.name = null; newChunk.origins = chunk.origins.map(copyWithReason); chunk.origins = chunk.origins.map(copyWithReason); compilation._aggressiveSplittingSplits = (compilation._aggressiveSplittingSplits || []).concat({ - modules: newChunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())) + modules: newChunk.mapModules(m => identifierUtils.makePathsRelative(compiler.context, m.identifier(), compilation.cache)) }); return true; } else { @@ -154,7 +157,7 @@ class AggressiveSplittingPlugin { if(chunk.hasEntryModule()) return; const size = chunk.size(this.options); const incorrectSize = size < minSize; - const modules = chunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())); + const modules = chunk.mapModules(m => identifierUtils.makePathsRelative(compiler.context, m.identifier(), compilation.cache)); if(typeof chunk._fromAggressiveSplittingIndex === "undefined") { if(incorrectSize) return; chunk.recorded = true; diff --git a/node_modules/webpack/lib/optimize/ChunkModuleIdRangePlugin.js b/node_modules/webpack/lib/optimize/ChunkModuleIdRangePlugin.js index 8166fc315..262014dc5 100644 --- a/node_modules/webpack/lib/optimize/ChunkModuleIdRangePlugin.js +++ b/node_modules/webpack/lib/optimize/ChunkModuleIdRangePlugin.js @@ -11,9 +11,7 @@ class ChunkModuleIdRangePlugin { const options = this.options; compiler.plugin("compilation", (compilation) => { compilation.plugin("module-ids", (modules) => { - const chunk = this.chunks.filter((chunk) => { - return chunk.name === options.name; - })[0]; + const chunk = this.chunks.find((chunk) => chunk.name === options.name); if(!chunk) throw new Error("ChunkModuleIdRangePlugin: Chunk with name '" + options.name + "' was not found"); let currentId = options.start; let chunkModules; diff --git a/node_modules/webpack/lib/optimize/CommonsChunkPlugin.js b/node_modules/webpack/lib/optimize/CommonsChunkPlugin.js index 3ef414198..465b7ff7a 100644 --- a/node_modules/webpack/lib/optimize/CommonsChunkPlugin.js +++ b/node_modules/webpack/lib/optimize/CommonsChunkPlugin.js @@ -60,8 +60,8 @@ The available options are: * that webpack will take care of loading this file. */ if(options.async && options.filename) { - throw new Error(`You can not specify a filename if you use the \"async\" option. -You can however specify the name of the async chunk by passing the desired string as the \"async\" option.`); + throw new Error(`You can not specify a filename if you use the "async" option. +You can however specify the name of the async chunk by passing the desired string as the "async" option.`); } /** @@ -115,7 +115,18 @@ You can however specify the name of the async chunk by passing the desired strin // override the "commonChunk" with the newly created async one and use it as commonChunk from now on let asyncChunk; if(this.async) { - asyncChunk = this.createAsyncChunk(compilation, this.async, targetChunk); + // If async chunk is one of the affected chunks, just use it + asyncChunk = affectedChunks.filter(c => c.name === this.async)[0]; + // Elsewise create a new one + if(!asyncChunk) { + asyncChunk = this.createAsyncChunk( + compilation, + targetChunks.length <= 1 || typeof this.async !== "string" ? this.async : + targetChunk.name ? `${this.async}-${targetChunk.name}` : + true, + targetChunk + ); + } targetChunk = asyncChunk; } @@ -190,7 +201,7 @@ You can however specify the name of the async chunk by passing the desired strin // we dont have named chunks specified, so we just take all of them if(asyncOrNoSelectedChunk) { - return allChunks.filter(chunk => !chunk.isInitial()); + return allChunks; } /** @@ -218,8 +229,15 @@ Take a look at the "name"/"names" or async/children option.`); } return targetChunk.chunks.filter((chunk) => { + // we only are interested in on-demand chunks + if(chunk.isInitial()) + return false; + // we can only move modules from this chunk if the "commonChunk" is the only parent - return asyncOption || chunk.parents.length === 1; + if(!asyncOption) + return chunk.parents.length === 1; + + return true; }); } @@ -275,7 +293,7 @@ Take a look at the "name"/"names" or async/children option.`); // count how many chunks contain a module const commonModulesToCountMap = usedChunks.reduce((map, chunk) => { - for(let module of chunk.modules) { + for(const module of chunk.modulesIterable) { const count = map.has(module) ? map.get(module) : 0; map.set(module, count + 1); } @@ -306,7 +324,7 @@ Take a look at the "name"/"names" or async/children option.`); extractModulesAndReturnAffectedChunks(reallyUsedModules, usedChunks) { return reallyUsedModules.reduce((affectedChunksSet, module) => { - for(let chunk of usedChunks) { + for(const chunk of usedChunks) { // removeChunk returns true if the chunk was contained and succesfully removed // false if the module did not have a connection to the chunk in question if(module.removeChunk(chunk)) { @@ -318,29 +336,32 @@ Take a look at the "name"/"names" or async/children option.`); } addExtractedModulesToTargetChunk(chunk, modules) { - for(let module of modules) { + for(const module of modules) { chunk.addModule(module); module.addChunk(chunk); } } makeTargetChunkParentOfAffectedChunks(usedChunks, commonChunk) { - for(let chunk of usedChunks) { + for(const chunk of usedChunks) { // set commonChunk as new sole parent chunk.parents = [commonChunk]; // add chunk to commonChunk commonChunk.addChunk(chunk); - for(let entrypoint of chunk.entrypoints) { + for(const entrypoint of chunk.entrypoints) { entrypoint.insertChunk(commonChunk, chunk); } } } moveExtractedChunkBlocksToTargetChunk(chunks, targetChunk) { - for(let chunk of chunks) { - for(let block of chunk.blocks) { - block.chunks.unshift(targetChunk); + for(const chunk of chunks) { + if(chunk === targetChunk) continue; + for(const block of chunk.blocks) { + if(block.chunks.indexOf(targetChunk) === -1) { + block.chunks.unshift(targetChunk); + } targetChunk.addBlock(block); } } @@ -348,8 +369,8 @@ Take a look at the "name"/"names" or async/children option.`); extractOriginsOfChunksWithExtractedModules(chunks) { const origins = []; - for(let chunk of chunks) { - for(let origin of chunk.origins) { + for(const chunk of chunks) { + for(const origin of chunk.origins) { const newOrigin = Object.create(origin); newOrigin.reasons = (origin.reasons || []).concat("async commons"); origins.push(newOrigin); diff --git a/node_modules/webpack/lib/optimize/ConcatenatedModule.js b/node_modules/webpack/lib/optimize/ConcatenatedModule.js new file mode 100644 index 000000000..6cb503f0d --- /dev/null +++ b/node_modules/webpack/lib/optimize/ConcatenatedModule.js @@ -0,0 +1,816 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const Module = require("../Module"); +const Template = require("../Template"); +const Parser = require("../Parser"); +const acorn = require("acorn"); +const escope = require("escope"); +const ReplaceSource = require("webpack-sources/lib/ReplaceSource"); +const ConcatSource = require("webpack-sources/lib/ConcatSource"); +const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); +const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency"); +const HarmonyExportSpecifierDependency = require("../dependencies/HarmonyExportSpecifierDependency"); +const HarmonyExportExpressionDependency = require("../dependencies/HarmonyExportExpressionDependency"); +const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency"); +const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency"); +const HarmonyModulesHelpers = require("../dependencies/HarmonyModulesHelpers"); + +function ensureNsObjSource(info, moduleToInfoMap, requestShortener) { + if(!info.hasNamespaceObject) { + info.hasNamespaceObject = true; + const name = info.exportMap.get(true); + const nsObj = [`var ${name} = {};`]; + for(const exportName of info.module.providedExports) { + const finalName = getFinalName(info, exportName, moduleToInfoMap, requestShortener, false); + nsObj.push(`__webpack_require__.d(${name}, ${JSON.stringify(exportName)}, function() { return ${finalName}; });`); + } + info.namespaceObjectSource = nsObj.join("\n") + "\n"; + } +} + +function getExternalImport(importedModule, info, exportName, asCall) { + if(exportName === true) return info.name; + const used = importedModule.isUsed(exportName); + if(!used) return "/* unused reexport */undefined"; + if(info.interop && exportName === "default") { + return asCall ? `${info.interopName}()` : `${info.interopName}.a`; + } + // TODO use Template.toNormalComment when merging with pure-module + const comment = used !== exportName ? ` /* ${exportName} */` : ""; + const reference = `${info.name}[${JSON.stringify(used)}${comment}]`; + if(asCall) + return `Object(${reference})`; + return reference; +} + +function getFinalName(info, exportName, moduleToInfoMap, requestShortener, asCall) { + switch(info.type) { + case "concatenated": + { + const directExport = info.exportMap.get(exportName); + if(directExport) { + if(exportName === true) + ensureNsObjSource(info, moduleToInfoMap, requestShortener); + const name = info.internalNames.get(directExport); + if(!name) + throw new Error(`The export "${directExport}" in "${info.module.readableIdentifier(requestShortener)}" has no internal name`); + return name; + } + const reexport = info.reexportMap.get(exportName); + if(reexport) { + const refInfo = moduleToInfoMap.get(reexport.module); + if(refInfo) { + // module is in the concatenation + return getFinalName(refInfo, reexport.exportName, moduleToInfoMap, requestShortener, asCall); + } + } + const problem = `Cannot get final name for export "${exportName}" in "${info.module.readableIdentifier(requestShortener)}"` + + ` (known exports: ${Array.from(info.exportMap.keys()).filter(name => name !== true).join(" ")}, ` + + `known reexports: ${Array.from(info.reexportMap.keys()).join(" ")})`; + // TODO use Template.toNormalComment when merging with pure-module + return `/* ${problem} */ undefined`; + } + case "external": + { + const importedModule = info.module; + return getExternalImport(importedModule, info, exportName, asCall); + } + } +} + +function getSymbolsFromScope(s, untilScope) { + const allUsedNames = new Set(); + let scope = s; + while(scope) { + if(untilScope === scope) break; + scope.variables.forEach(variable => allUsedNames.add(variable.name)); + scope = scope.upper; + } + return allUsedNames; +} + +function getAllReferences(variable) { + let set = variable.references; + // Look for inner scope variables too (like in class Foo { t() { Foo } }) + const identifiers = new Set(variable.identifiers); + for(const scope of variable.scope.childScopes) { + for(const innerVar of scope.variables) { + if(innerVar.identifiers.some(id => identifiers.has(id))) { + set = set.concat(innerVar.references); + break; + } + } + } + return set; +} + +function reduceSet(a, b) { + for(const item of b) + a.add(item); + return a; +} + +function getPathInAst(ast, node) { + if(ast === node) { + return []; + } + const nr = node.range; + var i; + if(Array.isArray(ast)) { + for(i = 0; i < ast.length; i++) { + const enterResult = enterNode(ast[i]); + if(typeof enterResult !== "undefined") + return enterResult; + } + } else if(ast && typeof ast === "object") { + const keys = Object.keys(ast); + for(i = 0; i < keys.length; i++) { + const value = ast[keys[i]]; + if(Array.isArray(value)) { + const pathResult = getPathInAst(value, node); + if(typeof pathResult !== "undefined") + return pathResult; + } else if(value && typeof value === "object") { + const enterResult = enterNode(value); + if(typeof enterResult !== "undefined") + return enterResult; + } + } + } + + function enterNode(n) { + const r = n.range; + if(r) { + if(r[0] <= nr[0] && r[1] >= nr[1]) { + const path = getPathInAst(n, node); + if(path) { + path.push(n); + return path; + } + } + } + return undefined; + } +} + +class ConcatenatedModule extends Module { + constructor(rootModule, modules) { + super(); + super.setChunks(rootModule._chunks); + this.rootModule = rootModule; + this.usedExports = rootModule.usedExports; + this.providedExports = rootModule.providedExports; + this.optimizationBailout = rootModule.optimizationBailout; + this.used = rootModule.used; + this.index = rootModule.index; + this.index2 = rootModule.index2; + this.depth = rootModule.depth; + this.built = modules.some(m => m.built); + this.cacheable = modules.every(m => m.cacheable); + const modulesSet = new Set(modules); + this.reasons = rootModule.reasons.filter(reason => !modulesSet.has(reason.module)); + this.meta = rootModule.meta; + this.moduleArgument = rootModule.moduleArgument; + this.exportsArgument = rootModule.exportsArgument; + this.strict = true; + this._numberOfConcatenatedModules = modules.length; + + this.dependencies = []; + this.dependenciesWarnings = []; + this.dependenciesErrors = []; + this.fileDependencies = []; + this.contextDependencies = []; + this.warnings = []; + this.errors = []; + this.assets = {}; + this._orderedConcatenationList = this._createOrderedConcatenationList(rootModule, modulesSet); + for(const info of this._orderedConcatenationList) { + if(info.type === "concatenated") { + const m = info.module; + + // populate dependencies + m.dependencies.filter(dep => !modulesSet.has(dep.module)) + .forEach(d => this.dependencies.push(d)); + // populate dep warning + m.dependenciesWarnings.forEach(depWarning => this.dependenciesWarnings.push(depWarning)); + // populate dep errors + m.dependenciesErrors.forEach(depError => this.dependenciesErrors.push(depError)); + // populate file dependencies + if(m.fileDependencies) m.fileDependencies.forEach(file => this.fileDependencies.push(file)); + // populate context dependencies + if(m.contextDependencies) m.contextDependencies.forEach(context => this.contextDependencies.push(context)); + // populate warnings + m.warnings.forEach(warning => this.warnings.push(warning)); + // populate errors + m.errors.forEach(error => this.errors.push(error)); + + Object.assign(this.assets, m.assets); + } + } + } + + get modules() { + return this._orderedConcatenationList + .filter(info => info.type === "concatenated") + .map(info => info.module); + } + + identifier() { + return this._orderedConcatenationList.map(info => { + switch(info.type) { + case "concatenated": + return info.module.identifier(); + } + }).filter(Boolean).join(" "); + } + + readableIdentifier(requestShortener) { + return this.rootModule.readableIdentifier(requestShortener) + ` + ${this._numberOfConcatenatedModules - 1} modules`; + } + + libIdent(options) { + return this.rootModule.libIdent(options); + } + + nameForCondition() { + return this.rootModule.nameForCondition(); + } + + build(options, compilation, resolver, fs, callback) { + throw new Error("Cannot build this module. It should be already built."); + } + + size() { + // Guess size from embedded modules + return this._orderedConcatenationList.reduce((sum, info) => { + switch(info.type) { + case "concatenated": + return sum + info.module.size(); + case "external": + return sum + 5; + } + return sum; + }, 0); + } + + _createOrderedConcatenationList(rootModule, modulesSet) { + const list = []; + const set = new Set(); + + function getConcatenatedImports(module) { + // TODO need changes when merging with the pure-module branch + const allDeps = module.dependencies + .filter(dep => dep instanceof HarmonyImportDependency && dep.module); + + return allDeps.map(dep => () => dep.module); + } + + function enterModule(getModule) { + const module = getModule(); + if(set.has(module)) return; + set.add(module); + if(modulesSet.has(module)) { + const imports = getConcatenatedImports(module); + imports.forEach(enterModule); + list.push({ + type: "concatenated", + module + }); + } else { + list.push({ + type: "external", + get module() { + // We need to use a getter here, because the module in the dependency + // could be replaced by some other process (i. e. also replaced with a + // concatenated module) + return getModule(); + } + }); + } + } + + enterModule(() => rootModule); + + return list; + } + + source(dependencyTemplates, outputOptions, requestShortener) { + // Metainfo for each module + const modulesWithInfo = this._orderedConcatenationList.map((info, idx) => { + switch(info.type) { + case "concatenated": + { + const exportMap = new Map(); + const reexportMap = new Map(); + info.module.dependencies.forEach(dep => { + if(dep instanceof HarmonyExportSpecifierDependency) { + exportMap.set(dep.name, dep.id); + } else if(dep instanceof HarmonyExportExpressionDependency) { + exportMap.set("default", "__WEBPACK_MODULE_DEFAULT_EXPORT__"); + } else if(dep instanceof HarmonyExportImportedSpecifierDependency) { + const exportName = dep.name; + const importName = dep.id; + const importedModule = dep.importDependency.module; + if(exportName && importName) { + reexportMap.set(exportName, { + module: importedModule, + exportName: importName, + dependency: dep + }); + } else if(exportName) { + reexportMap.set(exportName, { + module: importedModule, + exportName: true, + dependency: dep + }); + } else { + var activeExports = new Set(HarmonyModulesHelpers.getActiveExports(dep.originModule, dep)); + importedModule.providedExports.forEach(name => { + if(activeExports.has(name) || name === "default") + return; + reexportMap.set(name, { + module: importedModule, + exportName: name, + dependency: dep + }); + }); + } + } + }); + return { + type: "concatenated", + module: info.module, + index: idx, + ast: undefined, + source: undefined, + globalScope: undefined, + moduleScope: undefined, + internalNames: new Map(), + exportMap: exportMap, + reexportMap: reexportMap, + needCompatibilityFlag: false, + hasNamespaceObject: false, + namespaceObjectSource: null + }; + } + case "external": + return { + type: "external", + module: info.module, + index: idx, + name: undefined, + interopName: undefined, + interop: undefined + }; + default: + throw new Error(`Unsupported concatenation entry type ${info.type}`); + } + }); + + // Create mapping from module to info + const moduleToInfoMap = new Map(); + modulesWithInfo.forEach(m => moduleToInfoMap.set(m.module, m)); + + // Configure template decorators for dependencies + const innerDependencyTemplates = new Map(dependencyTemplates); + + innerDependencyTemplates.set(HarmonyImportSpecifierDependency, new HarmonyImportSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyImportSpecifierDependency), + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyImportDependency, new HarmonyImportDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyImportDependency), + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyExportSpecifierDependency, new HarmonyExportSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportSpecifierDependency), + this.rootModule + )); + innerDependencyTemplates.set(HarmonyExportExpressionDependency, new HarmonyExportExpressionDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportExpressionDependency), + this.rootModule, + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyExportImportedSpecifierDependency, new HarmonyExportImportedSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportImportedSpecifierDependency), + this.rootModule, + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyCompatibilityDependency, new HarmonyCompatibilityDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyCompatibilityDependency), + this.rootModule, + moduleToInfoMap + )); + innerDependencyTemplates.set("hash", innerDependencyTemplates.get("hash") + this.rootModule.identifier()); + + // Generate source code and analyse scopes + // Prepare a ReplaceSource for the final source + modulesWithInfo.forEach(info => { + if(info.type === "concatenated") { + const m = info.module; + const source = m.source(innerDependencyTemplates, outputOptions, requestShortener); + const code = source.source(); + let ast; + try { + ast = acorn.parse(code, { + ranges: true, + locations: true, + ecmaVersion: Parser.ECMA_VERSION, + sourceType: "module" + }); + } catch(err) { + if(err.loc && typeof err.loc === "object" && typeof err.loc.line === "number") { + const lineNumber = err.loc.line; + const lines = code.split("\n"); + err.message += "\n| " + lines.slice(Math.max(0, lineNumber - 3), lineNumber + 2).join("\n| "); + } + throw err; + } + const scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: "module", + optimistic: true, + ignoreEval: true, + impliedStrict: true + }); + const globalScope = scopeManager.acquire(ast); + const moduleScope = globalScope.childScopes[0]; + const resultSource = new ReplaceSource(source); + info.ast = ast; + info.source = resultSource; + info.globalScope = globalScope; + info.moduleScope = moduleScope; + } + }); + + // List of all used names to avoid conflicts + const allUsedNames = new Set([ + "__WEBPACK_MODULE_DEFAULT_EXPORT__", // avoid using this internal name + + "abstract", "arguments", "await", "boolean", "break", "byte", "case", "catch", "char", "class", + "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "eval", + "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", + "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", + "null", "package", "private", "protected", "public", "return", "short", "static", "super", + "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", + "var", "void", "volatile", "while", "with", "yield", + + "module", "__dirname", "__filename", "exports", + + "Array", "Date", "eval", "function", "hasOwnProperty", "Infinity", "isFinite", "isNaN", + "isPrototypeOf", "length", "Math", "NaN", "name", "Number", "Object", "prototype", "String", + "toString", "undefined", "valueOf", + + "alert", "all", "anchor", "anchors", "area", "assign", "blur", "button", "checkbox", + "clearInterval", "clearTimeout", "clientInformation", "close", "closed", "confirm", "constructor", + "crypto", "decodeURI", "decodeURIComponent", "defaultStatus", "document", "element", "elements", + "embed", "embeds", "encodeURI", "encodeURIComponent", "escape", "event", "fileUpload", "focus", + "form", "forms", "frame", "innerHeight", "innerWidth", "layer", "layers", "link", "location", + "mimeTypes", "navigate", "navigator", "frames", "frameRate", "hidden", "history", "image", + "images", "offscreenBuffering", "open", "opener", "option", "outerHeight", "outerWidth", + "packages", "pageXOffset", "pageYOffset", "parent", "parseFloat", "parseInt", "password", "pkcs11", + "plugin", "prompt", "propertyIsEnum", "radio", "reset", "screenX", "screenY", "scroll", "secure", + "select", "self", "setInterval", "setTimeout", "status", "submit", "taint", "text", "textarea", + "top", "unescape", "untaint", "window", + + "onblur", "onclick", "onerror", "onfocus", "onkeydown", "onkeypress", "onkeyup", "onmouseover", + "onload", "onmouseup", "onmousedown", "onsubmit" + ]); + + // get all global names + modulesWithInfo.forEach(info => { + if(info.globalScope) { + info.globalScope.through.forEach(reference => { + const name = reference.identifier.name; + if(/^__WEBPACK_MODULE_REFERENCE__\d+_([\da-f]+|ns)(_call)?__$/.test(name)) { + for(const s of getSymbolsFromScope(reference.from, info.moduleScope)) { + allUsedNames.add(s); + } + } else { + allUsedNames.add(name); + } + }); + } + }); + + // generate names for symbols + modulesWithInfo.forEach(info => { + switch(info.type) { + case "concatenated": + { + const namespaceObjectName = this.findNewName("namespaceObject", allUsedNames, null, info.module.readableIdentifier(requestShortener)); + allUsedNames.add(namespaceObjectName); + info.internalNames.set(namespaceObjectName, namespaceObjectName); + info.exportMap.set(true, namespaceObjectName); + info.moduleScope.variables.forEach(variable => { + const name = variable.name; + if(allUsedNames.has(name)) { + const references = getAllReferences(variable); + const symbolsInReferences = references.map(ref => getSymbolsFromScope(ref.from, info.moduleScope)).reduce(reduceSet, new Set()); + const newName = this.findNewName(name, allUsedNames, symbolsInReferences, info.module.readableIdentifier(requestShortener)); + allUsedNames.add(newName); + info.internalNames.set(name, newName); + const source = info.source; + const allIdentifiers = new Set(references.map(r => r.identifier).concat(variable.identifiers)); + for(const identifier of allIdentifiers) { + const r = identifier.range; + const path = getPathInAst(info.ast, identifier); + if(path && path.length > 1 && path[1].type === "Property" && path[1].shorthand) { + source.insert(r[1], `: ${newName}`); + } else { + source.replace(r[0], r[1] - 1, newName); + } + } + } else { + allUsedNames.add(name); + info.internalNames.set(name, name); + } + }); + break; + } + case "external": + { + info.interop = info.module.meta && !info.module.meta.harmonyModule; + const externalName = this.findNewName("", allUsedNames, null, info.module.readableIdentifier(requestShortener)); + allUsedNames.add(externalName); + info.name = externalName; + if(info.interop) { + const externalNameInterop = this.findNewName("default", allUsedNames, null, info.module.readableIdentifier(requestShortener)); + allUsedNames.add(externalNameInterop); + info.interopName = externalNameInterop; + } + break; + } + } + }); + + // Find and replace referenced to modules + modulesWithInfo.forEach(info => { + if(info.type === "concatenated") { + info.globalScope.through.forEach(reference => { + const name = reference.identifier.name; + const match = /^__WEBPACK_MODULE_REFERENCE__(\d+)_([\da-f]+|ns)(_call)?__$/.exec(name); + if(match) { + const referencedModule = modulesWithInfo[+match[1]]; + let exportName; + if(match[2] === "ns") { + exportName = true; + } else { + const exportData = match[2]; + exportName = new Buffer(exportData, "hex").toString("utf-8"); // eslint-disable-line node/no-deprecated-api + } + const asCall = !!match[3]; + const finalName = getFinalName(referencedModule, exportName, moduleToInfoMap, requestShortener, asCall); + const r = reference.identifier.range; + const source = info.source; + source.replace(r[0], r[1] - 1, finalName); + } + }); + } + }); + + const result = new ConcatSource(); + + // add harmony compatibility flag (must be first because of possible circular dependencies) + if(moduleToInfoMap.get(this.rootModule).needCompatibilityFlag) { + result.add(`Object.defineProperty(${this.exportsArgument || "exports"}, "__esModule", { value: true });\n`); + } + + // define required namespace objects (must be before evaluation modules) + modulesWithInfo.forEach(info => { + if(info.namespaceObjectSource) { + result.add(info.namespaceObjectSource); + } + }); + + // evaluate modules in order + modulesWithInfo.forEach(info => { + switch(info.type) { + case "concatenated": + result.add(`\n// CONCATENATED MODULE: ${info.module.readableIdentifier(requestShortener)}\n`); + result.add(info.source); + break; + case "external": + result.add(`\n// EXTERNAL MODULE: ${info.module.readableIdentifier(requestShortener)}\n`); + result.add(`var ${info.name} = __webpack_require__(${JSON.stringify(info.module.id)});\n`); + if(info.interop) { + result.add(`var ${info.interopName} = /*#__PURE__*/__webpack_require__.n(${info.name});\n`); + } + break; + default: + throw new Error(`Unsupported concatenation entry type ${info.type}`); + } + }); + + return result; + } + + findNewName(oldName, usedNamed1, usedNamed2, extraInfo) { + let name = oldName; + + if(name === "__WEBPACK_MODULE_DEFAULT_EXPORT__") + name = ""; + + // Remove uncool stuff + extraInfo = extraInfo.replace(/\.+\/|(\/index)?\.([a-zA-Z0-9]{1,4})($|\s|\?)|\s*\+\s*\d+\s*modules/g, ""); + + const splittedInfo = extraInfo.split("/"); + while(splittedInfo.length) { + name = splittedInfo.pop() + (name ? "_" + name : ""); + const nameIdent = Template.toIdentifier(name); + if(!usedNamed1.has(nameIdent) && (!usedNamed2 || !usedNamed2.has(nameIdent))) return nameIdent; + } + + let i = 0; + let nameWithNumber = Template.toIdentifier(`${name}_${i}`); + while(usedNamed1.has(nameWithNumber) || (usedNamed2 && usedNamed2.has(nameWithNumber))) { + i++; + nameWithNumber = Template.toIdentifier(`${name}_${i}`); + } + return nameWithNumber; + } + + updateHash(hash) { + for(const info of this._orderedConcatenationList) { + switch(info.type) { + case "concatenated": + info.module.updateHash(hash); + break; + case "external": + hash.update(`${info.module.id}`); + break; + } + } + super.updateHash(hash); + } + +} + +class HarmonyImportSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, modulesMap) { + this.originalTemplate = originalTemplate; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + const module = dep.importDependency.module; + const info = this.modulesMap.get(module); + if(!info) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + return; + } + let content; + if(dep.id === null) { + content = `__WEBPACK_MODULE_REFERENCE__${info.index}_ns__`; + } else if(dep.namespaceObjectAsContext) { + content = `__WEBPACK_MODULE_REFERENCE__${info.index}_ns__[${JSON.stringify(dep.id)}]`; + } else { + const exportData = new Buffer(dep.id, "utf-8").toString("hex"); // eslint-disable-line node/no-deprecated-api + content = `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportData}${dep.call ? "_call" : ""}__`; + } + if(dep.shorthand) { + content = dep.name + ": " + content; + } + source.replace(dep.range[0], dep.range[1] - 1, content); + } +} + +class HarmonyImportDependencyConcatenatedTemplate { + constructor(originalTemplate, modulesMap) { + this.originalTemplate = originalTemplate; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + const module = dep.module; + const info = this.modulesMap.get(module); + if(!info) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + return; + } + source.replace(dep.range[0], dep.range[1] - 1, ""); + } +} + +class HarmonyExportSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + } + } +} + +class HarmonyExportExpressionDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + let content = "/* harmony default export */ var __WEBPACK_MODULE_DEFAULT_EXPORT__ = "; + if(dep.originModule === this.rootModule) { + const used = dep.originModule.isUsed("default"); + const exportsName = dep.originModule.exportsArgument || "exports"; + if(used) content += `${exportsName}[${JSON.stringify(used)}] = `; + } + + if(dep.range) { + source.replace(dep.rangeStatement[0], dep.range[0] - 1, content + "("); + source.replace(dep.range[1], dep.rangeStatement[1] - 1, ");"); + return; + } + + source.replace(dep.rangeStatement[0], dep.rangeStatement[1] - 1, content); + } +} + +class HarmonyExportImportedSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule, modulesMap) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + this.modulesMap = modulesMap; + } + + getExports(dep) { + const active = HarmonyModulesHelpers.isActive(dep.originModule, dep); + if(!active) return []; + const importModule = dep.importDependency.module; + if(dep.id) { + // export { named } from "module" + return [{ + name: dep.name, + id: dep.id, + module: importModule + }]; + } + if(dep.name) { + // export * as abc from "module" + return [{ + name: dep.name, + id: true, + module: importModule + }]; + } + // export * from "module" + const activeExports = new Set(HarmonyModulesHelpers.getActiveExports(dep.originModule, dep)); + return importModule.providedExports.filter(exp => exp !== "default" && !activeExports.has(exp)).map(exp => { + return { + name: exp, + id: exp, + module: importModule + }; + }); + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + if(this.modulesMap.get(dep.importDependency.module)) { + const exportDefs = this.getExports(dep); + exportDefs.forEach(def => { + const info = this.modulesMap.get(def.module); + const used = dep.originModule.isUsed(def.name); + if(!used) { + source.insert(-1, `/* unused concated harmony import ${dep.name} */\n`); + } + let finalName; + if(def.id === true) { + finalName = `__WEBPACK_MODULE_REFERENCE__${info.index}_ns__`; + } else { + const exportData = new Buffer(def.id, "utf-8").toString("hex"); // eslint-disable-line node/no-deprecated-api + finalName = `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportData}__`; + } + const exportsName = this.rootModule.exportsArgument || "exports"; + const content = `/* concated harmony reexport */__webpack_require__.d(${exportsName}, ${JSON.stringify(used)}, function() { return ${finalName}; });\n`; + source.insert(-1, content); + }); + } else { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + } + } + } +} + +class HarmonyCompatibilityDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule, modulesMap) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + this.modulesMap.get(this.rootModule).needCompatibilityFlag = true; + } + } +} + +module.exports = ConcatenatedModule; diff --git a/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js b/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js index 71ee18533..46324c4e9 100644 --- a/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js +++ b/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js @@ -8,16 +8,19 @@ class EnsureChunkConditionsPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { + const triesMap = new Map(); compilation.plugin(["optimize-chunks-basic", "optimize-extracted-chunks-basic"], (chunks) => { let changed = false; chunks.forEach((chunk) => { - chunk.modules.slice().forEach((module) => { + chunk.forEachModule((module) => { if(!module.chunkCondition) return; if(!module.chunkCondition(chunk)) { - const usedChunks = module._EnsureChunkConditionsPlugin_usedChunks = (module._EnsureChunkConditionsPlugin_usedChunks || []).concat(chunk); + let usedChunks = triesMap.get(module); + if(!usedChunks) triesMap.set(module, usedChunks = new Set()); + usedChunks.add(chunk); const newChunks = []; chunk.parents.forEach((parent) => { - if(usedChunks.indexOf(parent) < 0) { + if(!usedChunks.has(parent)) { parent.addModule(module); newChunks.push(parent); } diff --git a/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js b/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js index e8b5a9457..75277b5aa 100644 --- a/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js +++ b/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js @@ -17,13 +17,13 @@ class FlagIncludedChunksPlugin { // instead of swapping A and B just bail // as we loop twice the current A will be B and B then A - if(chunkA.modules.length < chunkB.modules.length) return; + if(chunkA.getNumberOfModules() < chunkB.getNumberOfModules()) return; - if(chunkB.modules.length === 0) return; + if(chunkB.getNumberOfModules() === 0) return; // is chunkB in chunkA? - for(let i = 0; i < chunkB.modules.length; i++) { - if(chunkA.modules.indexOf(chunkB.modules[i]) < 0) return; + for(const m of chunkB.modulesIterable) { + if(!chunkA.containsModule(m)) return; } chunkA.ids.push(chunkB.id); }); diff --git a/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js b/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js index 90df06b51..7b006fd17 100644 --- a/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js +++ b/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js @@ -4,23 +4,18 @@ */ "use strict"; -function getChunkIdentifier(chunk) { - return chunk.modules.map((m) => { - return m.identifier(); - }).sort().join(", "); -} - class MergeDuplicateChunksPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { compilation.plugin("optimize-chunks-basic", (chunks) => { - const map = {}; + const map = Object.create(null); chunks.slice().forEach((chunk) => { if(chunk.hasRuntime() || chunk.hasEntryModule()) return; - const ident = getChunkIdentifier(chunk); - if(map[ident]) { - if(map[ident].integrate(chunk, "duplicate")) + const ident = chunk.getModulesIdent(); + const otherChunk = map[ident]; + if(otherChunk) { + if(otherChunk.integrate(chunk, "duplicate")) chunks.splice(chunks.indexOf(chunk), 1); return; } diff --git a/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js b/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js new file mode 100644 index 000000000..9e797c75e --- /dev/null +++ b/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js @@ -0,0 +1,307 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); +const ModuleHotAcceptDependency = require("../dependencies/ModuleHotAcceptDependency"); +const ModuleHotDeclineDependency = require("../dependencies/ModuleHotDeclineDependency"); +const ConcatenatedModule = require("./ConcatenatedModule"); +const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency"); +const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency"); + +function formatBailoutReason(msg) { + return "ModuleConcatenation bailout: " + msg; +} + +class ModuleConcatenationPlugin { + constructor(options) { + if(typeof options !== "object") options = {}; + this.options = options; + } + + apply(compiler) { + compiler.plugin("compilation", (compilation, params) => { + params.normalModuleFactory.plugin("parser", (parser, parserOptions) => { + parser.plugin("call eval", () => { + parser.state.module.meta.hasEval = true; + }); + }); + const bailoutReasonMap = new Map(); + + function setBailoutReason(module, reason) { + bailoutReasonMap.set(module, reason); + module.optimizationBailout.push(typeof reason === "function" ? (rs) => formatBailoutReason(reason(rs)) : formatBailoutReason(reason)); + } + + function getBailoutReason(module, requestShortener) { + const reason = bailoutReasonMap.get(module); + if(typeof reason === "function") return reason(requestShortener); + return reason; + } + + compilation.plugin("optimize-chunk-modules", (chunks, modules) => { + const relevantModules = []; + const possibleInners = new Set(); + for(const module of modules) { + // Only harmony modules are valid for optimization + if(!module.meta || !module.meta.harmonyModule || !module.dependencies.some(d => d instanceof HarmonyCompatibilityDependency)) { + setBailoutReason(module, "Module is not an ECMAScript module"); + continue; + } + + // Because of variable renaming we can't use modules with eval + if(module.meta && module.meta.hasEval) { + setBailoutReason(module, "Module uses eval()"); + continue; + } + + // Exports must be known (and not dynamic) + if(!Array.isArray(module.providedExports)) { + setBailoutReason(module, "Module exports are unknown"); + continue; + } + + // Using dependency variables is not possible as this wraps the code in a function + if(module.variables.length > 0) { + setBailoutReason(module, `Module uses injected variables (${module.variables.map(v => v.name).join(", ")})`); + continue; + } + + // Hot Module Replacement need it's own module to work correctly + if(module.dependencies.some(dep => dep instanceof ModuleHotAcceptDependency || dep instanceof ModuleHotDeclineDependency)) { + setBailoutReason(module, "Module uses Hot Module Replacement"); + continue; + } + + relevantModules.push(module); + + // Module must not be the entry points + if(module.getChunks().some(chunk => chunk.entryModule === module)) { + setBailoutReason(module, "Module is an entry point"); + continue; + } + + // Module must only be used by Harmony Imports + const nonHarmonyReasons = module.reasons.filter(reason => !(reason.dependency instanceof HarmonyImportDependency)); + if(nonHarmonyReasons.length > 0) { + const importingModules = new Set(nonHarmonyReasons.map(r => r.module)); + const importingModuleTypes = new Map(Array.from(importingModules).map(m => [m, new Set(nonHarmonyReasons.filter(r => r.module === m).map(r => r.dependency.type).sort())])); + setBailoutReason(module, (requestShortener) => { + const names = Array.from(importingModules).map(m => `${m.readableIdentifier(requestShortener)} (referenced with ${Array.from(importingModuleTypes.get(m)).join(", ")})`).sort(); + return `Module is referenced from these modules with unsupported syntax: ${names.join(", ")}`; + }); + continue; + } + + possibleInners.add(module); + } + // sort by depth + // modules with lower depth are more likely suited as roots + // this improves performance, because modules already selected as inner are skipped + relevantModules.sort((a, b) => { + return a.depth - b.depth; + }); + const concatConfigurations = []; + const usedAsInner = new Set(); + for(const currentRoot of relevantModules) { + // when used by another configuration as inner: + // the other configuration is better and we can skip this one + if(usedAsInner.has(currentRoot)) + continue; + + // create a configuration with the root + const currentConfiguration = new ConcatConfiguration(currentRoot); + + // cache failures to add modules + const failureCache = new Map(); + + // try to add all imports + for(const imp of this.getImports(currentRoot)) { + const problem = this.tryToAdd(currentConfiguration, imp, possibleInners, failureCache); + if(problem) { + failureCache.set(imp, problem); + currentConfiguration.addWarning(imp, problem); + } + } + if(!currentConfiguration.isEmpty()) { + concatConfigurations.push(currentConfiguration); + for(const module of currentConfiguration.modules) { + if(module !== currentConfiguration.rootModule) + usedAsInner.add(module); + } + } + } + // HACK: Sort configurations by length and start with the longest one + // to get the biggers groups possible. Used modules are marked with usedModules + // TODO: Allow to reuse existing configuration while trying to add dependencies. + // This would improve performance. O(n^2) -> O(n) + concatConfigurations.sort((a, b) => { + return b.modules.size - a.modules.size; + }); + const usedModules = new Set(); + for(const concatConfiguration of concatConfigurations) { + if(usedModules.has(concatConfiguration.rootModule)) + continue; + const newModule = new ConcatenatedModule(concatConfiguration.rootModule, Array.from(concatConfiguration.modules)); + concatConfiguration.sortWarnings(); + for(const warning of concatConfiguration.warnings) { + newModule.optimizationBailout.push((requestShortener) => { + const reason = getBailoutReason(warning[0], requestShortener); + const reasonWithPrefix = reason ? ` (<- ${reason})` : ""; + if(warning[0] === warning[1]) + return formatBailoutReason(`Cannot concat with ${warning[0].readableIdentifier(requestShortener)}${reasonWithPrefix}`); + else + return formatBailoutReason(`Cannot concat with ${warning[0].readableIdentifier(requestShortener)} because of ${warning[1].readableIdentifier(requestShortener)}${reasonWithPrefix}`); + }); + } + const chunks = concatConfiguration.rootModule.getChunks(); + for(const m of concatConfiguration.modules) { + usedModules.add(m); + chunks.forEach(chunk => chunk.removeModule(m)); + } + chunks.forEach(chunk => { + chunk.addModule(newModule); + if(chunk.entryModule === concatConfiguration.rootModule) + chunk.entryModule = newModule; + }); + compilation.modules.push(newModule); + newModule.reasons.forEach(reason => reason.dependency.module = newModule); + newModule.dependencies.forEach(dep => { + if(dep.module) { + dep.module.reasons.forEach(reason => { + if(reason.dependency === dep) + reason.module = newModule; + }); + } + }); + } + compilation.modules = compilation.modules.filter(m => !usedModules.has(m)); + }); + }); + } + + getImports(module) { + return Array.from(new Set(module.dependencies + + // Only harmony Dependencies + .filter(dep => dep instanceof HarmonyImportDependency && dep.module) + + // Dependencies are simple enough to concat them + .filter(dep => { + return !module.dependencies.some(d => + d instanceof HarmonyExportImportedSpecifierDependency && + d.importDependency === dep && + !d.id && + !Array.isArray(dep.module.providedExports) + ); + }) + + // Take the imported module + .map(dep => dep.module) + )); + } + + tryToAdd(config, module, possibleModules, failureCache) { + const cacheEntry = failureCache.get(module); + if(cacheEntry) { + return cacheEntry; + } + + // Already added? + if(config.has(module)) { + return null; + } + + // Not possible to add? + if(!possibleModules.has(module)) { + failureCache.set(module, module); // cache failures for performance + return module; + } + + // module must be in the same chunks + if(!config.rootModule.hasEqualsChunks(module)) { + failureCache.set(module, module); // cache failures for performance + return module; + } + + // Clone config to make experimental changes + const testConfig = config.clone(); + + // Add the module + testConfig.add(module); + + // Every module which depends on the added module must be in the configuration too. + for(const reason of module.reasons) { + const problem = this.tryToAdd(testConfig, reason.module, possibleModules, failureCache); + if(problem) { + failureCache.set(module, problem); // cache failures for performance + return problem; + } + } + + // Eagerly try to add imports too if possible + for(const imp of this.getImports(module)) { + const problem = this.tryToAdd(testConfig, imp, possibleModules, failureCache); + if(problem) { + config.addWarning(module, problem); + } + } + + // Commit experimental changes + config.set(testConfig); + return null; + } +} + +class ConcatConfiguration { + constructor(rootModule) { + this.rootModule = rootModule; + this.modules = new Set([rootModule]); + this.warnings = new Map(); + } + + add(module) { + this.modules.add(module); + } + + has(module) { + return this.modules.has(module); + } + + isEmpty() { + return this.modules.size === 1; + } + + addWarning(module, problem) { + this.warnings.set(module, problem); + } + + sortWarnings() { + this.warnings = new Map(Array.from(this.warnings).sort((a, b) => { + const ai = a[0].identifier(); + const bi = b[0].identifier(); + if(ai < bi) return -1; + if(ai > bi) return 1; + return 0; + })); + } + + clone() { + const clone = new ConcatConfiguration(this.rootModule); + for(const module of this.modules) + clone.add(module); + for(const pair of this.warnings) + clone.addWarning(pair[0], pair[1]); + return clone; + } + + set(config) { + this.rootModule = config.rootModule; + this.modules = new Set(config.modules); + this.warnings = new Map(config.warnings); + } +} + +module.exports = ModuleConcatenationPlugin; diff --git a/node_modules/webpack/lib/optimize/OccurrenceOrderPlugin.js b/node_modules/webpack/lib/optimize/OccurrenceOrderPlugin.js index a6bb30b34..45ec34719 100644 --- a/node_modules/webpack/lib/optimize/OccurrenceOrderPlugin.js +++ b/node_modules/webpack/lib/optimize/OccurrenceOrderPlugin.js @@ -15,98 +15,84 @@ class OccurrenceOrderPlugin { const preferEntry = this.preferEntry; compiler.plugin("compilation", (compilation) => { compilation.plugin("optimize-module-order", (modules) => { - function entryChunks(m) { - return m.chunks.map((c) => { - const sum = (c.isInitial() ? 1 : 0) + (c.entryModule === m ? 1 : 0); - return sum; - }).reduce((a, b) => { - return a + b; - }, 0); - } + const occursInInitialChunksMap = new Map(); + const occursInAllChunksMap = new Map(); - function occursInEntry(m) { - if(typeof m.__OccurenceOrderPlugin_occursInEntry === "number") return m.__OccurenceOrderPlugin_occursInEntry; - const result = m.reasons.map((r) => { - if(!r.module) return 0; - return entryChunks(r.module); - }).reduce((a, b) => { - return a + b; - }, 0) + entryChunks(m); - return m.__OccurenceOrderPlugin_occursInEntry = result; - } + const initialChunkChunkMap = new Map(); + const entryCountMap = new Map(); + modules.forEach(m => { + let initial = 0; + let entry = 0; + m.forEachChunk(c => { + if(c.isInitial()) initial++; + if(c.entryModule === m) entry++; + }); + initialChunkChunkMap.set(m, initial); + entryCountMap.set(m, entry); + }); + + const countOccursInEntry = (sum, r) => { + if(!r.module) return sum; + return sum + initialChunkChunkMap.get(r.module); + }; + const countOccurs = (sum, r) => { + if(!r.module) return sum; + return sum + r.module.getNumberOfChunks(); + }; - function occurs(m) { - if(typeof m.__OccurenceOrderPlugin_occurs === "number") return m.__OccurenceOrderPlugin_occurs; - const result = m.reasons.map((r) => { - if(!r.module) return 0; - return r.module.chunks.length; - }).reduce((a, b) => { - return a + b; - }, 0) + m.chunks.length + m.chunks.filter((c) => { - return c.entryModule === m; - }).length; - return m.__OccurenceOrderPlugin_occurs = result; + if(preferEntry) { + modules.forEach(m => { + const result = m.reasons.reduce(countOccursInEntry, 0) + initialChunkChunkMap.get(m) + entryCountMap.get(m); + occursInInitialChunksMap.set(m, result); + }); } + + modules.forEach(m => { + const result = m.reasons.reduce(countOccurs, 0) + m.getNumberOfChunks() + entryCountMap.get(m); + occursInAllChunksMap.set(m, result); + }); + modules.sort((a, b) => { if(preferEntry) { - const aEntryOccurs = occursInEntry(a); - const bEntryOccurs = occursInEntry(b); + const aEntryOccurs = occursInInitialChunksMap.get(a); + const bEntryOccurs = occursInInitialChunksMap.get(b); if(aEntryOccurs > bEntryOccurs) return -1; if(aEntryOccurs < bEntryOccurs) return 1; } - const aOccurs = occurs(a); - const bOccurs = occurs(b); + const aOccurs = occursInAllChunksMap.get(a); + const bOccurs = occursInAllChunksMap.get(b); if(aOccurs > bOccurs) return -1; if(aOccurs < bOccurs) return 1; - if(a.identifier() > b.identifier()) return 1; - if(a.identifier() < b.identifier()) return -1; + if(a.index > b.index) return 1; + if(a.index < b.index) return -1; return 0; }); - // TODO refactor to Map - modules.forEach((m) => { - m.__OccurenceOrderPlugin_occursInEntry = undefined; - m.__OccurenceOrderPlugin_occurs = undefined; - }); }); compilation.plugin("optimize-chunk-order", (chunks) => { - function occursInEntry(c) { - if(typeof c.__OccurenceOrderPlugin_occursInEntry === "number") return c.__OccurenceOrderPlugin_occursInEntry; - const result = c.parents.filter((p) => { - return p.isInitial(); - }).length; - return c.__OccurenceOrderPlugin_occursInEntry = result; - } + const occursInInitialChunksMap = new Map(); + + chunks.forEach(c => { + const result = c.parents.reduce((sum, p) => { + if(p.isInitial()) return sum + 1; + return sum; + }, 0); + return occursInInitialChunksMap.set(c, result); + }); function occurs(c) { return c.blocks.length; } - chunks.forEach((c) => { - c.modules.sort((a, b) => { - if(a.identifier() > b.identifier()) return 1; - if(a.identifier() < b.identifier()) return -1; - return 0; - }); - }); + chunks.sort((a, b) => { - const aEntryOccurs = occursInEntry(a); - const bEntryOccurs = occursInEntry(b); + const aEntryOccurs = occursInInitialChunksMap.get(a); + const bEntryOccurs = occursInInitialChunksMap.get(b); if(aEntryOccurs > bEntryOccurs) return -1; if(aEntryOccurs < bEntryOccurs) return 1; const aOccurs = occurs(a); const bOccurs = occurs(b); if(aOccurs > bOccurs) return -1; if(aOccurs < bOccurs) return 1; - if(a.modules.length > b.modules.length) return -1; - if(a.modules.length < b.modules.length) return 1; - for(let i = 0; i < a.modules.length; i++) { - if(a.modules[i].identifier() > b.modules[i].identifier()) return -1; - if(a.modules[i].identifier() < b.modules[i].identifier()) return 1; - } - return 0; - }); - // TODO refactor to Map - chunks.forEach((c) => { - c.__OccurenceOrderPlugin_occursInEntry = undefined; + return a.compareTo(b); }); }); }); diff --git a/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js b/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js index e73add989..43550819c 100644 --- a/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js +++ b/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js @@ -4,59 +4,31 @@ */ "use strict"; -function chunkContainsModule(chunk, module) { - const chunks = module.chunks; - const modules = chunk.modules; - if(chunks.length < modules.length) { - return chunks.indexOf(chunk) >= 0; - } else { - return modules.indexOf(module) >= 0; - } -} - function hasModule(chunk, module, checkedChunks) { - if(chunkContainsModule(chunk, module)) return [chunk]; + if(chunk.containsModule(module)) return [chunk]; if(chunk.parents.length === 0) return false; return allHaveModule(chunk.parents.filter((c) => { - return checkedChunks.indexOf(c) < 0; + return !checkedChunks.has(c); }), module, checkedChunks); } function allHaveModule(someChunks, module, checkedChunks) { - if(!checkedChunks) checkedChunks = []; - var chunks = []; + if(!checkedChunks) checkedChunks = new Set(); + var chunks = new Set(); for(var i = 0; i < someChunks.length; i++) { - checkedChunks.push(someChunks[i]); + checkedChunks.add(someChunks[i]); var subChunks = hasModule(someChunks[i], module, checkedChunks); if(!subChunks) return false; for(var index = 0; index < subChunks.length; index++) { var item = subChunks[index]; - if(!chunks.length || chunks.indexOf(item) < 0) { - chunks.push(item); - } + chunks.add(item); } } return chunks; } -function debugIds(chunks) { - var list = []; - for(var i = 0; i < chunks.length; i++) { - var debugId = chunks[i].debugId; - - if(typeof debugId !== "number") { - return "no"; - } - - list.push(debugId); - } - - list.sort(); - return list.join(","); -} - class RemoveParentModulesPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { @@ -67,19 +39,21 @@ class RemoveParentModulesPlugin { // TODO consider Map when performance has improved https://gist.github.com/sokra/b36098368da7b8f6792fd7c85fca6311 var cache = Object.create(null); - var modules = chunk.modules.slice(); + var modules = chunk.getModules(); for(var i = 0; i < modules.length; i++) { var module = modules[i]; - var dId = debugIds(module.chunks); + var dId = module.getChunkIdsIdent(); var parentChunksWithModule; - if((dId in cache) && dId !== "no") { + if(dId === null) { + parentChunksWithModule = allHaveModule(chunk.parents, module); + } else if(dId in cache) { parentChunksWithModule = cache[dId]; } else { parentChunksWithModule = cache[dId] = allHaveModule(chunk.parents, module); } if(parentChunksWithModule) { - module.rewriteChunkInReasons(chunk, parentChunksWithModule); + module.rewriteChunkInReasons(chunk, Array.from(parentChunksWithModule)); chunk.removeModule(module); } } diff --git a/node_modules/webpack/lib/optimize/UglifyJsPlugin.js b/node_modules/webpack/lib/optimize/UglifyJsPlugin.js index f95dc8eef..1caa10817 100644 --- a/node_modules/webpack/lib/optimize/UglifyJsPlugin.js +++ b/node_modules/webpack/lib/optimize/UglifyJsPlugin.js @@ -4,233 +4,6 @@ */ "use strict"; -const SourceMapConsumer = require("source-map").SourceMapConsumer; -const SourceMapSource = require("webpack-sources").SourceMapSource; -const RawSource = require("webpack-sources").RawSource; -const ConcatSource = require("webpack-sources").ConcatSource; -const RequestShortener = require("../RequestShortener"); -const ModuleFilenameHelpers = require("../ModuleFilenameHelpers"); -const uglify = require("uglify-js"); - -class UglifyJsPlugin { - constructor(options) { - if(typeof options !== "object" || Array.isArray(options)) options = {}; - if(typeof options.compressor !== "undefined") options.compress = options.compressor; - this.options = options; - } - - apply(compiler) { - const options = this.options; - options.test = options.test || /\.js($|\?)/i; - const warningsFilter = options.warningsFilter || (() => true); - - const requestShortener = new RequestShortener(compiler.context); - compiler.plugin("compilation", (compilation) => { - if(options.sourceMap) { - compilation.plugin("build-module", (module) => { - // to get detailed location info about errors - module.useSourceMap = true; - }); - } - compilation.plugin("optimize-chunk-assets", (chunks, callback) => { - const files = []; - chunks.forEach((chunk) => files.push.apply(files, chunk.files)); - files.push.apply(files, compilation.additionalChunkAssets); - const filterdFiles = files.filter(ModuleFilenameHelpers.matchObject.bind(undefined, options)); - filterdFiles.forEach((file) => { - const oldWarnFunction = uglify.AST_Node.warn_function; - const warnings = []; - let sourceMap; - try { - const asset = compilation.assets[file]; - if(asset.__UglifyJsPlugin) { - compilation.assets[file] = asset.__UglifyJsPlugin; - return; - } - let input; - let inputSourceMap; - if(options.sourceMap) { - if(asset.sourceAndMap) { - const sourceAndMap = asset.sourceAndMap(); - inputSourceMap = sourceAndMap.map; - input = sourceAndMap.source; - } else { - inputSourceMap = asset.map(); - input = asset.source(); - } - sourceMap = new SourceMapConsumer(inputSourceMap); - uglify.AST_Node.warn_function = (warning) => { // eslint-disable-line camelcase - const match = /\[.+:([0-9]+),([0-9]+)\]/.exec(warning); - const line = +match[1]; - const column = +match[2]; - const original = sourceMap.originalPositionFor({ - line: line, - column: column - }); - if(!original || !original.source || original.source === file) return; - if(!warningsFilter(original.source)) return; - warnings.push(warning.replace(/\[.+:([0-9]+),([0-9]+)\]/, "") + - "[" + requestShortener.shorten(original.source) + ":" + original.line + "," + original.column + "]"); - }; - } else { - input = asset.source(); - uglify.AST_Node.warn_function = (warning) => { // eslint-disable-line camelcase - warnings.push(warning); - }; - } - uglify.base54.reset(); - let ast = uglify.parse(input, { - filename: file - }); - if(options.compress !== false) { - ast.figure_out_scope(); - const compress = uglify.Compressor(options.compress || { - warnings: false - }); // eslint-disable-line new-cap - ast = compress.compress(ast); - } - if(options.mangle !== false) { - ast.figure_out_scope(options.mangle || {}); - ast.compute_char_frequency(options.mangle || {}); - ast.mangle_names(options.mangle || {}); - if(options.mangle && options.mangle.props) { - uglify.mangle_properties(ast, options.mangle.props); - } - } - const output = {}; - output.comments = Object.prototype.hasOwnProperty.call(options, "comments") ? options.comments : /^\**!|@preserve|@license/; - output.beautify = options.beautify; - for(let k in options.output) { - output[k] = options.output[k]; - } - const extractedComments = []; - if(options.extractComments) { - const condition = {}; - if(typeof options.extractComments === "string" || options.extractComments instanceof RegExp) { - // extractComments specifies the extract condition and output.comments specifies the preserve condition - condition.preserve = output.comments; - condition.extract = options.extractComments; - } else if(Object.prototype.hasOwnProperty.call(options.extractComments, "condition")) { - // Extract condition is given in extractComments.condition - condition.preserve = output.comments; - condition.extract = options.extractComments.condition; - } else { - // No extract condition is given. Extract comments that match output.comments instead of preserving them - condition.preserve = false; - condition.extract = output.comments; - } - - // Ensure that both conditions are functions - ["preserve", "extract"].forEach(key => { - switch(typeof condition[key]) { - case "boolean": - var b = condition[key]; - condition[key] = () => b; - break; - case "function": - break; - case "string": - if(condition[key] === "all") { - condition[key] = () => true; - break; - } - var regex = new RegExp(condition[key]); - condition[key] = (astNode, comment) => regex.test(comment.value); - break; - default: - regex = condition[key]; - condition[key] = (astNode, comment) => regex.test(comment.value); - } - }); - - // Redefine the comments function to extract and preserve - // comments according to the two conditions - output.comments = (astNode, comment) => { - if(condition.extract(astNode, comment)) { - extractedComments.push( - comment.type === "comment2" ? "/*" + comment.value + "*/" : "//" + comment.value - ); - } - return condition.preserve(astNode, comment); - }; - } - let map; - if(options.sourceMap) { - map = uglify.SourceMap({ // eslint-disable-line new-cap - file: file, - root: "" - }); - output.source_map = map; // eslint-disable-line camelcase - } - const stream = uglify.OutputStream(output); // eslint-disable-line new-cap - ast.print(stream); - if(map) map = map + ""; - const stringifiedStream = stream + ""; - let outputSource = (map ? - new SourceMapSource(stringifiedStream, file, JSON.parse(map), input, inputSourceMap) : - new RawSource(stringifiedStream)); - if(extractedComments.length > 0) { - let commentsFile = options.extractComments.filename || file + ".LICENSE"; - if(typeof commentsFile === "function") { - commentsFile = commentsFile(file); - } - - // Write extracted comments to commentsFile - const commentsSource = new RawSource(extractedComments.join("\n\n") + "\n"); - if(commentsFile in compilation.assets) { - // commentsFile already exists, append new comments... - if(compilation.assets[commentsFile] instanceof ConcatSource) { - compilation.assets[commentsFile].add("\n"); - compilation.assets[commentsFile].add(commentsSource); - } else { - compilation.assets[commentsFile] = new ConcatSource( - compilation.assets[commentsFile], "\n", commentsSource - ); - } - } else { - compilation.assets[commentsFile] = commentsSource; - } - - // Add a banner to the original file - if(options.extractComments.banner !== false) { - let banner = options.extractComments.banner || "For license information please see " + commentsFile; - if(typeof banner === "function") { - banner = banner(commentsFile); - } - if(banner) { - outputSource = new ConcatSource( - "/*! " + banner + " */\n", outputSource - ); - } - } - } - asset.__UglifyJsPlugin = compilation.assets[file] = outputSource; - if(warnings.length > 0) { - compilation.warnings.push(new Error(file + " from UglifyJs\n" + warnings.join("\n"))); - } - } catch(err) { - if(err.line) { - const original = sourceMap && sourceMap.originalPositionFor({ - line: err.line, - column: err.col - }); - if(original && original.source) { - compilation.errors.push(new Error(file + " from UglifyJs\n" + err.message + " [" + requestShortener.shorten(original.source) + ":" + original.line + "," + original.column + "][" + file + ":" + err.line + "," + err.col + "]")); - } else { - compilation.errors.push(new Error(file + " from UglifyJs\n" + err.message + " [" + file + ":" + err.line + "," + err.col + "]")); - } - } else if(err.msg) { - compilation.errors.push(new Error(file + " from UglifyJs\n" + err.msg)); - } else - compilation.errors.push(new Error(file + " from UglifyJs\n" + err.stack)); - } finally { - uglify.AST_Node.warn_function = oldWarnFunction; // eslint-disable-line camelcase - } - }); - callback(); - }); - }); - } -} +const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); module.exports = UglifyJsPlugin; diff --git a/node_modules/webpack/lib/prepareOptions.js b/node_modules/webpack/lib/prepareOptions.js new file mode 100644 index 000000000..0b063a03b --- /dev/null +++ b/node_modules/webpack/lib/prepareOptions.js @@ -0,0 +1,29 @@ +"use strict"; + +module.exports = function prepareOptions(options, argv) { + argv = argv || {}; + + options = handleExport(options); + + if(Array.isArray(options)) { + options = options.map(_options => handleFunction(_options, argv)); + } else { + options = handleFunction(options, argv); + } + return options; +}; + +function handleExport(options) { + const isES6DefaultExported = ( + typeof options === "object" && options !== null && typeof options.default !== "undefined" + ); + options = isES6DefaultExported ? options.default : options; + return options; +} + +function handleFunction(options, argv) { + if(typeof options === "function") { + options = options(argv.env, argv); + } + return options; +} diff --git a/node_modules/webpack/lib/util/Semaphore.js b/node_modules/webpack/lib/util/Semaphore.js new file mode 100644 index 000000000..de9b69dde --- /dev/null +++ b/node_modules/webpack/lib/util/Semaphore.js @@ -0,0 +1,32 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +class Semaphore { + constructor(available) { + this.available = available; + this.waiters = []; + } + + acquire(callback) { + if(this.available > 0) { + this.available--; + callback(); + } else { + this.waiters.push(callback); + } + } + + release() { + if(this.waiters.length > 0) { + const callback = this.waiters.pop(); + process.nextTick(callback); + } else { + this.available++; + } + } +} + +module.exports = Semaphore; diff --git a/node_modules/webpack/lib/util/SortableSet.js b/node_modules/webpack/lib/util/SortableSet.js new file mode 100644 index 000000000..15c7ecb87 --- /dev/null +++ b/node_modules/webpack/lib/util/SortableSet.js @@ -0,0 +1,45 @@ +"use strict"; + +module.exports = class SortableSet extends Set { + + constructor(initialIterable, defaultSort) { + super(initialIterable); + this._sortFn = defaultSort; + this._lastActiveSortFn = null; + } + + /** + * @param {any} value - value to add to set + * @returns {SortableSet} - returns itself + */ + add(value) { + this._lastActiveSortFn = null; + super.add(value); + return this; + } + + /** + * @param {Function} sortFn - function to sort the set + * @returns {void} + */ + sortWith(sortFn) { + if(this.size === 0 || sortFn === this._lastActiveSortFn) { + // already sorted - nothing to do + return; + } + + const sortedArray = Array.from(this).sort(sortFn); + super.clear(); + for(let i = 0; i < sortedArray.length; i += 1) { + this.add(sortedArray[i]); + } + this._lastActiveSortFn = sortFn; + } + + /** + * @returns {void} + */ + sort() { + this.sortWith(this._sortFn); + } +}; diff --git a/node_modules/webpack/lib/util/identifier.js b/node_modules/webpack/lib/util/identifier.js index b1bcbf5df..82e5b811f 100644 --- a/node_modules/webpack/lib/util/identifier.js +++ b/node_modules/webpack/lib/util/identifier.js @@ -7,10 +7,32 @@ const looksLikeAbsolutePath = (maybeAbsolutePath) => { const normalizePathSeparator = (p) => p.replace(/\\/g, "/"); -exports.makePathsRelative = (context, identifier) => { +const _makePathsRelative = (context, identifier) => { return identifier .split(/([|! ])/) .map(str => looksLikeAbsolutePath(str) ? normalizePathSeparator(path.relative(context, str)) : str) .join(""); }; + +exports.makePathsRelative = (context, identifier, cache) => { + if(!cache) return _makePathsRelative(context, identifier); + + const relativePaths = cache.relativePaths || (cache.relativePaths = new Map()); + + let cachedResult; + let contextCache = relativePaths.get(context); + if(typeof contextCache === "undefined") { + relativePaths.set(context, contextCache = new Map()); + } else { + cachedResult = contextCache.get(identifier); + } + + if(typeof cachedResult !== "undefined") { + return cachedResult; + } else { + const relativePath = _makePathsRelative(context, identifier); + contextCache.set(identifier, relativePath); + return relativePath; + } +}; diff --git a/node_modules/webpack/lib/webpack.js b/node_modules/webpack/lib/webpack.js index 3e2353c49..fb8c68b7f 100644 --- a/node_modules/webpack/lib/webpack.js +++ b/node_modules/webpack/lib/webpack.js @@ -58,63 +58,61 @@ webpack.validate = validateSchema.bind(this, webpackOptionsSchema); webpack.validateSchema = validateSchema; webpack.WebpackOptionsValidationError = WebpackOptionsValidationError; -function exportPlugins(exports, path, plugins) { - plugins.forEach(name => { - Object.defineProperty(exports, name, { +function exportPlugins(obj, mappings) { + Object.keys(mappings).forEach(name => { + Object.defineProperty(obj, name, { configurable: false, enumerable: true, - get() { - return require(`${path}/${name}`); - } + get: mappings[name] }); }); } -exportPlugins(exports, ".", [ - "DefinePlugin", - "NormalModuleReplacementPlugin", - "ContextReplacementPlugin", - "IgnorePlugin", - "WatchIgnorePlugin", - "BannerPlugin", - "PrefetchPlugin", - "AutomaticPrefetchPlugin", - "ProvidePlugin", - "HotModuleReplacementPlugin", - "SourceMapDevToolPlugin", - "EvalSourceMapDevToolPlugin", - "EvalDevToolModulePlugin", - "CachePlugin", - "ExtendedAPIPlugin", - "ExternalsPlugin", - "JsonpTemplatePlugin", - "LibraryTemplatePlugin", - "LoaderTargetPlugin", - "MemoryOutputFileSystem", - "ProgressPlugin", - "SetVarMainTemplatePlugin", - "UmdMainTemplatePlugin", - "NoErrorsPlugin", - "NoEmitOnErrorsPlugin", - "NewWatchingPlugin", - "EnvironmentPlugin", - "DllPlugin", - "DllReferencePlugin", - "LoaderOptionsPlugin", - "NamedModulesPlugin", - "NamedChunksPlugin", - "HashedModuleIdsPlugin", - "ModuleFilenameHelpers" -]); -exportPlugins(exports.optimize = {}, "./optimize", [ - "AggressiveMergingPlugin", - "AggressiveSplittingPlugin", - "CommonsChunkPlugin", - "ChunkModuleIdRangePlugin", - "DedupePlugin", - "LimitChunkCountPlugin", - "MinChunkSizePlugin", - "OccurrenceOrderPlugin", - "UglifyJsPlugin" -]); -exportPlugins(exports.dependencies = {}, "./dependencies", []); +exportPlugins(exports, { + "DefinePlugin": () => require("./DefinePlugin"), + "NormalModuleReplacementPlugin": () => require("./NormalModuleReplacementPlugin"), + "ContextReplacementPlugin": () => require("./ContextReplacementPlugin"), + "IgnorePlugin": () => require("./IgnorePlugin"), + "WatchIgnorePlugin": () => require("./WatchIgnorePlugin"), + "BannerPlugin": () => require("./BannerPlugin"), + "PrefetchPlugin": () => require("./PrefetchPlugin"), + "AutomaticPrefetchPlugin": () => require("./AutomaticPrefetchPlugin"), + "ProvidePlugin": () => require("./ProvidePlugin"), + "HotModuleReplacementPlugin": () => require("./HotModuleReplacementPlugin"), + "SourceMapDevToolPlugin": () => require("./SourceMapDevToolPlugin"), + "EvalSourceMapDevToolPlugin": () => require("./EvalSourceMapDevToolPlugin"), + "EvalDevToolModulePlugin": () => require("./EvalDevToolModulePlugin"), + "CachePlugin": () => require("./CachePlugin"), + "ExtendedAPIPlugin": () => require("./ExtendedAPIPlugin"), + "ExternalsPlugin": () => require("./ExternalsPlugin"), + "JsonpTemplatePlugin": () => require("./JsonpTemplatePlugin"), + "LibraryTemplatePlugin": () => require("./LibraryTemplatePlugin"), + "LoaderTargetPlugin": () => require("./LoaderTargetPlugin"), + "MemoryOutputFileSystem": () => require("./MemoryOutputFileSystem"), + "ProgressPlugin": () => require("./ProgressPlugin"), + "SetVarMainTemplatePlugin": () => require("./SetVarMainTemplatePlugin"), + "UmdMainTemplatePlugin": () => require("./UmdMainTemplatePlugin"), + "NoErrorsPlugin": () => require("./NoErrorsPlugin"), + "NoEmitOnErrorsPlugin": () => require("./NoEmitOnErrorsPlugin"), + "NewWatchingPlugin": () => require("./NewWatchingPlugin"), + "EnvironmentPlugin": () => require("./EnvironmentPlugin"), + "DllPlugin": () => require("./DllPlugin"), + "DllReferencePlugin": () => require("./DllReferencePlugin"), + "LoaderOptionsPlugin": () => require("./LoaderOptionsPlugin"), + "NamedModulesPlugin": () => require("./NamedModulesPlugin"), + "NamedChunksPlugin": () => require("./NamedChunksPlugin"), + "HashedModuleIdsPlugin": () => require("./HashedModuleIdsPlugin"), + "ModuleFilenameHelpers": () => require("./ModuleFilenameHelpers") +}); +exportPlugins(exports.optimize = {}, { + "AggressiveMergingPlugin": () => require("./optimize/AggressiveMergingPlugin"), + "AggressiveSplittingPlugin": () => require("./optimize/AggressiveSplittingPlugin"), + "CommonsChunkPlugin": () => require("./optimize/CommonsChunkPlugin"), + "ChunkModuleIdRangePlugin": () => require("./optimize/ChunkModuleIdRangePlugin"), + "DedupePlugin": () => require("./optimize/DedupePlugin"), + "LimitChunkCountPlugin": () => require("./optimize/LimitChunkCountPlugin"), + "MinChunkSizePlugin": () => require("./optimize/MinChunkSizePlugin"), + "ModuleConcatenationPlugin": () => require("./optimize/ModuleConcatenationPlugin"), + "OccurrenceOrderPlugin": () => require("./optimize/OccurrenceOrderPlugin"), + "UglifyJsPlugin": () => require("./optimize/UglifyJsPlugin") +}); diff --git a/node_modules/webpack/lib/webworker/WebWorkerChunkTemplatePlugin.js b/node_modules/webpack/lib/webworker/WebWorkerChunkTemplatePlugin.js index 0b7fa525b..3944f3cfc 100644 --- a/node_modules/webpack/lib/webworker/WebWorkerChunkTemplatePlugin.js +++ b/node_modules/webpack/lib/webworker/WebWorkerChunkTemplatePlugin.js @@ -4,8 +4,8 @@ */ "use strict"; -var ConcatSource = require("webpack-sources").ConcatSource; -var Template = require("../Template"); +const ConcatSource = require("webpack-sources").ConcatSource; +const Template = require("../Template"); class WebWorkerChunkTemplatePlugin { diff --git a/node_modules/webpack/lib/webworker/WebWorkerMainTemplate.runtime.js b/node_modules/webpack/lib/webworker/WebWorkerMainTemplate.runtime.js index bcead37e4..9b6c59fea 100644 --- a/node_modules/webpack/lib/webworker/WebWorkerMainTemplate.runtime.js +++ b/node_modules/webpack/lib/webworker/WebWorkerMainTemplate.runtime.js @@ -13,7 +13,8 @@ module.exports = function() { importScripts($require$.p + $hotChunkFilename$); } - function hotDownloadManifest(callback) { // eslint-disable-line no-unused-vars + function hotDownloadManifest(requestTimeout) { // eslint-disable-line no-unused-vars + requestTimeout = requestTimeout || 10000; return new Promise(function(resolve, reject) { if(typeof XMLHttpRequest === "undefined") return reject(new Error("No browser support")); @@ -21,7 +22,7 @@ module.exports = function() { var request = new XMLHttpRequest(); var requestPath = $require$.p + $hotMainFilename$; request.open("GET", requestPath, true); - request.timeout = 10000; + request.timeout = requestTimeout; request.send(null); } catch(err) { return reject(err); diff --git a/node_modules/webpack/lib/webworker/WebWorkerMainTemplatePlugin.js b/node_modules/webpack/lib/webworker/WebWorkerMainTemplatePlugin.js index 429e2c3d4..cc7615497 100644 --- a/node_modules/webpack/lib/webworker/WebWorkerMainTemplatePlugin.js +++ b/node_modules/webpack/lib/webworker/WebWorkerMainTemplatePlugin.js @@ -17,13 +17,9 @@ class WebWorkerMainTemplatePlugin { "// \"1\" means \"already loaded\"", "var installedChunks = {", this.indent( - chunk.ids.map(function(id) { - return id + ": 1"; - }).join(",\n") + chunk.ids.map((id) => `${id}: 1`).join(",\n") ), - "};", - "", - "var resolvedPromise = new Promise(function(resolve) { resolve(); });" + "};" ]); } return source; @@ -31,22 +27,24 @@ class WebWorkerMainTemplatePlugin { mainTemplate.plugin("require-ensure", function(_, chunk, hash) { const chunkFilename = this.outputOptions.chunkFilename; return this.asString([ - "// \"1\" is the signal for \"already loaded\"", - "if(!installedChunks[chunkId]) {", + "return new Promise(function(resolve) {", this.indent([ - "importScripts(" + - this.applyPluginsWaterfall("asset-path", JSON.stringify(chunkFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function(length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this), - chunk: { - id: "\" + chunkId + \"" - } - }) + ");" + "// \"1\" is the signal for \"already loaded\"", + "if(!installedChunks[chunkId]) {", + this.indent([ + "importScripts(" + + this.applyPluginsWaterfall("asset-path", JSON.stringify(chunkFilename), { + hash: `" + ${this.renderCurrentHashCode(hash)} + "`, + hashWithLength: (length) => `" + ${this.renderCurrentHashCode(hash, length)} + "`, + chunk: { + id: "\" + chunkId + \"" + } + }) + ");" + ]), + "}", + "resolve();" ]), - "}", - "return resolvedPromise;" + "});" ]); }); mainTemplate.plugin("bootstrap", function(source, chunk, hash) { @@ -54,7 +52,7 @@ class WebWorkerMainTemplatePlugin { const chunkCallbackName = this.outputOptions.chunkCallbackName || Template.toIdentifier("webpackChunk" + (this.outputOptions.library || "")); return this.asString([ source, - "this[" + JSON.stringify(chunkCallbackName) + "] = function webpackChunkCallback(chunkIds, moreModules) {", + `this[${JSON.stringify(chunkCallbackName)}] = function webpackChunkCallback(chunkIds, moreModules) {`, this.indent([ "for(var moduleId in moreModules) {", this.indent(this.renderAddModule(hash, chunk, "moduleId", "moreModules[moduleId]")), @@ -72,24 +70,21 @@ class WebWorkerMainTemplatePlugin { const hotUpdateMainFilename = this.outputOptions.hotUpdateMainFilename; const hotUpdateFunction = this.outputOptions.hotUpdateFunction || Template.toIdentifier("webpackHotUpdate" + (this.outputOptions.library || "")); const currentHotUpdateChunkFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateChunkFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function(length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this), + hash: `" + ${this.renderCurrentHashCode(hash)} + "`, + hashWithLength: (length) => `" + ${this.renderCurrentHashCode(hash, length)} + "`, chunk: { id: "\" + chunkId + \"" } }); const currentHotUpdateMainFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateMainFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function(length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this) + hash: `" + ${this.renderCurrentHashCode(hash)} + "`, + hashWithLength: (length) => `" + ${this.renderCurrentHashCode(hash, length)} + "`, }); return source + "\n" + - "var parentHotUpdateCallback = this[" + JSON.stringify(hotUpdateFunction) + "];\n" + - "this[" + JSON.stringify(hotUpdateFunction) + "] = " + Template.getFunctionContent(require("./WebWorkerMainTemplate.runtime.js")) + `var parentHotUpdateCallback = this[${JSON.stringify(hotUpdateFunction)}];\n` + + `this[${JSON.stringify(hotUpdateFunction)}] = ` + + Template.getFunctionContent(require("./WebWorkerMainTemplate.runtime.js")) .replace(/\/\/\$semicolon/g, ";") .replace(/\$require\$/g, this.requireFn) .replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename) -- cgit v1.2.3