我刚开始编写Webpack插件。
我想向现有的Webpack插件存储库添加新功能。
此功能是在.json文件中解析子软件包的结构,然后应从主软件包供应商捆绑程序中拆分出子软件包根目录下的依赖项。
例如,我的app.json:
{
"pages":[
"pages/one/one",
"pages/two/two"
],
"subPackages": [
{
"root": "pages/sub",
"pages": [
"one",
"two"
]
}
]
}
因此,如果我项目的src
结构如下:
--pages
--one
--one.js
--one.html
--one.css
--one.service.js
--two
--two.js
--two.html
--two.css
--two.service.js
--sub
--folder
--test.js
--one.js
--one.html
--one.css
--one.service.js
然后我希望它的dist
输出如下:
[[ CASE A ]]
--pages
--one
--one.js
--one.html
--one.css
--two
--two.js
--two.html
--two.css
--sub
--folder
--test.js
--one.js
--one.html
--one.css
--one.service.js
--vendor.js
或:
--pages
--one
--one.js
--one.html
--one.css
--two
--two.js
--two.html
--two.css
--sub
--one.js
--one.html
--one.css
--vendor.js
--vendor.js
当前仓库的功能是将所有依赖项分块在一起,并将其输出到根路径的供应商文件。
所以我的代码是:
// waiting For Compiling And Deal By SingleEntryPlugin
async getEntryResources() {
const appJSONFile = resolve(base, 'app.json');
const { pages = [], subPackages = [] } = await readJson(
appJSONFile
);
const subDepFiles = [];
for (const subPackage of subPackages) {
const { root, pages = [] } = subPackage;
const scripts = pages.map(w => resolve(base, join(root, w)));
const subFiles = await globby(join(root, '**/*'), {
cwd: base,
nodir: true,
realpath: true
});
subFiles.forEach(resource => {
const name = stripExt(resource)
if (/\.js$/.test(resource) && scripts.indexOf(name) < 0) {
subDepFiles.push(name.slice(name.indexOf(root)));
}
})
}
this.subRoots = subPackages.map(v => v.root);
// pages + subpages + subpages' dependencies
return [
...pages,
...subDepFiles,
...[].concat(...subPackages.map(v => v.pages.map(w => join(v.root, w))))
];
}
然后我的applyCommonsChunk
过滤子包根目录中的依赖项:
applyCommonsChunk(compiler) {
const scripts = entryResources.map(::this.getFullScriptPath);
compiler.apply(
new CommonsChunkPlugin({
name: 'vendor',
minChunks: ({ resource }) => {
if (resource) {
const inSubPackage = this.subRoots.find(v => resource.match(v))
return /\.js$/.test(resource) && scripts.indexOf(resource) < 0 && !inSubPackage;
}
return false;
}
})
);
}
然后我的vendor.js
还可以,并且可以像[[CASE A]]一样输出,但是sub/one.js
具有服务的副本,而不是从sub/one.service.js
导入。 / p>