Skip to content

Referencing dependencies from one chunk in another #369

Closed

Description

@kflorence

I've got chunks split between head and body end, in some of the body end chunks it needs to reference things that were defined in the head chunk. If I require it in the body chunk, the dependency will end up in both head and body chunks. The only solution I can think of is having multiple compiler points and exporting the head dependencies and using them as externals in the body chunk, but I don't really want to do that. Is there a better way?

Activity

  1. sokra commented on Jul 21, 2014

    @sokra
    Member

    You can do it this way:

    var webpack = require("webpack");
    module.exports = {
      entry: {
        head: "./head.js",
        body: "./body.js"
      },
      output: {
        filename: "[name].js"
      },
      plugins: [
        new webpack.optimize.CommonsChunkPlugin("body", "body.js", ["head"], Infinity)
      ]
    };
  2. kflorence commented on Jul 21, 2014

    @kflorence
    Author

    @sokra Hm, that doesn't seem to be working (webpack 1.3.2-beta1). Now I have the duplicated dependency in head.js and the body chunk (instead of body.js).

    A little more details:

    • In "head" there is an amd module called "track-stub" which provides a simple API stub for tracking calls before the full API is implemented in body.
    • In body, there is an amd module called "track" which required "track-stub" so it can fill out the API.

    This results in "track-stub" being defined in head (good) but it also gets duplicated in body (bad) because of the define call that lists it as a dependency.

    Here is my full config:

    module.exports = {
      context: path.resolve(paths.scripts.src),
      entry: {
        "body": "./body",
        "head": "./head",
        "home": "./home",
        "places": "./places"
      },
      externals: {
        handlebars: "Handlebars",
        jquery: "jQuery",
        zeroclipboard: "ZeroClipboard"
      },
      output: {
        path: path.resolve(paths.scripts.dest),
        publicPath: paths.publicPath,
        filename: "[name].js"
      },
      plugins: [
        new webpack.optimize.CommonsChunkPlugin("body", "body.js", ["head"], Infinity)
      ],
      resolve: {
        alias: {
          bootstrap: "bootstrap-sass-official/vendor/assets"
        },
        modulesDirectories: ["node_modules", "bower_components"],
        root: [paths.scripts.src]
      }
    };
  3. sokra commented on Jul 21, 2014

    @sokra
    Member

    ups I got it wrong. It's

    new webpack.optimize.CommonsChunkPlugin("head", "head.js", ["body"], Infinity)
  4. kflorence commented on Jul 21, 2014

    @kflorence
    Author

    After updating to webpack 1.3.2-beta3 and changing my config to:

    new webpack.optimize.CommonsChunkPlugin("head", "head.js", ["body"], Infinity)

    It seems to be working correctly. I will confirm shortly.

  5. kflorence commented on Jul 21, 2014

    @kflorence
    Author

    Haha, just figured that out as well :) BTW what does the Infinity do?

  6. kflorence commented on Jul 21, 2014

    @kflorence
    Author

    @sokra Confirmed that it's working. Both of the modules are using the AMD web + global pattern, but since they are inside webpack bundles this is just an empty Object. Changing it to window fixed it :)

  7. kflorence commented on Aug 7, 2014

    @kflorence
    Author

    @sokra Now I have a similar issue when trying to reference dependencies in different bundles. For example, I have a "common/head" bundle and a "common/body" bundle which load common assets that go inside the <head> tag and at the end of the <body> tag, respectively. The solution above works fine for these two files (where "common/body" depends on something in "common/head") -- but now I'm getting duplication in my entry files, for example "page1" entry that depends on something defined in "common/body" -- is there an easy way to link these dependencies other than looping through all of the defined entry points and adding more CommonsChunkPlugin instances for them?

  8. kflorence commented on Aug 7, 2014

    @kflorence
    Author

    Also, I think this will be a fairly common case for users with multiple bundles where some of those bundles store common dependencies.

  9. sokra commented on Aug 7, 2014

    @sokra
    Member

    These r.js config maps to this webpack config:

    {
      entry: {
        page1: "app/main1",
        page2: "app/main2"
      },
      plugins: [
        new webpack.optimize.CommonJsPlugin("common.js")
      ]
    }
  10. kflorence commented on Aug 8, 2014

    @kflorence
    Author

    @sokra I think I've got it figured out:

    var plugins = [
      // Automatically split commonly used assets into the "common/body" bundle.
      new webpack.optimize.CommonsChunkPlugin("common/body", "[name].js", nonCommonEntryPoints),
      // Make sure dependencies that are loaded in "common/head" bundle
      // and depended on in "common/body" bundle don't get duplicated.
      new webpack.optimize.CommonsChunkPlugin("common/head", "[name].js", ["common/body"], Infinity),
    ];

    Where nonCommonEntryPoints is an array of entry points without the common files included, like:

    ["page1", "page2"]

    Thanks for your help, as always.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions