Skip to content

Instantly share code, notes, and snippets.

@couto
Last active November 7, 2024 13:10
Show Gist options
  • Select an option

  • Save couto/b29676dd1ab8714a818f to your computer and use it in GitHub Desktop.

Select an option

Save couto/b29676dd1ab8714a818f to your computer and use it in GitHub Desktop.
Fetch polyfill with webpack
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;
@tarikjn

tarikjn commented May 19, 2016

Copy link
Copy Markdown

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

@tarikjn

tarikjn commented May 19, 2016

Copy link
Copy Markdown

@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']
};

@simonsmith

Copy link
Copy Markdown

Has anyone had success adding this when entry is an object?

@xingwang

Copy link
Copy Markdown

@simonsmith Does this not work for you?

entry: {
    demo: ['whatwg-fetch', './app']
  },

@strobox

strobox commented Jul 19, 2016

Copy link
Copy Markdown

@tarikjn
Works for me too, thanks!

@pmcalmeida

Copy link
Copy Markdown

@couto ganda truta! 👍

@luiscvalmeida

Copy link
Copy Markdown

🐟

@vikas5914

vikas5914 commented Aug 31, 2016

Copy link
Copy Markdown

@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']

@callmemagnus

callmemagnus commented Sep 10, 2016

Copy link
Copy Markdown

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?

@Zjaaspoer

Copy link
Copy Markdown

@vikas5914, I'm getting the exact same. Did you solve this in the end, as I would rather keep using babel-polyfill

@NicolasSiver

Copy link
Copy Markdown

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.

@karlAlnebratt

Copy link
Copy Markdown

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

@samarpanda

Copy link
Copy Markdown

Can we use webpack.ProvidePlugin to conditionally load polyfills? Essentially load polyfills if browser don't support natively.

ghost commented Aug 2, 2017

Copy link
Copy Markdown

+1

@xgqfrms007

xgqfrms007 commented Nov 29, 2017

Copy link
Copy Markdown

🥇

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;

@r9software

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment