shlomiassaf / webpack-dll-bundles-plugin

A Webpack plugin for bundling group of packages as DLLs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[question] adding separate files into ddls

karolmie1 opened this issue · comments

I want to add few files I use to ddls, for example:

  [50] ./~/core-js/es6/array.js 944 bytes {3} [built]
  [51] ./~/core-js/es6/date.js 231 bytes {3} [built]
  [52] ./~/core-js/es6/function.js 185 bytes {3} [built]
  [53] ./~/core-js/es6/map.js 207 bytes {3} [built]
  [54] ./~/core-js/es6/math.js 690 bytes {3} [built]
  [55] ./~/core-js/es6/number.js 602 bytes {3} [built]
  [56] ./~/core-js/es6/object.js 881 bytes {3} [built]
  [57] ./~/core-js/es6/parse-float.js 95 bytes {3} [built]
  [58] ./~/core-js/es6/parse-int.js 91 bytes {3} [built]
  [59] ./~/core-js/es6/reflect.js 717 bytes {3} [built]
  [60] ./~/core-js/es6/regexp.js 345 bytes {3} [built]
  [61] ./~/core-js/es6/set.js 207 bytes {3} [built]
  [62] ./~/core-js/es6/string.js 1.13 kB {3} [built]
  [63] ./~/core-js/es6/symbol.js 130 bytes {3} [built]
  [64] ./~/core-js/es6/typed.js 596 bytes {3} [built]
  [65] ./~/core-js/es6/weak-map.js 175 bytes {3} [built]
  [66] ./~/core-js/es6/weak-set.js 173 bytes {3} [built]

Right now, I've added

polyfills: [
   'core-js',
]

but I don't know how to add core-js/es6. I think I've tried every combination. Each trial ends with something like:

DLL: Checking if DLLs are valid.
Error: Package name mismatch, Expected core-js/es6 but found core-js 
    at webapp/node_modules/src/DllBundlesControl.ts:126:21
    at process._tickCallback (internal/process/next_tick.js:103:7)
    at Module.runMain (module.js:607:11)
    at run (bootstrap_node.js:420:7)
    at startup (bootstrap_node.js:139:9)
    at bootstrap_node.js:535:3

I could do it when I was using just ddl plugin.
Is there a way to include separate files into bundle?

Yes & No...

The native DllPlugin is a low level construct to create DLL's, it has no logic to enforce business logic on those dlls.

The dll bundles plugin wraps logic around DLLs so they are:

  1. Grouped
  2. Cached & validated

To implement cache we use the version in package.json and we expect a package not single files.

Single files, part of an npm package (YES)

You can add custom files as long as they are part of a package (which is the case for you)

     new DllBundlesPlugin({
        bundles: {
          polyfills: [
            'core-js',
            {
              name: 'zone.js',
              path: 'zone.js/dist/zone.js'
            },
            {
              name: 'zone.js',
              path: 'zone.js/dist/long-stack-trace-zone.js'
            },
            'ts-helpers',
          ],
          vendor: [
            '@angular/platform-browser',
            '@angular/platform-browser-dynamic',
            '@angular/core',
            '@angular/common',
            '@angular/forms',
            '@angular/http',
            '@angular/router',
            '@angularclass/hmr',
            'rxjs',
          ]
        },
        dllDir: helpers.root('dll'),
        webpackConfig: webpackMergeDll(commonConfig({env: ENV}), {
          devtool: 'cheap-module-source-map',
          plugins: []
        })
      }),

In the example above we can see that zone.js as a package name is used twice

The first instance loads the main package file:

    {
              name: 'zone.js',
              path: 'zone.js/dist/zone.js'
     }

The second instance loads a file that is not part of the bundle and used in development for long stack traces.

    {
              name: 'zone.js',
              path: ''zone.js/dist/long-stack-trace-zone.js'
     }

Key point here is that the package name is set explicitly via the name property, this must match the name property in the file package.json

The plugin will search for package.json in the path supplied and will go up a directory until it finds the first one, that must match the name.

Important note:

Some npm packages comes with 2 versions included:

  • es6 module
  • umd bundle

Make sure you know what you'r doing. In the above example I specifically set the main umd bundle in the 1st item and the 2nd is the extra file, I don't give webpack the ability to select the modules version (if exists)

When marking single files make sure these files are not part of the module.

Single files, part of the project

For separate files, not part of an npm pacakge, there is not support (yet).
To support that, a hashing logic needs to be implemented so every file used in a bundle is hashed and that hash is stored. On every webpack dev server start these files are re-calculated to compare the hash to the stored hash, this how cached files can be invalidated.

This is an expansive process that I don't know if it has value...

Another option is to allow pointing out a version file, passing the responsibility for cache invalidation to the user.

Anyway, I don't think there's much value here.

Wow, this is really exhaustive answer. Now i understand how it works, and I was able to configure dll properly. Thank you, kind soul!

This answer was really helpful as I was struggling with the same thing - trying to add a single file from my project into a vendor bundle. I have to do this since a dependency I'm using, darsain-tooltips, was built for component and doesn't have built files in the package - built file is hosted elsewhere and I had to manually add it into my code base, but would still like to bundle it with vendor dependencies. I assume there's no way to accomplish this?

Anyway, the info your answer would be great in the readme or wiki!

I nearly thought I had it with a horrendous hack: making a sort of fake module with the built vendor library (darsain-tooltips.js), inside it's own directory in my source tree alongside the following invented package.json:

{
    "name": "darsain-tooltips",
    "version": "0.0.1",
    "main": "darsain-tooltips.js"
}

That way I could manually update the vendor library when needed and update the version number.

Then I tried to include it in the bundle:

 new DllBundlesPlugin({
    bundles: {
      vendor: [
        '@angular/platform-browser',
        '@angular/platform-browser-dynamic',
        'etc...',
        {
          name: 'darsain-tooltips',
          path: process.cwd() + '/src/app/vendor/darsain-tooltips'
        },
      ]
    },

In my own code I use it like so:

import * as Tooltips from '../vendor/darsain-tooltips';

However, the library still ended up in my main bundle and not the vendor bundle. I'm guessing somehow the name or some other identifiers didn't line up in some way.

I'm almost glad it didn't work because it's such a ridiculous hack.

For now I'll include these vendor libraries in my main bundle.