Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack implicit vendor bundle with polyfill bundle

I would like to build three bundles: main.js, vendor.js and polyfill.js. polyfill.js file should contain the modules defined in polyfill.js file. vendor.js file should be dynamically created by extracting all the dependencies imported from npm(node_modules). Finally main.js should contain other than polyfill and vendor modules, which is essentially my app code.

polyfill.js

import 'core-js/es7/reflect';
import 'zone.js/dist/zone';

main.js

import { NgModule, ApplicationRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Store } from '@ngrx/store';

@NgModule([
    imports: [...]
])
class AppModule {
}

I've written following webpack config but always get following error:

"CommonsChunkPlugin: While running in normal mode it's not allowed to use a non-entry chunk (main)",
    "CommonsChunkPlugin: While running in normal mode it's not allowed to use a non-entry chunk (vendor)"

webpack.config.prod.js

{
  entry: {
    polyfill: './polyfill.ts',
    main: './main.ts'
  },
  output: {
    publicPath: options.assetPath
  },
  devtool: 'source-map',
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module) {
        const check = module.context && module.context.indexOf('node_modules') !== -1;        
        module.originalChunkNames = module.chunks.map(chunk=> chunk.name);
        return check;
      }
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'polyfill',
      chunks: ['vendor'],
      minChunks: ({ originalChunkNames }) => originalChunkNames.includes('polyfill'),
    }),
    new webpack.optimize.CommonsChunkPlugin({
      names: ['main', 'vendor', 'polyfill'],
      minChunks: Infinity
    })
  ]
}

Here what I would like to do is dynamically create vendor bundle including all node_modules I import in my source files. Create polyfill bundle by including all module explicitly defined in polyfill.js file. And the final main bundle.

I've tried lots of example from webpack github repo but none of them helped me to achieve something like above mentioned

like image 216
Lekhnath Avatar asked Nov 08 '22 22:11

Lekhnath


1 Answers

I've created a Github repository to demonstrate the working example.

Below is important part of webpack configuration to achieve this type of output:

{
  entry: {
    polyfill: 'polyfill.ts',
    main: 'main.ts'
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      chunks: ["main"],
      minChunks: function(module) {
        const check =
          module.context && module.context.indexOf("node_modules") !== -1;
        module.originalChunkNames = module.chunks.map(chunk => chunk.name);
        return check;
      }
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: "polyfill",
      chunks: ["vendor"],
      minChunks: function({ originalChunkNames }) {
        return originalChunkNames.includes("polyfill");
      }
    }),
  ]
}
like image 68
Lekhnath Avatar answered Nov 26 '22 05:11

Lekhnath