Uncaught ReferenceError: webpackJsonp is not defined with Code Splitting and -p flag #368

Closed
dsawardekar opened this Issue Jul 20, 2014 · 11 comments

Projects

None yet

6 participants

@dsawardekar

I have a basic react app built with webpack. The app has 2 files app/app.js and app/vendor.js. The vendor.js file requires a few libraries like es5-shim, react, jquery etc. And the app/app.js uses the same libraries but also has a React component that is rendered on the page on load.

My webpack.config.js is using Code Splitting. I would like to split the final app into dist/app.js and dist/vendor.js. The dist/app.js should contain only app code and dist/vendor.js contains all the external libraries. The config is show below,

var webpack = require('webpack');

module.exports = {
  entry: {
    app: './app/app.js',
    vendor: './app/vendor.js',
  },
  output: {
    path: 'dist',
    filename: '[name].js'
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin('vendor.js')
  ],
  externals: {
    'jquery': 'jQuery'
  },
  module: {
    loaders: [
      { test: /\.js$/, loader: 'jsx-loader' }
    ]
  }
};

This works fine and produces the 2 different files I needed. But when I use the -p flag to build a production version the app stops working with the error,

Uncaught ReferenceError: webpackJsonp is not defined

I have a feeling I'm using the CommonsChunkPlugin incorrectly. Is this the correct plugin for splitting an app into 2 files vendor and app?

Thanks.

@sokra
Member
sokra commented Jul 20, 2014

I assue you want to have ./app/vendor.js in the commons chunk. But your current config means: Create 2 entry chunks app and vendor and extract a commons chunk vendor.js from both chunks. (And this causes a filename conflict as both have the same name)

The commons chunk plugin can use an exisiting chunk if it has the same name. By default the commons chunk name is the filename (in your case vendor.js). So the vendor entry point should be named vendor.js to make the commons chunk plugin use it.

  entry: {
    app: './app/app.js',
    'vendor.js': './app/vendor.js',
  },

In the newest beta version there is a new optional parameter for the CommonsChunkPlugin so you could alternativly pass vendor as name:

  plugins: [
    new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js')
  ],

From a technical view it makes no sense to use the CommonsChunkPlugin with a single app entry. It only looks better. It costs an additional HTTP request and doesn't give you anything in production. While development it has faster incremental compiling.

A commons chunk makes only sense with multiple entries...

@dsawardekar

@sokra Thanks for the quick response. I agree about the number of HTTP requests. Faster incremental compiling is one of the reasons I'm trying to do this.

I made the your suggested change, switching to CommonsChunkPlugin('vendor', 'vendor.js'). However now the app.js is being compiled without anything in it with the -p flag. It's output is,

webpackJsonp([1],[]);

Webpack version is, 1.3.2-beta3

@sokra
Member
sokra commented Jul 20, 2014

yes, the CommonsChunkPlugin move all modules that are common in the remaining chunks into the commons chunk. Because there is only one remaining chunk all modules are moved into the commons chunk.

Try to use:

new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js', Infinity)
@dsawardekar

@sokra Thanks, using Infinity works in production mode as well.

I'm starting to come around to webpack's approach. But I'd suggest making this requirement an important intermediate step to get more people to adopt webpack.

Coming from grunt or a gulp based build tool, it's common to build 2 production assets like vendor and app. This is particularly useful when the vendor doesn't change often.

You could hide this behind a new VendorChunkPlugin or document the above approach for anyone wanting to build 2 assets.

If you can point me in the right direction, I'd be happy to make a PR for this. Thanks.

@sokra
Member
sokra commented Jul 24, 2014

We can add this to the documentation. (Feel free to do it, there is a edit button in the documentation.)

I don't like to create an additional plugin that does mostly the same. I think this confuses more.

I change the default value of the minChunkCount parameter to a minimum of 2. Moving all modules from a chunk makes so sense. So you can omit the Infinity in your case.

@sokra sokra added a commit that referenced this issue Jul 24, 2014
@sokra sokra minCount default should not be 1 or lower
fixes #368
15045d2
@dsawardekar

@sokra I've added a small section to the Chunk optimization section of the Code splitting page. Let me know if you'd like any changes.

@sokra
Member
sokra commented Jul 24, 2014

Thanks

@samithaf samithaf referenced this issue in AngularClass/NG6-starter Mar 31, 2016
Open

Uncaught ReferenceError: webpackJsonp is not defined #88

@steinbachr
steinbachr commented Sep 15, 2016 edited

for me as well I was tripped up by the requirement of minChunks: Infinity. Previous configuration of:

....
entry: {
        main: './src/Main.react.js',
        core: ['jquery', 'backbone', 'react', 'react-dom', 'react-router', 'react-helmet']
},

output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].[hash].bundle.js',
        chunkFilename: '[id].[hash].bundle.js',
        publicPath: '//static.rukkus.com/js/spa/dist/'
},

plugins: [
        ....
        new webpack.optimize.CommonsChunkPlugin({
            names: ['core'],
            filename: '[name].js'
        }),
        ...
    ]

was yielding the webpackJsonp is not defined error. However, adding minChunks: Infinity to the CommonsChunkPlugin config fixed the issue.

@shidaping
shidaping commented Oct 10, 2016 edited

you do not import vendor.js in your html.
try to add
<script type="javascript" src="./dist/vendor.js">
to your html file
before
<script type="javascript" src="./dist/app.js">

@llam001 llam001 referenced this issue in hassanqaiser/angular2_webpack2_esri Oct 11, 2016
Open

How to deploy production build app? #1

@luckydrq
luckydrq commented Nov 1, 2016

From a technical view it makes no sense to use the CommonsChunkPlugin with a single app entry.

@sokra I think an additional http request may not cause situation worse. On one side, modern browsers support multiple download threads which makes resource download duration shorter i think. On the other side, if resource changes, the common chunk which refers to vendor chunk you guys discussed above probably not change at all, so it can be cached by cdn or static server.

@FAOfao931013

@shidaping it solved my problem webpackJsonp is not defined

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