webpack/lib/dependencies/RequireContextPlugin.js

126 lines
3.3 KiB
JavaScript
Raw Normal View History

2013-01-31 01:49:25 +08:00
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
2018-07-30 23:08:51 +08:00
"use strict";
2013-01-31 01:49:25 +08:00
const ContextElementDependency = require("./ContextElementDependency");
2018-07-30 23:08:51 +08:00
const RequireContextDependency = require("./RequireContextDependency");
2013-01-31 01:49:25 +08:00
const RequireContextDependencyParserPlugin = require("./RequireContextDependencyParserPlugin");
2013-01-31 01:49:25 +08:00
class RequireContextPlugin {
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;
}
2013-01-31 01:49:25 +08:00
apply(compiler) {
2018-02-25 09:00:20 +08:00
compiler.hooks.compilation.tap(
"RequireContextPlugin",
(compilation, { contextModuleFactory, normalModuleFactory }) => {
compilation.dependencyFactories.set(
RequireContextDependency,
contextModuleFactory
);
compilation.dependencyTemplates.set(
RequireContextDependency,
new RequireContextDependency.Template()
);
2018-02-25 09:00:20 +08:00
compilation.dependencyFactories.set(
ContextElementDependency,
normalModuleFactory
);
2018-02-25 09:00:20 +08:00
const handler = (parser, parserOptions) => {
if (
2018-08-21 08:26:50 +08:00
parserOptions.requireContext !== undefined &&
2018-02-25 09:00:20 +08:00
!parserOptions.requireContext
)
return;
2018-02-25 09:00:20 +08:00
new RequireContextDependencyParserPlugin().apply(parser);
};
2018-02-25 09:00:20 +08:00
normalModuleFactory.hooks.parser
.for("javascript/auto")
.tap("RequireContextPlugin", handler);
normalModuleFactory.hooks.parser
.for("javascript/dynamic")
.tap("RequireContextPlugin", handler);
2013-02-15 21:16:18 +08:00
2018-02-25 09:00:20 +08:00
contextModuleFactory.hooks.alternatives.tap(
"RequireContextPlugin",
items => {
if (items.length === 0) return items;
// TODO use .flat() when min node.js version >= 12
return [].concat(
...items.map(obj => {
const { request, context } = obj;
2018-02-25 09:00:20 +08:00
return this.extensions
.filter(ext => request.endsWith(ext))
.map(ext => ({
context,
request: request.slice(0, -ext.length)
}))
2018-02-25 09:00:20 +08:00
.concat(obj);
})
);
2018-02-25 09:00:20 +08:00
}
);
2013-02-15 21:16:18 +08:00
2018-02-25 09:00:20 +08:00
contextModuleFactory.hooks.alternatives.tap(
"RequireContextPlugin",
items => {
if (items.length === 0) return items;
const result = [];
for (const obj of items) {
const { request, context } = obj;
for (const mainFile of this.mainFiles) {
if (request.endsWith(`/${mainFile}`)) {
result.push({
context,
request: request.slice(0, -mainFile.length)
});
result.push({
context,
request: request.slice(0, -mainFile.length - 1)
});
}
}
result.push(obj);
}
return result;
2018-02-25 09:00:20 +08:00
}
);
2018-02-25 09:00:20 +08:00
contextModuleFactory.hooks.alternatives.tap(
"RequireContextPlugin",
items => {
if (items.length === 0) return items;
return items.map(obj => {
for (const dir of this.modulesDirectories) {
if (obj.request.startsWith(`./${dir}/`)) {
2018-02-25 09:00:20 +08:00
obj.request = obj.request.slice(dir.length + 3);
break;
}
}
return obj;
});
2013-06-15 23:31:56 +08:00
}
2018-02-25 09:00:20 +08:00
);
}
);
}
}
module.exports = RequireContextPlugin;