首页 > 解决方案 > Webpack Tree-Shaking Dynamic Imports 似乎不起作用

问题描述

历史: 我最近在使用 Webpack 和动态导入时发现了一个奇怪的行为。首先,我认为这可能是我使用的第 3 方库“可加载组件”,所以我打开了一个错误问题(https://github.com/gregberge/loadable-components/issues/517)。作者回复告诉我该行为来自 Webpack 和动态导入本身。

我可以忍受这样一个事实,即它不会对动态导入产生影响,对我来说,理解为什么会这样更重要。

可以在此处找到演示该行为的演示存储库: https ://github.com/dazlious/treeshaking-dynamic-imports

问题的简短描述:从我的角度来看,导入的命名导出不应强制将所有导出的代码捆绑在其中。

在演示案例中,我们有一个组件 (./lib/index.jsx),它有两个子组件,分别称为 module1 (./lib/module1/module1.jsx) 和 module2 (./lib/module1/module2.jsx)。Module1 导出一个名为 FOO_BAR 的常量,然后 Module2 将其作为命名导入导入。

查看构建输出时,您会发现 Module2 包含整个 Module1 而不仅仅是专门导入的字符串。

是否有人对 Webpack 和/或动态导入有深入的了解?很高兴了解更多关于这种行为的信息。

标签: javascriptwebpackecmascript-6importtree-shaking

解决方案


我将 webpack.config 编辑为:

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

const baseDir = path.resolve(__dirname);

const config = {
  mode: process.env.NODE_ENV,
  stats: 'minimal',
  resolve: {
    extensions: ['.js', '.jsx'],
    symlinks: false,
  },
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
      openAnalyzer: false,
      reportFilename: 'analyze.html',
    }),
  ],
  target: 'web',
  devtool: 'hidden-source-map',
  entry: {
    bundle: [path.resolve(baseDir, 'lib')],
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,
      }),
    ],
    mangleWasmImports: true,
    splitChunks: {
      cacheGroups: {
        default: false,
        vendors: false,
        vendor: {
          name: 'vendor',
          chunks: 'all',
          test: /node_modules/,
          priority: 20
        },
        common: {
          name: 'common',
          minChunks: 2,
          chunks: 'all',
          priority: 10,
          reuseExistingChunk: true,
          enforce: true
        }
      }
    },
  },
  output: {
    chunkFilename: '[name].[chunkhash].js',
    publicPath: '/',
    path: path.join(baseDir, 'dist'),
    filename: '[name].[hash].js',
  },
  module: {
    rules: [
      {
        test: /^.*\.jsx?$/,
        include: [path.resolve(baseDir, 'lib')],
        loader: 'babel-loader?cacheDirectory',
      },
      {
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      },
    ],
  },
};

module.exports = config;

我认为这有你正在寻找的结果? bunde 分析器的图像显示了它们自己的包中的模块

我认为它需要 splitChunks 选项才能正确地对组件进行实际的树摇动。我花了很多时间试图弄清楚 webpack,但我仍然在这里猜测。


推荐阅读