Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
dsawardekar opened this issue Jul 20, 2014 · 35 comments

Comments

@dsawardekar
Copy link

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
Copy link
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
Copy link
Author

@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
Copy link
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
Copy link
Author

@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
Copy link
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 added a commit that referenced this issue Jul 24, 2014
@dsawardekar
Copy link
Author

@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
Copy link
Member

sokra commented Jul 24, 2014

Thanks

@steinbachr
Copy link

steinbachr commented Sep 15, 2016

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
Copy link

shidaping commented Oct 10, 2016

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

@luckydrq
Copy link

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
Copy link

@shidaping it solved my problem webpackJsonp is not defined

@sbrudz
Copy link

sbrudz commented Feb 7, 2017

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

@sag1v
Copy link

sag1v commented Mar 20, 2017

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

@uinz
Copy link

uinz commented May 7, 2017

@shidaping not work with

new ScriptExtHtmlWebpackPlugin({
    defaultAttribute: 'async'
})

@shahabganji
Copy link

@sbrudz Why should we add the manifest file in our HTML? does it not have any overloads?

@sbrudz
Copy link

sbrudz commented May 26, 2017

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

@nuclearspike
Copy link

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.

@shahabganji
Copy link

@nuclearspike yeah, that's JavaScript rules 👍🏻👍🏻

@dottodot
Copy link

Is there anything that would cause this error. My files are loaded in order and I have a manifest.js file.

@halben
Copy link

halben commented Jun 26, 2017

If you're using the script async attribute, remove it.

@dottodot
Copy link

I'm not using the async attribute so it's not that.

@shahabganji
Copy link

@dottodot, In my case it was owing to not referencing the manifest.js file prior to my application files.

@pixedd
Copy link

pixedd commented Jul 12, 2017

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)

@jeantimex
Copy link

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.

@demanzonderjas
Copy link

I had the same problem and solved it by including commons.js (which is built via the CommonChunks plugin) first in the index.php, then the other bundle(s).

@rishmaflipkart
Copy link

rishmaflipkart commented Sep 27, 2017

Adding jsonpFunction:"webpackJsonp" to the output of config solved the issue for me.
module.exports = {
output: {
jsonpFunction:'webpackJsonp'
}
}

@01Kuzma
Copy link

01Kuzma commented Oct 9, 2017

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.

@Pranidhi0421
Copy link

I am having same issue even after adding infinity and manifest.

entry: {
vendor: ['react', 'react-dom'],
app: [
'babel-polyfill',
"./src/app.jsx",
]
}

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

@Pranidhi0421
Copy link

Can any one help me on the above issue please

@TimeBandit
Copy link

I came across exact same error message. As stated by others, your 'common' chunk must be loaded before your 'app' chunk. My HTML loaded them in the correct order but I was seeing this issue because the defer attribute was set defer="defer" in the script tag for the 'common' chunk. The solution was to set them both to defer or not to defer.

@ethannguyens
Copy link

My case is that manifest need to load before vendor

@nikhilknoldus
Copy link

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

klinker24 added a commit to Serubin/pulse-sms-web that referenced this issue Jul 27, 2018
@tomuplec
Copy link

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?

@olofsellgren
Copy link

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'
    }
}
`

@talhaanees
Copy link

@olofsellgren Now it says mylibrary is not defined. Sorry new to webpack any idea why this is happening?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests