Created
November 8, 2019 00:16
-
-
Save bholloway/9feb2ca4adb8eb4b89b538882908d4e1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { basename } = require('path'); | |
const { ConcatSource } = require('webpack-sources'); | |
const ModuleFilenameHelpers = require('webpack/lib/ModuleFilenameHelpers'); | |
/** | |
* Loosely based on wrapper-webpack-plugin | |
* https://www.npmjs.com/package/wrapper-webpack-plugin | |
* | |
* Chunk deletion based on webpack-remove-empty-js-chunks-plugin | |
* https://www.npmjs.com/package/webpack-remove-empty-js-chunks-plugin | |
*/ | |
class ExtractAndWrapPlugin { | |
constructor(args) { | |
if (typeof args !== 'object') { | |
throw new TypeError('Argument "args" must be an object.'); | |
} | |
this.test = args.test || ''; | |
this.header = args.header || ''; | |
this.footer = args.footer || ''; | |
} | |
apply(compiler) { | |
const { header, footer, test } = this; | |
const wrapChunks = (compilation, chunks) => { | |
const extractChunk = chunkFilenameTest => { | |
const selectedChunks = chunks.filter( | |
({ name }) => | |
chunkFilenameTest && | |
typeof name === 'string' && | |
ModuleFilenameHelpers.matchObject( | |
{ test: chunkFilenameTest }, | |
basename(name), | |
), | |
); | |
if (selectedChunks.length) { | |
const files = selectedChunks.reduce((r, c) => r.concat(c.files), []); | |
const source = compilation.assets[files[0]].source(); | |
// stop this chunk from outputting files | |
files.forEach(f => { | |
// eslint-disable-next-line no-param-reassign | |
delete compilation.assets[f]; | |
}); | |
// eslint-disable-next-line no-underscore-dangle | |
return source; | |
} | |
return null; | |
}; | |
const headerSource = extractChunk(header); | |
const footerSource = extractChunk(footer); | |
if (headerSource || footerSource) { | |
chunks.forEach(chunk => { | |
chunk.files.forEach(fileName => { | |
if (ModuleFilenameHelpers.matchObject({ test }, fileName)) { | |
// eslint-disable-next-line no-param-reassign | |
compilation.assets[fileName] = new ConcatSource( | |
...[ | |
headerSource, | |
compilation.assets[fileName], | |
footerSource, | |
].filter(Boolean), | |
); | |
} | |
}); | |
}); | |
} | |
}; | |
compiler.hooks.compilation.tap('ExtractAndWrapPlugin', compilation => { | |
compilation.hooks.optimizeChunkAssets.tapAsync( | |
'ExtractAndWrapPlugin', | |
(chunks, done) => { | |
// eslint-disable-next-line no-use-before-define | |
wrapChunks(compilation, chunks); | |
done(); | |
}, | |
); | |
}); | |
} | |
} | |
module.exports = ExtractAndWrapPlugin; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment