How to fix your node dependencies’ es6 causing browser errors
If you’re doing anything with modern JavaScript this day and age you’re probably using es6 and using babel to transpile it back to es5, which works with most browsers.
This works fine for the code you write, but what about your dependencies? Usually they themselves provide transpiled code so it’s not something to worry about. However, some of them may not (especially if their primary focus wasn’t to be used on the browser and, well… you may get the errors like the below in older browsers (such as IE11):
SCRIPT1014: Invalid character
SCRIPT5009: 'webpackJsonp' is undefined
Your first instinct may be to leave the industry and go herd baby goats.
However, there is an alternative. Or at least, I found a solution on github after much hair pulling googling:
First of all, you unfortunately need to figure out which module is causing the problem. Thankfully, your browser should show the code where the error occurs. In this case, this module was using es6 template string, which IE11 does not support:
If you’re bundling your dependencies, it’s not immediately obvious where the error is. In this case, I got lucky, and easily found the culprit with a bit of scrolling up; it turned out to be csv-parse (and yep, my evil experiments have me parsing CSV files in the browser…)
Once you find out what the problem is, what you have to do is essentially tell babel to transpile that module as well, since you would normally be excluding all of node_modules.
First of all if you have exclude: /node_modules
in your webpack.config.json
, you have to get rid of that.
Instead, use include: ['src']
(or whatever your source directory is).
Now you have to add the problematic module as well. In this case, this is what my config looks now (replace csv-parse
with the name of the module that is the problem):
{
test: /\.js$/,
include: ['src', require.resolve('csv-parse') ],
use: {
loader: 'babel-loader',
options: {
}
}
},
Also, make sure that you are using babel-polyfill to get es5 polyfills for all the es6 code.
For example, I changed my entry to this:
entry: [ 'babel-polyfill', './src/client/index.ts' ],
That’s it. Once you’ve done those things, after you re-compile, all the errors should go away and you should have plain old es5 code compiled from your es6 dependencies!
Here is the full diff of what I changed for comparison:
diff --git a/.babelrc b/.babelrc
index 76a26b7..244d28b 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,4 +1,3 @@
{
- "presets": [ "es2015" ],
- "plugins": ["transform-runtime"]
+ "presets": [ "es2015" ]
}
diff --git a/webpack.config.js b/webpack.config.js
index 3796b22..3112198 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -6,7 +6,7 @@ const env = process.env.NODE_ENV
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
- entry: [ './src/client/index.ts' ],
+ entry: [ 'babel-polyfill', './src/client/index.ts' ],
output: {
filename: 'dist/public/bundle.js'
},
@@ -21,11 +21,10 @@ module.exports = {
},
{
test: /\.js$/,
- exclude: /(node_modules|bower_components)/,
+ include: ['src', require.resolve('csv-parse') ],
use: {
loader: 'babel-loader',
options: {
- presets: ['[@babel/preset-env](http://twitter.com/babel/preset-env)']
}
}
},
Huge thanks to KagamiChan and johnwebbcole on github who found this issue and published a solution, I am merely reporting in case it helps someone else, and not trying to take credit 🙂