Webpack 5 bundle doesn't exclude externals

25 Views Asked by At

My needs

I am creating a Typescript React component library for internal applications, using mainly material-ui 5. I need it to be as slim as possible.

My files

webpack.config.js

// imports

module.exports = {
  entry: 'src/index.ts',
  mode: 'production',
  output: {
    clean: true,
    path: path.join(__dirname, 'dist'),
    filename: 'titn.js',
    globalObject: 'this',
    library: {
      name: 'thisisthename',
      type: 'umd',
    },
  },
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin({ extractComments: false }), new CssMinimizerPlugin()],
  },
  externals: [
    'react',
    'moment',
    'react-dom',
    'react-intl',
    'react-router-dom',
    'react/jsx-runtime',
    /^@mui\/material\/.+$/,
    /^@mui\/icons-material\/.+$/,
    /^@mui\/lab\/.+$/,
  ],
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: ['babel-loader'],
        exclude: /node_modules/,
      },
      {
        test: /\.(c|sc)ss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ],
  },
  resolve: {
    modules: [__dirname, 'src', 'node_modules'],
    extensions: ['.js', '.ts', '.tsx', '.scss', '.svg'],
  },
  plugins: [
    new MiniCssExtractPlugin(),
    new BundleAnalyzerPlugin({ analyzerMode: 'static', reportFilename: 'bundle-report.html' }),
  ],
}

package.json

For information, the peer dependencies are ony declared in their block, neither in dependencies nor in devDependencies.

{
  "name": "thisisthename",
  "version": "4.0.0",
  "description": "...",
  "main": "dist/titn.js",
  "types": "dist/types/index.d.ts",
  "private": false,
  "author": "Me",
  "license": "ISC",
  "files": [
    "/dist",
    "README.md",
    "package.json"
  ],
  "repository": {
    "type": "git",
    "url": "..."
  },
  "scripts": {
    "build": "rm -rf dist && NODE_ENV=production webpack --config webpack.config.js && tsc",
    "prepare": "husky"
  },
  "publishConfig": {
    "registry": "...",
    "access": "public"
  },
  "peerDependencies": {
    "@mui/icons-material": "^5.15.12",
    "@mui/lab": "^5.0.0-alpha.167",
    "@mui/material": "^5.15.11",
    "moment": "^2.30.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-intl": "^6.6.2",
    "react-router-dom": "^6.22.2"
  },
  "dependencies": {
    ...
  },
  "devDependencies": {
    ...
  }
}

My problem

The bundle generated by webpack weighs 1.86Mo, which is way too much - when I remove all the code below my bundle, I fall back to 27Ko which is way better.

Here is an excerpt of the bundle-report.html

When I inspect the titn.js bundle, I can find my bundled code along with dependencies that I explicitely excluded from the bundle:

  • react-is.production.min.js (included two times !!)
  • is-plain-object
  • is-object
  • object-assign
  • jedwatson.github.io/classnames (not even in my package.json)
  • stylis (not even in my package.json)

Why would these dependencies be included in the bundle ?

I tried including various webpack plugins.

0

There are 0 best solutions below