Upgrade tapable in ModuleFactories

This commit is contained in:
Tobias Koppers 2017-11-28 09:54:24 +01:00
parent 3f453a4f3c
commit a27ef326d5
5 changed files with 73 additions and 21 deletions

View File

@ -7,7 +7,9 @@
const asyncLib = require("async"); const asyncLib = require("async");
const path = require("path"); const path = require("path");
const Tapable = require("tapable-old"); const Tapable = require("tapable").Tapable;
const AsyncSeriesWaterfallHook = require("tapable").AsyncSeriesWaterfallHook;
const SyncWaterfallHook = require("tapable").SyncWaterfallHook;
const ContextModule = require("./ContextModule"); const ContextModule = require("./ContextModule");
const ContextElementDependency = require("./dependencies/ContextElementDependency"); const ContextElementDependency = require("./dependencies/ContextElementDependency");
@ -16,6 +18,21 @@ const EMPTY_RESOLVE_OPTIONS = {};
module.exports = class ContextModuleFactory extends Tapable { module.exports = class ContextModuleFactory extends Tapable {
constructor(resolverFactory) { constructor(resolverFactory) {
super(); super();
this.hooks = {
beforeResolve: new AsyncSeriesWaterfallHook(["data"]),
afterResolve: new AsyncSeriesWaterfallHook(["data"]),
contextModuleFiles: new SyncWaterfallHook(["files"]),
alternatives: new AsyncSeriesWaterfallHook(["modules"])
};
this._pluginCompat.tap("ContextModuleFactory", options => {
switch(options.name) {
case "before-resolve":
case "after-resolve":
case "alternatives":
options.async = true;
break;
}
});
this.resolverFactory = resolverFactory; this.resolverFactory = resolverFactory;
} }
@ -24,7 +41,7 @@ module.exports = class ContextModuleFactory extends Tapable {
const dependencies = data.dependencies; const dependencies = data.dependencies;
const resolveOptions = data.resolveOptions; const resolveOptions = data.resolveOptions;
const dependency = dependencies[0]; const dependency = dependencies[0];
this.applyPluginsAsyncWaterfall("before-resolve", Object.assign({ this.hooks.beforeResolve.callAsync(Object.assign({
context: context, context: context,
dependencies: dependencies, dependencies: dependencies,
resolveOptions resolveOptions
@ -76,7 +93,7 @@ module.exports = class ContextModuleFactory extends Tapable {
], (err, result) => { ], (err, result) => {
if(err) return callback(err); if(err) return callback(err);
this.applyPluginsAsyncWaterfall("after-resolve", Object.assign({ this.hooks.afterResolve.callAsync(Object.assign({
addon: loadersPrefix + result[1].join("!") + (result[1].length > 0 ? "!" : ""), addon: loadersPrefix + result[1].join("!") + (result[1].length > 0 ? "!" : ""),
resource: result[0], resource: result[0],
resolveDependencies: this.resolveDependencies.bind(this) resolveDependencies: this.resolveDependencies.bind(this)
@ -106,7 +123,7 @@ module.exports = class ContextModuleFactory extends Tapable {
const addDirectory = (directory, callback) => { const addDirectory = (directory, callback) => {
fs.readdir(directory, (err, files) => { fs.readdir(directory, (err, files) => {
if(err) return callback(err); if(err) return callback(err);
files = cmf.applyPluginsWaterfall("context-module-files", files); files = cmf.hooks.contextModuleFiles.call(files);
if(!files || files.length === 0) return callback(null, []); if(!files || files.length === 0) return callback(null, []);
asyncLib.map(files.filter(p => p.indexOf(".") !== 0), (seqment, callback) => { asyncLib.map(files.filter(p => p.indexOf(".") !== 0), (seqment, callback) => {
@ -136,7 +153,7 @@ module.exports = class ContextModuleFactory extends Tapable {
request: "." + subResource.substr(resource.length).replace(/\\/g, "/") request: "." + subResource.substr(resource.length).replace(/\\/g, "/")
}; };
this.applyPluginsAsyncWaterfall("alternatives", [obj], (err, alternatives) => { this.hooks.alternatives.callAsync([obj], (err, alternatives) => {
if(err) return callback(err); if(err) return callback(err);
alternatives = alternatives.filter(obj => regExp.test(obj.request)).map(obj => { alternatives = alternatives.filter(obj => regExp.test(obj.request)).map(obj => {
const dep = new ContextElementDependency(obj.request + resourceQuery, obj.request); const dep = new ContextElementDependency(obj.request + resourceQuery, obj.request);

View File

@ -4,12 +4,13 @@
*/ */
"use strict"; "use strict";
const Tapable = require("tapable-old"); const Tapable = require("tapable").Tapable;
const DllModule = require("./DllModule"); const DllModule = require("./DllModule");
class DllModuleFactory extends Tapable { class DllModuleFactory extends Tapable {
constructor() { constructor() {
super(); super();
this.hooks = {};
} }
create(data, callback) { create(data, callback) {
const dependency = data.dependencies[0]; const dependency = data.dependencies[0];

View File

@ -51,7 +51,7 @@ class IgnorePlugin {
checkIgnore(result, callback) { checkIgnore(result, callback) {
// check if result is ignored // check if result is ignored
if(this.checkResult(result)) { if(this.checkResult(result)) {
return callback(); return callback(null, null);
} }
return callback(null, result); return callback(null, result);
} }

View File

@ -4,12 +4,13 @@
*/ */
"use strict"; "use strict";
const Tapable = require("tapable-old"); const Tapable = require("tapable").Tapable;
const MultiModule = require("./MultiModule"); const MultiModule = require("./MultiModule");
module.exports = class MultiModuleFactory extends Tapable { module.exports = class MultiModuleFactory extends Tapable {
constructor() { constructor() {
super(); super();
this.hooks = {};
} }
create(data, callback) { create(data, callback) {

View File

@ -5,7 +5,12 @@
"use strict"; "use strict";
const asyncLib = require("async"); const asyncLib = require("async");
const Tapable = require("tapable-old"); const Tapable = require("tapable").Tapable;
const AsyncSeriesWaterfallHook = require("tapable").AsyncSeriesWaterfallHook;
const SyncWaterfallHook = require("tapable").SyncWaterfallHook;
const SyncBailHook = require("tapable").SyncBailHook;
const SyncHook = require("tapable").SyncHook;
const HookMap = require("tapable").HookMap;
const NormalModule = require("./NormalModule"); const NormalModule = require("./NormalModule");
const RawModule = require("./RawModule"); const RawModule = require("./RawModule");
const RuleSet = require("./RuleSet"); const RuleSet = require("./RuleSet");
@ -47,13 +52,45 @@ const identToLoaderRequest = resultString => {
class NormalModuleFactory extends Tapable { class NormalModuleFactory extends Tapable {
constructor(context, resolverFactory, options) { constructor(context, resolverFactory, options) {
super(); super();
this.hooks = {
resolver: new SyncWaterfallHook(["resolver"]),
factory: new SyncWaterfallHook(["factory"]),
beforeResolve: new AsyncSeriesWaterfallHook(["data"]),
afterResolve: new AsyncSeriesWaterfallHook(["data"]),
createModule: new SyncBailHook(["data"]),
module: new SyncWaterfallHook(["module", "data"]),
createParser: new HookMap(() => new SyncBailHook(["parserOptions"])),
parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])),
};
this._pluginCompat.tap("NormalModuleFactory", options => {
switch(options.name) {
case "before-resolve":
case "after-resolve":
options.async = true;
break;
case "parser":
this.hooks.parser.for("javascript/auto").tap(options.fn.name || "unnamed compat plugin", options.fn);
return true;
}
let match;
match = /^parser (.+)$/.exec(options.name);
if(match) {
this.hooks.parser.for(match[1]).tap(options.fn.name || "unnamed compat plugin", options.fn.bind(this));
return true;
}
match = /^create-parser (.+)$/.exec(options.name);
if(match) {
this.hooks.createParser.for(match[1]).tap(options.fn.name || "unnamed compat plugin", options.fn.bind(this));
return true;
}
});
this.resolverFactory = resolverFactory; this.resolverFactory = resolverFactory;
this.ruleSet = new RuleSet(options.defaultRules.concat(options.rules)); this.ruleSet = new RuleSet(options.defaultRules.concat(options.rules));
this.cachePredicate = typeof options.unsafeCache === "function" ? options.unsafeCache : Boolean.bind(null, options.unsafeCache); this.cachePredicate = typeof options.unsafeCache === "function" ? options.unsafeCache : Boolean.bind(null, options.unsafeCache);
this.context = context || ""; this.context = context || "";
this.parserCache = {}; this.parserCache = {};
this.plugin("factory", () => (result, callback) => { this.plugin("factory", () => (result, callback) => {
let resolver = this.applyPluginsWaterfall0("resolver", null); let resolver = this.hooks.resolver.call(null);
// Ignored // Ignored
if(!resolver) return callback(); if(!resolver) return callback();
@ -68,13 +105,13 @@ class NormalModuleFactory extends Tapable {
if(typeof data.source === "function") if(typeof data.source === "function")
return callback(null, data); return callback(null, data);
this.applyPluginsAsyncWaterfall("after-resolve", data, (err, result) => { this.hooks.afterResolve.callAsync(data, (err, result) => {
if(err) return callback(err); if(err) return callback(err);
// Ignored // Ignored
if(!result) return callback(); if(!result) return callback();
let createdModule = this.applyPluginsBailResult1("create-module", result); let createdModule = this.hooks.createModule.call(result);
if(!createdModule) { if(!createdModule) {
if(!result.request) { if(!result.request) {
@ -93,7 +130,7 @@ class NormalModuleFactory extends Tapable {
); );
} }
createdModule = this.applyPluginsWaterfall1("module", createdModule, result); createdModule = this.hooks.module.call(createdModule, result);
return callback(null, createdModule); return callback(null, createdModule);
}); });
@ -230,7 +267,7 @@ class NormalModuleFactory extends Tapable {
const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS; const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS;
const request = dependencies[0].request; const request = dependencies[0].request;
const contextInfo = data.contextInfo || {}; const contextInfo = data.contextInfo || {};
this.applyPluginsAsyncWaterfall("before-resolve", { this.hooks.beforeResolve.callAsync({
contextInfo, contextInfo,
resolveOptions, resolveOptions,
context, context,
@ -242,7 +279,7 @@ class NormalModuleFactory extends Tapable {
// Ignored // Ignored
if(!result) return callback(); if(!result) return callback();
const factory = this.applyPluginsWaterfall0("factory", null); const factory = this.hooks.factory.call(null);
// Ignored // Ignored
if(!factory) return callback(); if(!factory) return callback();
@ -300,15 +337,11 @@ class NormalModuleFactory extends Tapable {
createParser(type, parserOptions) { createParser(type, parserOptions) {
parserOptions = parserOptions || {}; parserOptions = parserOptions || {};
const parser = this.applyPluginsBailResult1(`create-parser ${type}`, parserOptions); const parser = this.hooks.createParser.for(type).call(parserOptions);
if(!parser) { if(!parser) {
throw new Error(`No parser registered for ${type}`); throw new Error(`No parser registered for ${type}`);
} }
if(type === "javascript/auto") { this.hooks.parser.for(type).call(parser, parserOptions);
// TODO: remove backward compat in webpack 5
this.applyPlugins2("parser", parser, parserOptions);
}
this.applyPlugins2(`parser ${type}`, parser, parserOptions);
return parser; return parser;
} }