1

我是编写 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

当前 repo 的能力是将所有依赖项分块在一起并将其输出到根路径的供应商文件。

所以我的代码是:

// 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.

4

0 回答 0