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

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.

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Reactions: 84
  • Comments: 35 (4 by maintainers)

Commits related to this issue

Most upvoted comments

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">

@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.

FYI, if you followed the code splitting example in the webpack 2 docs and are seeing this error, another possible cause is that you forgot to include the manifest.js file in your HTML page. (That was the root cause of the issue for me.)

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.

@shahabganji If you create a manifest.js file as described in the webpack 2 code splitting documentation, then that file contains all the webpack runtime code. Your other bundle files (main, vendor, etc.) will be generated without the runtime code but they will depend on that runtime code being loaded in order to function properly. Because of this, the manifest.js file needs to be loaded in your HTML along with the other bundle files. Otherwise, you’ll get an error about webpackJsonp not being defined and things won’t work.

If you don’t create a manifest.js file and just create a vendor bundle, then the webpack runtime code will be placed in your vendor.js file and no separate manifest file is needed.

Note that “manifest” is not a special name. If you specify a bundle name that doesn’t have a corresponding key in the entry section, then the CommonsChunkPlugin will put the remaining common code (which is just the webpack runtime stuff) into that bundle file. So you could call it “runtime” or “webpack” and get a file with a different name but the same purpose.

Adding jsonpFunction:“webpackJsonp” to the output of config solved the issue for me. module.exports = { output: { jsonpFunction:‘webpackJsonp’ } }

Can any one help me on the above issue please

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…

HI there! Could anybody explain me the difference between these two configurations:

        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            filename: 'vendor.[chunkhash].js',
            minChunks (module) {
                **return module.context && module.context.indexOf('node_modules') >= 0;**
            }
        }),

and the second:

        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            filename: 'vendor.[chunkhash].js',
        	**minChunks: Infinity**
        }),

I was using the first, but IE 10 thrown me a webpackJsonp is not defined error. So the second config solves this issue. But is there a big difference between them? Sorry for noob question.

same issue here, our files order is ok in our html, we added Infinity option:

new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: '[name]' + (prod ? '.[hash].js' : '.js'), minChunks: Infinity }),

We can’t reproduce the issue but we have a lot of error logs from differents browsers (safari 10.1.1 on Mac OS X 10.12, Chrome 59.0.3071 on Windows 7 and some firefox 54)

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.

And as a reminder, the order the files are loaded does matter. If you load client.js then vendor.js (assuming no manifest) then you’ll get the error. vendor (or manifest) must be loaded first.

My case is that manifest need to load before vendor

@shidaping not work with

new ScriptExtHtmlWebpackPlugin({
    defaultAttribute: 'async'
})

@sbrudz thanks! lack of manifest was my issue as well.

This might help someone:

If there are multiple webpack runtimes on the same page (e.g.a third party script, also compiled with webpack) you might need to rename output.jsonpFunction if the other script also is using the default jsonpFunction name.

https://webpack.js.org/configuration/output/#outputjsonpfunction

This needs to be changed if multiple webpack runtimes (from different compilation) are used on the same webpage

webpack example

module.exports = {
  //...
  output: {
    jsonpFunction: 'MyLibrary'
  }
}

vue-cli (vue.config.js) example:

module.exports = {
  //...
  configureWebpack: {
    output: {
      jsonpFunction: 'ThirdPartyServicesShouldNamespaceStuff'
    }
}
`

A similar problem, I get this error in Chrome:

Uncaught ReferenceError: webpackJsonp is not defined at main.js:1

it relates to this first line of code webpackJsonp([19], {
of course this is closed later on.

It seems similar and I’m new to Webpack, anyone know what it could be?

The best solution for this issue it to install/sync the version of @ionic/app-scripts , I faced this issues multiple times when I updated my machine (for cordova, ionic, app-script versions).

This is my system config, ( notice app-script), when I updated to app-script to 3.1.9, everything fucking things got messed up, than I came back to 1.3.7, and everything became awesome again. !!

image

we had the same issue, turns out our vendor.js and app.js are loaded dynamically by JavaScript (document.createElement(‘script’)…), and by default the scripts are executed asynchronously when they are loaded dynamically, so we just need to set the async to false, so that we make sure vendor.js executed first, that will make sure the webpackJsonp is defined.