title: Webpack: Common chunks for code shared between Webworker and Web code?
body: <p>I have lots of code shared between web and web worker parts of my browser app.</p>
  
  <p>How can I tell webpack to split my code up into common chunks so that the result is garanteed to work 100%?</p>
  
  <p>The webworker code breaks (fails at runtime) after I tell webpack to generate the common chunks (which it does). Even after I fix the trivial "window not defined" error the worker just does nothing.</p>
  
  <p>I believe this has to do with the webpack "target" option, which per default is set to "web". But I need "web" target because I don't have purely webworker code.</p>
  
  <p>I also cannot do multiple webpack configs because I cannot do the common chunks thing with multiple configs...</p>
  
  <p>What should I do?</p>
  
  <p>If anybody is interested: I am trying build a minimal sized build for my app which includes the monaco editor (which provides the workers):</p>
  
  <p><a href="https://github.com/Microsoft/monaco-editor/blob/master/docs/integrate-esm.md" rel="noreferrer">https://github.com/Microsoft/monaco-editor/blob/master/docs/integrate-esm.md</a></p>
  
  <p>You can see here (at the bottom of the page) that the entry points consist of 1 main entry file + the workers.</p>
  
  <p>Currently at least 6 MB is wasted because of duplicate code I am using and currently can not be split up because of this problem. That is a lot of wasted traffic.</p>
  
  <p>Any ideas? :)</p>
  
  <p>my webpack 4.1.1 config is basically:</p>
  
  <pre><code>module.exports = (env, options) =&gt; {
      const mode = options.mode;
      const isProduction = mode === 'production';
      const outDir = isProduction ? 'build/release' : 'build/debug';
  
      return {
  
          entry: {
              "app": "./src/main.tsx",
              "editor.worker": 'monaco-editor/esm/vs/editor/editor.worker.js',
              "ts.worker": 'monaco-editor/esm/vs/language/typescript/ts.worker.js'
          },
          output: {
              filename: "[name].bundle.js",
              path: `${__dirname}/${outDir}`,
              libraryTarget: 'umd',
              globalObject: 'this',
              library: 'app',
              umdNamedDefine: true
          },
          node: {
              fs: 'empty' 
          },
          devtool: isProduction ? undefined : "source-map",
          resolve: {
              extensions: [".ts", ".tsx", ".js", ".json"],
              alias: {
                  "@components": path.resolve(__dirname, "src/components"),
                  "@lib": path.resolve(__dirname, "src/lib"),
                  "@common": path.resolve(__dirname, "src/common"),
                  "@redux": path.resolve(__dirname, "src/redux"),
                  "@services": path.resolve(__dirname, "src/services"),
                  "@translations": path.resolve(__dirname, "src/translations"),
                  "@serverApi": path.resolve(__dirname, "src/server-api")
              }
          },
          optimization: isProduction ? undefined : {
              splitChunks: {
                  minSize: 30000,
                  minChunks: 1,
                  name: true,
                  maxAsyncRequests: 100,
                  maxInitialRequests: 100,
                  cacheGroups: {
                      default: {
                          chunks: "all",
                          priority: -100,
                          test: (module) =&gt; {
                              const req = module.userRequest;
                              if (!req) return false;
                              return (!/node_modules[\\/]/.test(req));
                          },
                      },
                      vendor: {
                          chunks: "all",
                          test: (module) =&gt; {
                              const req = module.userRequest;
                              if (!req) return false;
                              if (!/[\\/]node_modules[\\/]/.test(req)) return false;
                              return true;
                          },
                          priority: 100,
                      }
                  }
              },
          },
          module: {
              rules: [...(isProduction ? [] : [
                  {
                      enforce: "pre", test: /\.js$/, loader: "source-map-loader",
                      exclude: [
                          /node_modules[\\/]monaco-editor/ 
                      ]
                  }
              ]),
              {
                  test: require.resolve('jquery.hotkeys'),
                  use: 'imports-loader?jQuery=jquery'
              },
              {
                  test: /\.tsx?$/,
                  loader: "awesome-typescript-loader",
                  options: {
                      configFileName: 'src/tsconfig.json',
                      getCustomTransformers: () =&gt; {
                          return {
                              before: [p =&gt; keysTransformer(p)]
                          };
                      }
                  }
              },
              {
                  test: /\.(css|sass|scss)$/,
                  use: extractSass.extract({
                      use: [
                          {
                              loader: 'css-loader',
                              options: {
                                  minimize: isProduction
                              }
                          },
                          {
                              loader: "postcss-loader",
                              options: {
                                  plugins: () =&gt; [autoprefixer({
                                      browsers: [
                                          'last 3 version',
                                          'ie &gt;= 10'
                                      ]
                                  })]
                              }
                          },
                          { loader: "sass-loader" }
                      ],
                      fallback: "style-loader"
                  })
              },
              {
                  test: /node_modules[\/\\]font-awesome/,
                  loader: 'file-loader',
                  options: {
                      emitFile: false
                  }
              },
              {
                  test: { not: [{ test: /node_modules[\/\\]font-awesome/ }] },
                  rules: [
                      {
                          test: { or: [/icomoon\.svg$/, /fonts[\/\\]seti\.svg$/] },
                          rules: [
                              { loader: 'file-loader?mimetype=image/svg+xml' },
                          ]
                      }, {
                          test: { not: [/icomoon\.svg$/, /fonts[\/\\]seti\.svg$/] },
                          rules: [
                              {
                                  test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
                                  use: {
                                      loader: 'svg-url-loader',
                                      options: {}
                                  }
                              },
                          ]
                      },
                      {
                          test: /\.(png|jpg|gif)$/,
                          loader: 'url-loader'
                      },
                      { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?mimetype=application/font-woff" },
                      { test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?mimetype=application/font-woff" },
                      { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?mimetype=application/octet-stream" },
                      { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader" },
                  ]
              },
  
              ]
          },
          plugins: [
              new HardSourceWebpackPlugin({
                  cacheDirectory: '../node_modules/.cache/hard-source/[confighash]', configHash: function (webpackConfig) {
                      return require('node-object-hash')({ sort: false }).hash(Object.assign({}, webpackConfig, { devServer: false }));
                  },
                  environmentHash: {
                      root: process.cwd(),
                      directories: [],
                      files: ['../package-lock.json'],
                  }
              }),
              new webpack.ProvidePlugin({
                  "window.$": "jquery"
              }),
              new CleanWebpackPlugin(outDir),
              extractSass,
              new HtmlWebpackPlugin({
                  title: 'my title',
                  filename: 'index.html',
                  minify: isProduction ? {
                      collapseWhitespace: true,
                      collapseInlineTagWhitespace: true,
                      removeComments: true,
                      removeRedundantAttributes: true
                  } : false,
                  template: 'index_template.html',
                  excludeChunks: ['ts.worker', "editor.worker"]
              }),
              new webpack.IgnorePlugin(/^((fs)|(path)|(os)|(crypto)|(source-map-support))$/, /vs[\\\/]language[\\\/]typescript[\\\/]lib/)
          ].concat(isProduction ? [new webpack.optimize.LimitChunkCountPlugin({
              maxChunks: 1
          })] : [])
      }
  };
  </code></pre>