【问题标题】:How to split dynamically by directories with Webpack/SplitChunks plugin?如何使用 Webpack/SplitChunks 插件按目录动态拆分?
【发布时间】:2019-01-21 13:20:39
【问题描述】:

我正在尝试通过以下方式使用 splitChunks 插件拆分我的 React 代码(使用 create-react-app 创建):

我有以下组件(JSX)结构:

  • 服务
    • 服务A
      • 组件A1
      • 组件A2
      • 子文件夹
        • 组件A3
      • ...
    • 服务B
      • 组件B1
      • 组件B2
      • ...
    • 服务C
      • 组件B1
      • 组件B2
      • ...
    • ...

并且我希望有以下输出(构建):

  • 静态/js
    • 服务A
      • serviceA.bundle.chunkhash.js
    • 服务B
      • serviceB.bundle.chunkhash.js
    • 服务C
      • serviceC.bundle.chunkhash.js

(其他运行时/mains在/static/js的根目录下)

另一个限制是组件是动态加载的

const Component = lazy(() => import(componentPath));
...
<Suspense fallback={..}>Component</suspense>

“componentPath”是动态确定的(当用户单击图标时,它会打开给定的服务)。

这样做的原因是我想将每个包包含到运行后端的单独 Docker 映像中。然后由于应用程序路由,每个 Docker 映像都可以访问:

static/js/serviceA/  ==> js served by Docker container running service A
static/js/serviceB/  ==> js served by Docker container running service B
static/js/serviceC/  ==> js served by Docker container running service C

到目前为止,我尝试过:

  • 将 output.chunkFilename 设置为 [name]/[name].[chunkhash].js
  • 将 webpackChunkName 与 [name] 和 [request] 一起使用:

    • [name] 似乎不起作用(只是将“[name]”作为我的目录名称的一部分)。

    • [request] 展平目录名称:

      服务A-组件A1 服务A-组件A2 服务A-subFolder-ComponentA3 服务B-组件B1 服务B-组件B2 ...

然后我尝试使用 splitChunks 插件:

  splitChunks: {
    chunks: 'all',
    name: function(module) {
      let serviceName = module.rawRequest ? module.rawRequest : 'default';
      serviceName = serviceName.replace('../', '').replace('./', '');
      serviceName = serviceName.split('/')[0];
      return serviceName;
    },
    cacheGroups: {
      vendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10
      },
      default: {
        minChunks: 2,
        priority: -20,
        reuseExistingChunk: true
      },
      serviceA: {
        test: /[\\/]serviceA[\\/]/,
        priority: -10
      },
      serviceB: {
        test: /[\\/]serviceB[\\/]/,
        priority: -10
      },
      serviceC: {
        test: /[\\/]serviceC[\\/]/,
        priority: -10
      },              
    }
  },

这种方法看起来很有效,因为我的所有服务都在它们自己的目录中。但是我仍然有一些额外的目录作为数字(可能是捆绑 ID),我希望它们被包含在默认值中。

所以问题是:我的方法正确吗?

【问题讨论】:

    标签: reactjs webpack-4 webpack-splitchunks splitchunksplugin


    【解决方案1】:

    我不确定以下选项是否适合您。我有一个类似的问题,我需要在不同的包上输出不同的文件夹。

    在我的例子中,我从 glob 解决方案开始,建议 here。 然后,知道我需要为每个所需输出提供一组输入,我想出了这个:

    const path = require('path');
    const glob = require('glob');
    
    const plugins = [...];
    
    module.exports = {
        entry: glob.sync('./src/**/*.js').reduce((acc, item) => {
            const path = item.split('/');
            path.pop();
            const rootFolder = path[2] ? `${path[0]}/${path[2]}` : path[0];
            if (acc[rootFolder]) {
                acc[rootFolder].push(item);
            } else {
                acc[rootFolder] = [item];
            }
            return acc;
        }, {}),
        output: {
            filename: '[name]/main.js',
            path: path.resolve(__dirname, 'dist'),
        },
      module: { ... },
        plugins,
    };
    

    这是我的 config 的简化版本,它可能会得到改进,但它可以很好地满足我的需要。 :)

    关于 glob 库的更多信息:https://github.com/isaacs/node-glob

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2018-10-18
      • 2019-09-22
      • 2010-12-09
      • 2017-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多