Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webpackJsonp is not defined

Codes

This is my webpack.babel.js

entry section:

entry: {
   vendor: [
       "react",
       "react-dom"
    ]
}

// 自动获取路径(主动获取写的逻辑代码)
let files = glob.sync('./src/**/index.js'),
    newEntries = files.reduce(function (memo , file) {
        let name = /.*\/(.*?)\/index\.js/.exec(file)[1];

        memo[name] = entry(name);

        return memo;
    }, {});

config.entry = Object.assign({} , config.entry , newEntries);

function entry(name) {
    return './src/js/' + name + '/index.js';
}

output section:

output: {
    path: path.join(__dirname,"/dist/js/"),
    filename: "[name].js"
},

module section:

 module: {

        // 将非js的资源 或者 非es5 资源 转化为合适的 js 资源 
        loaders: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel',
            query: {
                presets: [
                    'es2015',
                    'stage-0',
                    'react'
                ]
            } 
        }]
    },

    // 第三方库合并
    plugins: [
        new webpack.optimize.CommonsChunkPlugin('vendor' , 'vendor.bundle.js')
    ]
}

I use webpack loading in my React code (home.js)

Problem

I want to load my script however I meet some ReferenceError.

Uncaught ReferenceError: webpackJsonp is not defined

I am loading vendor.bundle.js bundle file right before home.js

<script src="../../dist/js/vendor.bundle.js"></script>
<script src="../../dist/js/home.js"></script>
like image 532
Owen Brown Avatar asked Jun 18 '16 12:06

Owen Brown


2 Answers

Try adding Infinity into your module section:

module: {
    ...

    // 第三方库合并
    plugins: [
        new webpack.optimize.CommonsChunkPlugin('vendor' , 'vendor.bundle.js', Infinity)
    ]
}
like image 70
Jee Mok Avatar answered Oct 10 '22 11:10

Jee Mok


So the error message is essentially saying you forgot that other script tag, remember that bundle.js? Well you need to do the same for vendor.js.

So we now have these separate javascript files, we may need to do some more code splitting, but we have this index.html file where we need to ensure we have a single script file for every script file thats generated. We might even argue that the script tags that you do have in your index.html file are messy or not properly formatted and so on.

I don’t know about you, but the number of scripts might vary and I don’t want to have to change my index.html file manually to accommodate for that and go through all this trouble you are going through right now.

I would hate to have to remember that every time we change our webpack file, we also have to go over to index.html and add in additional script tags as well.

To solve this issue we are going to add in a plugin to your webpack.config.js file called HtmlWebpackPlugin.

The purpose of the plugin is to replace or make obsolete the need to manually maintain the script tags inside this html document.

So our webpack process is going to run, it will spit out some number of scripts and the plugin will automatically generate an html document for us that has the correct script inside of it.

You you install the plugin like so:

npm install —save-dev html-webpack-plugin

In the webpack.config.js file you will require in that module like so:

var HtmlWebpackPlugin = require(‘html-webpack-plugin’);

At the bottom you will add it to your plugins section like so:

plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor'
    }),
    new HtmlWebpackPlugin({

    })
  ]
};

Notice how my CommonsChunkPlugin looks different to yours? Go with my setup.

Now you need to pass some amount of configuration to this thing.

First, pass in a reference to an html template for web pack to use. So npm run build will automatically generate this html for you with some script tags inside it, but when you don’t provide it a template, it will just do the best job it can do without a template because it does not know what setup it has inside your html document, it would not know about any customization you might want to use. To ensure the plugin takes the customization into account you have to tell it the following:

plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor'
    }),
    new HtmlWebpackPlugin({
      template: 'src/index.html'
    })
  ]

So this setup requires that you now move your index.html from your root directory to your src/ folder and the justification for that is because we are now treating it as a template.

  1. Find your script tag and delete the existing script tag. Why? The purpose of this plugin is to say for every javascript document that was generated by webpack, its going to automatically add a script tag into this html document for us, so we don’t have to manually do it ourselves.

So now when you run webpack, the plugin will run. The plugin will take the index.html template and manually add a script tag in there for every javascript file you added and then it will output a new html document into your dist/ directory.

npm run build

Now you should have an index.html document inside your dist/ directory and if you look inside of it, underneath the div tag you will notice that there are two additional script tags that have been injected inside your document.

You will notice you have the script tag references for both vendor.js and bundle.js.

So now as you start to add in more entry points or more code splitting or more anything from Webpack the html plugin will automatically inject it into the html document for you.

Test it out by opening your application in terminal with the command to manually open your dist/ directory and ensure everything works:

open dist/index.html

Your browser should open up, you should be in the dist/ directory, it grabs the html document and voila you have your application working and displaying properly on the screen and if you open up the elements tab, you still have vendor.js and bundle.js in there and you did not have to do a single manual thing to the script tags.

Why do this?

Aside from the hassle of getting the ReferenceError: webpackJsonp is not defined, you are doing it this way because over time you might change the number of script tags or even the names of the script tags that are outputted by webpack.

By using this plugin it will add all the scripts to your index.html document.

So thats another step forward on your application. All the best.

like image 22
Daniel Avatar answered Oct 10 '22 12:10

Daniel