rename eager-weak to weak in import() comment

rename ImportEagerWeak to ImportWeak
rename "eager-weak" asyncMode to "async-weak"

weak dependencies don't need to be in dependencies blocks
This commit is contained in:
Tobias Koppers 2017-07-26 14:49:37 +02:00
parent 7779847692
commit 94e0fcb80a
7 changed files with 93 additions and 110 deletions

View File

@ -140,28 +140,15 @@ class ContextModule extends Module {
this.addBlock(block); this.addBlock(block);
} }
} else if(this.async === "weak") { } else if(this.async === "weak" || this.async === "async-weak") {
this.dependencies = dependencies; this.dependencies = dependencies;
// if we are weak create a new async dependency block per dependency // we mark all dependencies as weak
// and add all blocks to this context, but mark each dep as weak, to dependencies.forEach(dep => dep.weak = true);
// prevent them from being bundled in the parent this.dependencies = dependencies;
dependencies.forEach((dep, idx) => {
dep.weak = true;
let chunkName = this.chunkName;
if(chunkName) {
if(!/\[(index|request)\]/.test(chunkName))
chunkName += "[index]";
chunkName = chunkName.replace(/\[index\]/g, idx);
chunkName = chunkName.replace(/\[request\]/g, Template.toPath(dep.userRequest));
}
const block = new AsyncDependenciesBlock(chunkName, dep.module, dep.loc);
block.addDependency(dep);
this.addBlock(block);
});
} else { } else {
// if we are lazy or eager-weak create a new async dependency block per dependency // if we are lazy create a new async dependency block per dependency
// and add all blocks to this context // and add all blocks to this context
dependencies.forEach((dep, idx) => { dependencies.forEach((dep, idx) => {
let chunkName = this.chunkName; let chunkName = this.chunkName;
@ -223,7 +210,7 @@ webpackContext.id = ${JSON.stringify(id)};`;
function webpackContext(req) { function webpackContext(req) {
var id = webpackContextResolve(req); var id = webpackContextResolve(req);
if(!__webpack_require__.m[id]) if(!__webpack_require__.m[id])
throw new Error("Module '" + id + "' is not available (weak dependency)"); throw new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
return __webpack_require__(id); return __webpack_require__(id);
}; };
function webpackContextResolve(req) { function webpackContextResolve(req) {
@ -240,43 +227,33 @@ module.exports = webpackContext;
webpackContext.id = ${JSON.stringify(id)};`; webpackContext.id = ${JSON.stringify(id)};`;
} }
getWeakEagerSource(blocks, id) { getAsyncWeakSource(dependencies, id) {
const map = blocks const map = this.getUserRequestMap(dependencies);
.filter(block => block.dependencies[0].module)
.map((block) => ({
dependency: block.dependencies[0],
block: block,
userRequest: block.dependencies[0].userRequest
})).sort((a, b) => {
if(a.userRequest === b.userRequest) return 0;
return a.userRequest < b.userRequest ? -1 : 1;
}).reduce((map, item) => {
const chunks = item.block.chunks || [];
map[item.userRequest] = [item.dependency.module.id]
.concat(chunks.map(chunk => chunk.id));
return map;
}, Object.create(null));
return `var map = ${JSON.stringify(map, null, "\t")}; return `var map = ${JSON.stringify(map, null, "\t")};
function webpackAsyncContext(req) { function webpackAsyncContext(req) {
var ids = map[req]; return webpackAsyncContextResolve(req).then(function(id) {
if(!ids)
return Promise.reject(new Error("Cannot find module '" + req + "'."));
return new Promise(function(resolve, reject) {
var id = ids[0];
if(!__webpack_require__.m[id]) if(!__webpack_require__.m[id])
reject(new Error("Module '" + id + "' is not available (weak dependency)")); throw new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
else return __webpack_require__(id);
resolve(__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() { webpackAsyncContext.keys = function webpackAsyncContextKeys() {
return Object.keys(map); return Object.keys(map);
}; };
module.exports = webpackAsyncContext; webpackAsyncContext.resolve = webpackAsyncContextResolve;
webpackAsyncContext.id = ${JSON.stringify(id)};`; webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`;
} }
getEagerSource(dependencies, id) { getEagerSource(dependencies, id) {
@ -286,20 +263,21 @@ function webpackAsyncContext(req) {
return webpackAsyncContextResolve(req).then(__webpack_require__); return webpackAsyncContextResolve(req).then(__webpack_require__);
}; };
function webpackAsyncContextResolve(req) { 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]; var id = map[req];
if(!(id + 1)) // check for number or string if(!(id + 1)) // check for number or string
reject(new Error("Cannot find module '" + req + "'.")); throw new Error("Cannot find module '" + req + "'.");
else return id;
resolve(id);
}); });
}; };
webpackAsyncContext.keys = function webpackAsyncContextKeys() { webpackAsyncContext.keys = function webpackAsyncContextKeys() {
return Object.keys(map); return Object.keys(map);
}; };
webpackAsyncContext.resolve = webpackAsyncContextResolve; 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) { getLazyOnceSource(block, dependencies, id, outputOptions, requestShortener) {
@ -321,8 +299,8 @@ webpackAsyncContext.keys = function webpackAsyncContextKeys() {
return Object.keys(map); return Object.keys(map);
}; };
webpackAsyncContext.resolve = webpackAsyncContextResolve; webpackAsyncContext.resolve = webpackAsyncContextResolve;
module.exports = webpackAsyncContext; webpackAsyncContext.id = ${JSON.stringify(id)};
webpackAsyncContext.id = ${JSON.stringify(id)};`; module.exports = webpackAsyncContext;`;
} }
getLazySource(blocks, id) { getLazySource(blocks, id) {
@ -363,8 +341,8 @@ function webpackAsyncContext(req) {
webpackAsyncContext.keys = function webpackAsyncContextKeys() { webpackAsyncContext.keys = function webpackAsyncContextKeys() {
return Object.keys(map); return Object.keys(map);
}; };
module.exports = webpackAsyncContext; webpackAsyncContext.id = ${JSON.stringify(id)};
webpackAsyncContext.id = ${JSON.stringify(id)};`; module.exports = webpackAsyncContext;`;
} }
getSourceForEmptyContext(id) { getSourceForEmptyContext(id) {
@ -379,7 +357,11 @@ webpackEmptyContext.id = ${JSON.stringify(id)};`;
getSourceForEmptyAsyncContext(id) { getSourceForEmptyAsyncContext(id) {
return `function webpackEmptyAsyncContext(req) { 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.keys = function() { return []; };
webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext; webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
@ -407,9 +389,9 @@ webpackEmptyAsyncContext.id = ${JSON.stringify(id)};`;
} }
return this.getSourceForEmptyAsyncContext(this.id); return this.getSourceForEmptyAsyncContext(this.id);
} }
if(asyncMode === "eager-weak") { if(asyncMode === "async-weak") {
if(this.blocks && this.blocks.length > 0) { if(this.dependencies && this.dependencies.length > 0) {
return this.getWeakEagerSource(this.blocks, this.id); return this.getAsyncWeakSource(this.dependencies, this.id);
} }
return this.getSourceForEmptyAsyncContext(this.id); return this.getSourceForEmptyAsyncContext(this.id);
} }

View File

@ -5,13 +5,13 @@
"use strict"; "use strict";
const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
const ImportDependency = require("./ImportDependency"); const ImportDependency = require("./ImportDependency");
const ImportEagerWeakDependency = require("./ImportEagerWeakDependency"); const ImportWeakDependency = require("./ImportWeakDependency");
module.exports = class ImportDependenciesBlock extends AsyncDependenciesBlock { module.exports = class ImportDependenciesBlock extends AsyncDependenciesBlock {
constructor(request, range, chunkName, module, loc, mode) { constructor(request, range, chunkName, module, loc) {
super(chunkName, module, loc); super(chunkName, module, loc);
this.range = range; this.range = range;
const dep = mode === "eager-weak" ? new ImportEagerWeakDependency(request, this) : new ImportDependency(request, this, mode); const dep = new ImportDependency(request, this);
dep.loc = loc; dep.loc = loc;
this.addDependency(dep); this.addDependency(dep);
} }

View File

@ -5,7 +5,8 @@
"use strict"; "use strict";
const ImportEagerContextDependency = require("./ImportEagerContextDependency"); const ImportEagerContextDependency = require("./ImportEagerContextDependency");
const ImportEagerWeakContextDependency = require("./ImportEagerWeakContextDependency"); const ImportWeakDependency = require("./ImportWeakDependency");
const ImportWeakContextDependency = require("./ImportWeakContextDependency");
const ImportLazyOnceContextDependency = require("./ImportLazyOnceContextDependency"); const ImportLazyOnceContextDependency = require("./ImportLazyOnceContextDependency");
const ImportLazyContextDependency = require("./ImportLazyContextDependency"); const ImportLazyContextDependency = require("./ImportLazyContextDependency");
const ImportDependenciesBlock = require("./ImportDependenciesBlock"); const ImportDependenciesBlock = require("./ImportDependenciesBlock");
@ -47,29 +48,31 @@ class ImportParserPlugin {
} }
if(param.isString()) { if(param.isString()) {
if(mode !== "lazy" && mode !== "eager" && mode !== "eager-weak") { if(mode !== "lazy" && mode !== "eager" && mode !== "weak") {
parser.state.module.warnings.push(new UnsupportedFeatureWarning(parser.state.module, `\`webpackMode\` expected 'lazy', 'eager' or 'eager-weak', but received: ${mode}.`)); parser.state.module.warnings.push(new UnsupportedFeatureWarning(parser.state.module, `\`webpackMode\` expected 'lazy', 'eager' or 'weak', but received: ${mode}.`));
} }
if(mode === "eager") { if(mode === "eager") {
const dep = new ImportEagerDependency(param.string, expr.range); const dep = new ImportEagerDependency(param.string, expr.range);
parser.state.current.addDependency(dep); parser.state.current.addDependency(dep);
} else if(mode === "weak") {
const dep = new ImportWeakDependency(param.string, expr.range);
parser.state.current.addDependency(dep);
} else { } else {
// both lazy and eager-weak modes use this; eager-weak needs the chunks created, but will expect them pre-served const depBlock = new ImportDependenciesBlock(param.string, expr.range, chunkName, parser.state.module, expr.loc);
const depBlock = new ImportDependenciesBlock(param.string, expr.range, chunkName, parser.state.module, expr.loc, mode);
parser.state.current.addBlock(depBlock); parser.state.current.addBlock(depBlock);
} }
return true; return true;
} else { } else {
if(mode !== "lazy" && mode !== "lazy-once" && mode !== "eager" && mode !== "eager-weak") { 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 'eager-weak', but received: ${mode}.`)); parser.state.module.warnings.push(new UnsupportedFeatureWarning(parser.state.module, `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`));
} }
let Dep = ImportLazyContextDependency; let Dep = ImportLazyContextDependency;
if(mode === "eager") { if(mode === "eager") {
Dep = ImportEagerContextDependency; Dep = ImportEagerContextDependency;
} else if(mode === "eager-weak") { } else if(mode === "weak") {
Dep = ImportEagerWeakContextDependency; Dep = ImportWeakContextDependency;
} else if(mode === "lazy-once") { } else if(mode === "lazy-once") {
Dep = ImportLazyOnceContextDependency; Dep = ImportLazyOnceContextDependency;
} }

View File

@ -6,9 +6,9 @@
const ImportDependency = require("./ImportDependency"); const ImportDependency = require("./ImportDependency");
const ImportEagerDependency = require("./ImportEagerDependency"); const ImportEagerDependency = require("./ImportEagerDependency");
const ImportEagerWeakDependency = require("./ImportEagerWeakDependency"); const ImportWeakDependency = require("./ImportWeakDependency");
const ImportEagerContextDependency = require("./ImportEagerContextDependency"); const ImportEagerContextDependency = require("./ImportEagerContextDependency");
const ImportEagerWeakContextDependency = require("./ImportEagerWeakContextDependency"); const ImportWeakContextDependency = require("./ImportWeakContextDependency");
const ImportLazyOnceContextDependency = require("./ImportLazyOnceContextDependency"); const ImportLazyOnceContextDependency = require("./ImportLazyOnceContextDependency");
const ImportLazyContextDependency = require("./ImportLazyContextDependency"); const ImportLazyContextDependency = require("./ImportLazyContextDependency");
const ImportParserPlugin = require("./ImportParserPlugin"); const ImportParserPlugin = require("./ImportParserPlugin");
@ -30,14 +30,14 @@ class ImportPlugin {
compilation.dependencyFactories.set(ImportEagerDependency, normalModuleFactory); compilation.dependencyFactories.set(ImportEagerDependency, normalModuleFactory);
compilation.dependencyTemplates.set(ImportEagerDependency, new ImportEagerDependency.Template()); compilation.dependencyTemplates.set(ImportEagerDependency, new ImportEagerDependency.Template());
compilation.dependencyFactories.set(ImportEagerWeakDependency, normalModuleFactory); compilation.dependencyFactories.set(ImportWeakDependency, normalModuleFactory);
compilation.dependencyTemplates.set(ImportEagerWeakDependency, new ImportEagerWeakDependency.Template()); compilation.dependencyTemplates.set(ImportWeakDependency, new ImportWeakDependency.Template());
compilation.dependencyFactories.set(ImportEagerContextDependency, contextModuleFactory); compilation.dependencyFactories.set(ImportEagerContextDependency, contextModuleFactory);
compilation.dependencyTemplates.set(ImportEagerContextDependency, new ImportEagerContextDependency.Template()); compilation.dependencyTemplates.set(ImportEagerContextDependency, new ImportEagerContextDependency.Template());
compilation.dependencyFactories.set(ImportEagerWeakContextDependency, contextModuleFactory); compilation.dependencyFactories.set(ImportWeakContextDependency, contextModuleFactory);
compilation.dependencyTemplates.set(ImportEagerWeakContextDependency, new ImportEagerWeakContextDependency.Template()); compilation.dependencyTemplates.set(ImportWeakContextDependency, new ImportWeakContextDependency.Template());
compilation.dependencyFactories.set(ImportLazyOnceContextDependency, contextModuleFactory); compilation.dependencyFactories.set(ImportLazyOnceContextDependency, contextModuleFactory);
compilation.dependencyTemplates.set(ImportLazyOnceContextDependency, new ImportLazyOnceContextDependency.Template()); compilation.dependencyTemplates.set(ImportLazyOnceContextDependency, new ImportLazyOnceContextDependency.Template());

View File

@ -6,17 +6,17 @@
const ImportContextDependency = require("./ImportContextDependency"); const ImportContextDependency = require("./ImportContextDependency");
const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall"); const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall");
class ImportEagerWeakContextDependency extends ImportContextDependency { class ImportWeakContextDependency extends ImportContextDependency {
constructor(request, recursive, regExp, range, valueRange, chunkName) { constructor(request, recursive, regExp, range, valueRange, chunkName) {
super(request, recursive, regExp, range, valueRange, chunkName); super(request, recursive, regExp, range, valueRange, chunkName);
this.async = "eager-weak"; this.async = "async-weak";
} }
get type() { get type() {
return "import() context eager-weak"; return "import() context weak";
} }
} }
ImportEagerWeakContextDependency.Template = ContextDependencyTemplateAsRequireCall; ImportWeakContextDependency.Template = ContextDependencyTemplateAsRequireCall;
module.exports = ImportEagerWeakContextDependency; module.exports = ImportWeakContextDependency;

View File

@ -4,28 +4,26 @@
*/ */
"use strict"; "use strict";
const ModuleDependency = require("./ModuleDependency"); const ModuleDependency = require("./ModuleDependency");
const DepBlockHelpers = require("./DepBlockHelpers");
const webpackMissingPromiseModule = require("./WebpackMissingModule").promise; const webpackMissingPromiseModule = require("./WebpackMissingModule").promise;
class ImportEagerWeakDependency extends ModuleDependency { class ImportWeakDependency extends ModuleDependency {
constructor(request, block) { constructor(request, range) {
super(request); super(request);
this.block = block; this.range = range;
this.weak = true;
} }
get type() { get type() {
return "import() eager-weak"; return "import() weak";
} }
} }
ImportEagerWeakDependency.Template = class ImportDependencyTemplate { ImportWeakDependency.Template = class ImportDependencyTemplate {
apply(dep, source, outputOptions, requestShortener) { apply(dep, source, outputOptions, requestShortener) {
const depBlock = dep.block;
const promise = DepBlockHelpers.getDepBlockPromise(depBlock, outputOptions, requestShortener, "import()");
const comment = this.getOptionalComment(outputOptions.pathinfo, requestShortener.shorten(dep.request)); const comment = this.getOptionalComment(outputOptions.pathinfo, requestShortener.shorten(dep.request));
const content = this.getContent(promise, dep, comment); const content = this.getContent(dep, comment);
source.replace(depBlock.range[0], depBlock.range[1] - 1, content); source.replace(dep.range[0], dep.range[1] - 1, content);
} }
getOptionalComment(pathinfo, shortenedRequest) { getOptionalComment(pathinfo, shortenedRequest) {
@ -36,14 +34,14 @@ ImportEagerWeakDependency.Template = class ImportDependencyTemplate {
return `/*! ${shortenedRequest} */ `; return `/*! ${shortenedRequest} */ `;
} }
getContent(promise, dep, comment) { getContent(dep, comment) {
if(dep.module) { if(dep.module) {
const stringifiedId = JSON.stringify(dep.module.id); const stringifiedId = JSON.stringify(dep.module.id);
return `new Promise(function(resolve) { resolve(__webpack_require__(${comment}${stringifiedId})); })`; 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); return webpackMissingPromiseModule(dep.request);
} }
}; };
module.exports = ImportEagerWeakDependency; module.exports = ImportWeakDependency;

View File

@ -58,9 +58,9 @@ it("should be able to combine chunks by name", function(done) {
testChunkLoading(load, false, true, done); testChunkLoading(load, false, true, done);
}); });
it("should be able to use eager-weak mode", function(done) { it("should be able to use weak mode", function(done) {
function load(name) { function load(name) {
return import(/* webpackMode: "eager-weak" */"./dir8/" + name); return import(/* webpackMode: "weak" */ "./dir8/" + name);
} }
require("./dir8/a") // chunks served manually by the user require("./dir8/a") // chunks served manually by the user
require("./dir8/b") require("./dir8/b")
@ -68,15 +68,15 @@ it("should be able to use eager-weak mode", function(done) {
testChunkLoading(load, true, true, done); testChunkLoading(load, true, true, done);
}); });
it("should be able to use eager-weak mode (without context)", function(done) { it("should be able to use weak mode (without context)", function(done) {
function load(name) { function load(name) {
switch(name) { switch(name) {
case "a": case "a":
return import(/* webpackMode: "eager-weak" */ "./dir9/a"); return import(/* webpackMode: "weak" */ "./dir9/a");
case "b": case "b":
return import(/* webpackMode: "eager-weak" */ "./dir9/b"); return import(/* webpackMode: "weak" */ "./dir9/b");
case "c": case "c":
return import(/* webpackMode: "eager-weak" */ "./dir9/c"); return import(/* webpackMode: "weak" */ "./dir9/c");
default: default:
throw new Error("Unexcepted test data"); throw new Error("Unexcepted test data");
} }
@ -87,17 +87,17 @@ it("should be able to use eager-weak mode (without context)", function(done) {
testChunkLoading(load, true, true, done); testChunkLoading(load, true, true, done);
}); });
it("should not find module when mode is eager-weak and chunk not served elsewhere", function(done) { it("should not find module when mode is weak and chunk not served elsewhere", function(done) {
var name = "a"; var name = "a";
import(/* webpackMode: "eager-weak" */"./dir10/" + name) import(/* webpackMode: "weak" */ "./dir10/" + name)
.catch(function(e) { .catch(function(e) {
e.should.match(/not available/); e.should.match(/not available/);
done(); done();
}) })
}); });
it("should not find module when mode is eager-weak and chunk not served elsewhere (without context)", function(done) { it("should not find module when mode is weak and chunk not served elsewhere (without context)", function(done) {
import(/* webpackMode: "eager-weak" */"./dir11/a") import(/* webpackMode: "weak" */ "./dir11/a")
.catch(function(e) { .catch(function(e) {
e.should.match(/not available/); e.should.match(/not available/);
done(); done();