Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save PatrickJS/ac2affca14de4940f8e8d1e05516172b to your computer and use it in GitHub Desktop.
Save PatrickJS/ac2affca14de4940f8e8d1e05516172b to your computer and use it in GitHub Desktop.
Plugin brainstorm to support async attribute use on script tags with webpack.
function ScriptAsyncAttrSupportPlugin() {}
module.exports = ScriptAsyncAttrSupportPlugin;
ScriptAsyncAttrSupportPlugin.prototype.apply = function(compiler) {
compiler.plugin('this-compilation', function(compilation) {
compilation.mainTemplate.plugin('bootstrap', function(source) {
return this.asString([
source,
'',
'if (window["__webpackJsonp"]) {',
' var chunks = __webpackJsonp.slice();',
' Promise.resolve()',
' .then(function() {',
' chunks.forEach(function(chunkCb) {',
' chunkCb();',
' });',
' });',
'}',
]);
});
});
// Need to connect this plugin after JsonpChunkTemplatePlugin. The order of
// the main template piece doesn't really matter.
compiler.plugin('after-plugins', function() {
compiler.plugin('this-compilation', function(compilation) {
compilation.chunkTemplate.plugin('render', function(source) {
return this.asString([
'if (!window["webpackJsonp"]) {',
' window["webpackJsonp"] = function(args) {',
' args = [].slice.call(arguments);',
' if (!window["__webpackJsonp"]) {',
' window["__webpackJsonp"] = [];',
' }',
' window["__webpackJsonp"].push(function() {',
' webpackJsonp.apply(null, args);',
' });',
' window["webpackJsonp"] = null;',
' };',
'}',
'',
source.source(),
]);
});
});
});
};
const webpack = require('webpack');
const ScriptAsyncAttrSupportPlugin = require('./script-async-attr-support-plugin');
module.exports = {
entry: {
vendor: ['react', 'react-dom'],
main: './index.js',
},
output: {
path: path.join(__dirname, '../dist'),
filename: '[name].chunkhash.bundle.js',
chunkFilename: '[name].chunkhash.bundle.js',
publicPath: '/',
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'initial',
name: 'vendor',
test: 'vendor',
enforce: true
},
}
},
runtimeChunk: true
},
plugins: [
new ScriptAsyncAttrSupportPlugin(),
],
}
var h = require('react').createElement;
var render = require('react-dom').render;
function Root() {
return h('div', null, 'hello world');
}
render(h(Root), document.querySelector('#root'));
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="root"></div>
<script async src="dist/vendor.js"></script>
<script async src="dist/main.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment