I'm new to writing Webpack plugins.
I want to add a new feature to an existing Webpack plugin repo.
The feature is to resolve a sub-package's structure in a .json file, then the dependencies below the sub-package roots should be split from the main package vendor bundler.
for example, my app.json:
{
"pages":[
"pages/one/one",
"pages/two/two"
],
"subPackages": [
{
"root": "pages/sub",
"pages": [
"one",
"two"
]
}
]
}
so if my project's src
structure looks like:
--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
then I expect its dist
output to be like:
[[ 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
or:
--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
The current repo's ability is to chunk all the dependencies together and output it to the root path's vendor file.
So my code is:
// 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))))
];
}
then my applyCommonsChunk
filters the dependencies from the sub-package roots:
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;
}
})
);
}
then my vendor.js
is ok, and can output like [[ CASE A ]], but the sub/one.js
has a copy of the service, instead of import from the sub/one.service.js
.