-
Star
(183)
You must be signed in to star a gist -
Fork
(20)
You must be signed in to fork a gist
-
-
Save Couto/b29676dd1ab8714a818f to your computer and use it in GitHub Desktop.
var webpack = require('webpack'); | |
var HtmlWebpackPlugin = require('html-webpack-plugin'); | |
var path = require('path'); | |
var folders = { | |
APP: path.resolve(__dirname, '../app'), | |
BUILD: path.resolve(__dirname, '../build'), | |
BOWER: path.resolve(__dirname, '../bower_components'), | |
NPM: path.resolve(__dirname, '../node_modules') | |
}; | |
var config = { | |
entry: { | |
app: [ | |
'webpack/hot/dev-server', | |
"./js/app.js" | |
] | |
}, | |
debug: true, | |
resolve: { | |
extensions: ['', '.js', '.jsx', '.scss'], | |
alias: { | |
//'es6-promise': path.join(folders.NPM, 'es6-promise', 'es6-promise.js'), | |
//'fetch': path.join(folders.NPM, 'whatwg-fetch', 'fetch.js'), | |
} | |
}, | |
stats: { | |
colors: true, | |
reasons: true, | |
}, | |
output: { | |
path: __dirname + '/build', | |
publicPath: '/', | |
filename: '[name].[hash].js', | |
chunkFilename: '[id].[hash].js' | |
}, | |
module: { | |
loaders: [ | |
{ | |
test: /\.s?css$/, | |
exclude: /node_modules/, | |
loaders: [ | |
'style', | |
'css', | |
'autoprefixer?browsers=last 2 version', | |
'sass?' + ['outputStyle=nested'].join('&') | |
] | |
}, | |
{ test: /\.jsx?$/, loaders: ['react-hot', 'babel'], exclude: /node_modules/ }, | |
{ test: /\.json$/, loader: 'json' }, | |
] | |
}, | |
plugins: [ | |
new webpack.HotModuleReplacementPlugin(), | |
new webpack.ProvidePlugin({ | |
'Promise': 'es6-promise', // Thanks Aaron (https://gist.github.com/Couto/b29676dd1ab8714a818f#gistcomment-1584602) | |
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch' | |
}), | |
//new webpack.optimize.CommonsChunkPlugin('app', null, false), | |
new webpack.NoErrorsPlugin(), | |
new HtmlWebpackPlugin({ | |
template: path.resolve('./', 'index.html'), | |
webpackDevServer: '/webpack-dev-server.js' | |
}) | |
] | |
}; | |
module.exports = config; |
@Nosherwan @Couto @Andersos I was having the same issues with Promise
and ended up simplifying it to the following:
new webpack.ProvidePlugin({
'Promise': 'exports?global.Promise!es6-promise',
'fetch': 'exports?self.fetch!whatwg-fetch'
})
This works in Chrome, Safari, and IE. The polyfills for both fetch
and Promise
are only used when needed.
I case anyone runs into this in the future.. if you are calling window.fetch inside your code. Use 'window.fetch' your config.
new webpack.ProvidePlugin({
'Promise': 'exports?global.Promise!es6-promise',
'window.fetch': 'exports?self.fetch!whatwg-fetch'
})
Why do we need to add this as a plugin to webpack? Can't we just do import ('fetch')
in our code to get the benefits?
In my testing this increased the bundle filesize by about 3kb compared to just importing the polyfills in my entrypoint. No clue why, perhaps it's skipped over by Webpack's de-duping?
Unfortunately this means even new browsers will use the Promise polyfill 😢
My mistake, that's intended: stefanpenner/es6-promise#148
@finbarmaginn I was wondering the same thing, but I think you have the benefit of deciding when to polyfill based on the environment. E.g. you probably don't want to polyfill promises when testing in Node.js because newer versions support them.
Is this still the preferred method to polyfill Promise
and does it cause any errors? re: https://github.com/babel/babel-loader#custom-polyfills-eg-promise-library
I am curious just today I have learned that at least in babel 6 there is a 'babel-polyfill' (provides es6 env) that can be imported via the entry option in webpack.config.js like so:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: [
'babel-polyfill',
'./src/main'
],
output: {
publicPath: '/',
filename: 'main.js'
},
devtool: 'source-map',
module: {
loaders: [
{
test: /\.js$/,
include: path.join(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ["es2015","react"],
}
}
]
},
debug: true
};
Would this not make es6-promise polyfill redundant, and maybe it is smart enough to use browser implementation if provided?
Was wondering the same thing…
babel-polyfill
does not appear to include a fetch polyfill, so you'd still need to use this.
Wouldn't simply including it in entry be a better approach? There is actually a use case where the demonstrated method will fail, for example if you use Webpack server side with externals: [nodeExternals()]
, you would be forced to use entry anyways because external modules would not see fetch
as being defined. So it seems it would be more consistent to use entry here as well.
After double checking, this approach is actually incorrect and will not polyfill fetch properly, the correct approach is to configure whatwg-fetch
on your Webpack entry
configuration, like such:
module.exports = {
entry: ['whatwg-fetch', './app/js']
};
This will fix issues where using a 3rd party that expect fetch
will not find it with the approach of this gist. This is also consistent with the way babel documents using a polyfill with Webpack and does not require the extra loaders.
I have opened a PR with fetch
so they stop referring to this solution: JakeChampion/fetch#331
@Nosherwan @silvenon you should not include a Promise polyfill if you use babel-polyfill
, the correct configuration would then be:
module.exports = {
entry: ['babel-polyfill', 'whatwg-fetch', './app/js']
};
Has anyone had success adding this when entry
is an object?
@simonsmith Does this not work for you?
entry: {
demo: ['whatwg-fetch', './app']
},
@tarikjn
Works for me too, thanks!
@Couto ganda truta! 👍
🐟
@tarikjn i am getting a Exception thrown and not caught in IE11 when i use babel-polyfill instead of es6 promise .
entry: ['babel-polyfill', 'whatwg-fetch','./src/main.js'],
but this works perfect in IE11
entry: ['es6-promise', 'whatwg-fetch','./src/main.js']
Is there a way to have the polyfills loaded from a seperated chunk?
I wish that when a browser is lacking a feature it loads the predeclared polyfill (which would be put in a chunk by webpack). So that the final bundle size does not contain all the polyfills.
Is this possible somehow?
@vikas5914, I'm getting the exact same. Did you solve this in the end, as I would rather keep using babel-polyfill
Adding polyfills through entry
- defines them in global scope. If you own an application (SPA for example), I think It's Ok, but if you are working on the library, I don't recommend this approach.
if you use webpack 2
you need to change import -> import-loader
and export -> export-loader
new webpack.ProvidePlugin({
fetch: 'imports-loader?this=>global!exports-loader?global.fetch!whatwg-fetch'
})
Can we use webpack.ProvidePlugin
to conditionally load polyfills? Essentially load polyfills if browser don't support natively.
+1
🥇
good job!
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const folders = {
APP: path.resolve(__dirname, '../app'),
BUILD: path.resolve(__dirname, '../build'),
BOWER: path.resolve(__dirname, '../bower_components'),
NPM: path.resolve(__dirname, '../node_modules')
};
const config = {
entry: {
app: [
'webpack/hot/dev-server',
"./js/app.js"
]
},
debug: true,
resolve: {
extensions: ['', '.js', '.jsx', '.scss'],
alias: {
//'es6-promise': path.join(folders.NPM, 'es6-promise', 'es6-promise.js'),
//'fetch': path.join(folders.NPM, 'whatwg-fetch', 'fetch.js'),
}
},
stats: {
colors: true,
reasons: true,
},
output: {
path: __dirname + '/build',
publicPath: '/',
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].js'
},
module: {
loaders: [
{
test: /\.s?css$/,
exclude: /node_modules/,
loaders: [
'style',
'css',
'autoprefixer?browsers=last 2 version',
'sass?' + ['outputStyle=nested'].join('&')
]
},
{ test: /\.jsx?$/, loaders: ['react-hot', 'babel'], exclude: /node_modules/ },
{ test: /\.json$/, loader: 'json' },
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.ProvidePlugin({
'Promise': 'es6-promise', // Thanks Aaron (https://gist.github.com/Couto/b29676dd1ab8714a818f#gistcomment-1584602)
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
}),
//new webpack.optimize.CommonsChunkPlugin('app', null, false),
new webpack.NoErrorsPlugin(),
new HtmlWebpackPlugin({
template: path.resolve('./', 'index.html'),
webpackDevServer: '/webpack-dev-server.js'
})
]
};
module.exports = config;
In case someone has this error on firebase
https://stackoverflow.com/questions/44908044/babel-not-polyfilling-fetch-when-using-babel-preset-env/64791611#64791611
I fixed it like this
@Andersos I've had some success on IE9 by using the following snippet:
So far this works because
es6-promise
calls the polyfill() automatically, right after the UMD snippet.Also:
I haven't tested but, I'm pretty sure you can import the es6-promise and call the polyfill() function, something like:
right at the top of your app's entry point.