Динамический импорт Webpack Tree-Shaking не работает

История. Недавно я обнаружил странное поведение при использовании Webpack и динамического импорта. Сначала я подумал, что это может быть сторонняя библиотека «Загружаемые компоненты», которую я использовал, поэтому я обнаружил ошибку (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 и / или динамического импорта? Был бы рад узнать больше о поведении.


person dazlious    schedule 03.02.2020    source источник


Ответы (1)


Я отредактировал 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, но я все еще здесь в догадках.

person btnhawk    schedule 03.02.2020
comment
МОЙ БОГ! Спасибо. То же самое и здесь, только догадываясь, хотя я имею дело с Webpack, начиная с версии 1;) - person dazlious; 03.02.2020