簡體   English   中英

Webpack 導入會導致大量的包大小,即使設置了 sideEffects 和 usedExports

[英]Webpack import causing massive bundle size even with sideEffects and unusedExports set

我有一個 typescript 項目(Designer 項目),我用它來將文件與另一個 lerna 管理的“幫助函數”項目和類型定義(幫助項目)捆綁在一起。 這兩個項目都位於不同的文件夾中。 我的 Helper 項目中每個 package 的每個 package.json 都標記為sideEffect: false 主要的 package 我在它的主要index.ts文件中有其他包的導出。 我認為它必須與 typescript 相關,因為導入接口工作正常,但對象和函數開始破壞。 任何幫助表示贊賞。

我的 Helper 項目有幾個文件:

// index.ts
export * from './models'; // works sorta fine
export * from './helpers'; // doesn't work for sole export
// models.ts
// importing this and other interface exports works fine
export interface LFRepoWindow {
  [k: string]: any;
  webAccessApi?: WebAccessApi;
}
// importing this export causes the entire package to be imported 
// with all dependencies and 30+mb bundle size
export const notificationTypes = {
  warning: 'warning',
  error: 'error',
  success: 'success',
  information: 'information'
} as const;
// helpers.ts
// Importing this similarly causes all dependencies to bundle and 30+mb bundle size
export const getWebAccessInfo = function(checkFrames = false) {
  const windowList = checkFrames ? Array.from(window.frames) : [window, window.parent, window.top || undefined];
  const waWindow = windowList.find((w) => w?.webAccessApi !== undefined);
  return { waWindow, webAccessApi: waWindow?.webAccessApi, name: waWindow?.name };
}

我的 webpack 配置文件相當復雜,因為它用於從我的 Designer 項目中動態捆綁文件夾,但應該從這個片段中相對理解

const config: webpack.Configuration = {
  devtool: srcMap || env === 'DEV' ? 'inline-source-map' : undefined,
  entry: name.reduce((prev, cur, i) => {
    prev[cur] = path.resolve(curDir, 'src', cur + type[i], 'index');
    return prev;
  }, {} as { [k: string]: string }),
  mode: webpackENVMap[env],
  externals: {
  //   d3: 'd3'
    jquery: 'jQuery'
  },
  module: {
    rules: [
      {
        exclude: /node_modules/,
        test: /\.[jt]sx?$/,
        use: [
          // {
          //   loader: 'babel-loader',
          //   options: { cacheDirectory: true },
          // },
          {
            loader: 'ts-loader',
          },
        ],
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
            options: {
              minimize: true,
              sources: {
              urlFilter: (attribute: string, value: string, resourcePath: string) => {
                if (/\/Forms\/img\//i.test(value)) {
                  return false
                }
              }
            } },
          },
        ],
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: env !== 'DEV' ? true : false,
            },
          },
          'css-loader',
        ],
      },
    ],
  },
  optimization: {
    usedExports: true,
    sideEffects: true,
    moduleIds: 'deterministic',
    runtimeChunk: !splitChunks ? false : 'single',
    splitChunks: !splitChunks
      ? false
      : {
          cacheGroups: {
            vendor: {
              chunks: 'all',
              enforce: true,
              name(module: { context?: string }) {
                // get the name. E.g. node_modules/packageName/not/this/part.js
                // or node_modules/packageName
                const packageName = module.context?.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)?.[1]
                  || module.context || 'vendors';
                // npm package names are URL-safe, but some servers don't like @ symbols
                const packageChunkName = `npm.${packageName.replace('@', '')}`;
                vendorChunks.push(packageChunkName);
                return packageChunkName;
              },
              reuseExistingChunk: true,
              test: nodeModuleRegex,
            },
          },
        },
  },
  output: {
    filename: `[name]${splitChunks ? '.[' + hashType + ']' : ''}.js`,
    path: path.resolve(curDir, 'dist'),
    publicPath:
      env === 'DEV'
        ? 'http' + '://' + forms.DEV_HOST_NAME + ':' + forms.DEV_PORT
        : 'https' + '://' + forms.HOST_NAME + forms.FORMS_BUILD_LOCATION,
    // ? forms.PROTOCOL + '://' + forms.DEV_HOST_NAME + ':' + forms.DEV_PORT
    // : forms.PROTOCOL + '://' + forms.HOST_NAME + forms.FORMS_BUILD_LOCATION,
  },
  plugins: [
    new webpack.WatchIgnorePlugin({ paths: [/(css)\.d\.ts$/] }),
    ...(shouldClean ? [new CleanWebpackPlugin()] : []),
    new MiniCssExtractPlugin({
      filename: env === 'PROD' ? '[name].css' : '[name].[' + hashType + '].css',
    }),
    ...name.map(
      n =>
        new HtmlWebpackPlugin({
          chunks: [n],
          filename: `${n}.html`,
          template: path.resolve(__dirname, '../assets', './index.html'),
        }),
    ),
    new webpack.ids.HashedModuleIdsPlugin(),
  ],
  resolve: {
    alias: {
      // '@root': path.resolve(__dirname, '../'),
    },
    fallback: {
      "tty": require.resolve("tty-browserify"),
      "path": require.resolve("path-browserify"),
      "util": require.resolve("util/"),
      "stream": require.resolve("stream-browserify"),
      "crypto": require.resolve("crypto-browserify"),
      "zlib": require.resolve("browserify-zlib"),
      "https": require.resolve("https-browserify"),
      "http": require.resolve("stream-http"),
      "vm": false, //require.resolve("vm-browserify"),
      "fs": false,
      "os": false,
      "worker_threads": false,
      "assert": false,
      "module": false,
      "console": false,
      "inspector": false,
      "esbuild": false,
      "@swc/core": false,
      "child_process": false,
      "constants": false,
    },
    extensions: ['.tsx', '.ts', '.js'],
  },
  stats: withMultiple ? 'minimal' : 'verbose',
  target: 'web',
}

如果有人碰巧遇到這個問題,我的問題是我的 tsconfig 文件沒有設置為module: 'es6' :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM