diff --git a/src/chunk-manifest-webpack-plugin.js b/src/chunk-manifest-webpack-plugin.js index 22dd198..418c802 100644 --- a/src/chunk-manifest-webpack-plugin.js +++ b/src/chunk-manifest-webpack-plugin.js @@ -1,7 +1,7 @@ /** - * This dependency plugin is a fork of: + * This dependency plugin is a fork of: * chunk-manifest-webpack-plugin (https://github.com/soundcloud/chunk-manifest-webpack-plugin) - * + * * inline-chunk-manifest-html-webpack-plugin already enables inlining webpack's chunk manifest, * and therefor has been extracted. */ @@ -22,15 +22,15 @@ class ChunkManifestPlugin { const manifestVariable = this.manifestVariable; let chunkFilename; - compiler.plugin("this-compilation", compilation => { + compiler.hooks.thisCompilation.tap("ChunkManifestPlugin", compilation => { const mainTemplate = compilation.mainTemplate; - mainTemplate.plugin("require-ensure", function( + mainTemplate.hooks.requireEnsure.tap("ChunkManifestPlugin", ( source, chunk, hash /*, chunkIdVariableName */ - ) { - chunkFilename = this.outputOptions.chunkFilename; + ) => { + chunkFilename = compilation.outputOptions.chunkFilename; if (chunkFilename) { const chunkManifest = [chunk].reduce(function registerChunk( @@ -42,23 +42,28 @@ class ChunkManifestPlugin { if (c.hasRuntime()) { manifest[c.id] = undefined; } else { - const assetFilename = mainTemplate.applyPluginsWaterfall( - "asset-path", - chunkFilename, - { - hash, - chunk: c - } - ); + const assetFilename = mainTemplate.getAssetPath(chunkFilename, { + hash: hash, + chunk: c + }); manifest[c.id] = assetFilename; } - return c.chunks.reduce(registerChunk, manifest); + const cGroups = Array.from(c.groupsIterable); + const cGroupsChildren = cGroups.map(group => group.chunks); + const unsortedChunks = cGroupsChildren.reduce( + (chunksArray, childrens) => chunksArray.concat(childrens), + [] + ); + + const chunks = Array.from(new Set(unsortedChunks)); + + return chunks.reduce(registerChunk, manifest); }, {}); - this.outputOptions.chunkFilename = "__CHUNK_MANIFEST__"; + compilation.outputOptions.chunkFilename = "__CHUNK_MANIFEST__"; compilation.assets[manifestFilename] = new RawSource( JSON.stringify(chunkManifest) @@ -69,25 +74,23 @@ class ChunkManifestPlugin { }); }); - compiler.plugin("compilation", compilation => { + compiler.hooks.compilation.tap("ChunkManifestPlugin", compilation => { const mainTemplate = compilation.mainTemplate; - mainTemplate.plugin("require-ensure", function( - source, - chunk, - hash, - chunkIdVariableName - ) { - if (chunkFilename) { - this.outputOptions.chunkFilename = chunkFilename; - } - - const updatedSource = source.replace( - /"__CHUNK_MANIFEST__"/, - `window["${manifestVariable}"][${chunkIdVariableName}]` - ); + mainTemplate.hooks.requireEnsure.tap( + "ChunkManifestPlugin", + (source, chunk, hash, chunkIdVariableName) => { + if (chunkFilename) { + compilation.outputOptions.chunkFilename = chunkFilename; + } + + const updatedSource = source.replace( + /"__CHUNK_MANIFEST__"/, + `window["${manifestVariable}"][${chunkIdVariableName}]` + ); - return updatedSource; - }); + return updatedSource; + } + ); }); } } diff --git a/src/index.js b/src/index.js index 6a343cd..41a0013 100644 --- a/src/index.js +++ b/src/index.js @@ -51,52 +51,58 @@ class InlineChunkManifestHtmlWebpackPlugin { const chunkManifestVariable = this.chunkManifestVariable; const dropAsset = this.dropAsset; - compiler.plugin("emit", (compilation, callback) => { - if (dropAsset) { - delete compilation.assets[manifestFilename]; - } + compiler.hooks.emit.tapAsync( + "InlineChunkManifestHtmlWebpackPlugin", + (compilation, callback) => { + if (dropAsset) { + delete compilation.assets[manifestFilename]; + } - callback(); - }); - - compiler.plugin("compilation", compilation => { - compilation.plugin( - "html-webpack-plugin-alter-asset-tags", - (htmlPluginData, callback) => { - const asset = compilation.assets[manifestFilename]; - - if (asset) { - const newTag = { - tagName: "script", - closeTag: true, - attributes: { - type: "text/javascript" - }, - innerHTML: `window.${manifestVariable}=${asset.source()}` - }; - - htmlPluginData.head.unshift(newTag); + callback(); + } + ); + + compiler.hooks.compilation.tap( + "InlineChunkManifestHtmlWebpackPlugin", + compilation => { + compilation.hooks.htmlWebpackPluginAlterAssetTags.tapAsync( + "InlineChunkManifestHtmlWebpackPlugin", + (htmlPluginData, callback) => { + const asset = compilation.assets[manifestFilename]; + + if (asset) { + const newTag = { + tagName: "script", + closeTag: true, + attributes: { + type: "text/javascript" + }, + innerHTML: `window.${manifestVariable}=${asset.source()}` + }; + + htmlPluginData.head.unshift(newTag); + } + + callback(null, htmlPluginData); } + ); - callback(null, htmlPluginData); - } - ); + compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration.tapAsync( + "InlineChunkManifestHtmlWebpackPlugin", + (htmlPluginData, callback) => { + const asset = compilation.assets[manifestFilename]; - compilation.plugin( - "html-webpack-plugin-before-html-generation", - (htmlPluginData, callback) => { - const asset = compilation.assets[manifestFilename]; + if (asset) { + htmlPluginData.assets[ + chunkManifestVariable + ] = ``; + } - if (asset) { - htmlPluginData.assets[ - chunkManifestVariable - ] = ``; + callback(null, htmlPluginData); } - - callback(null, htmlPluginData); - } - ); - }); + ); + } + ); } applyDependencyPlugins(compiler) { diff --git a/test/plugin-apply-test.js b/test/plugin-apply-test.js index 77d1e5e..59ac315 100644 --- a/test/plugin-apply-test.js +++ b/test/plugin-apply-test.js @@ -12,7 +12,16 @@ test("plugin and dependency plugins has apply", t => { test.cb("dependency plugins are applied", t => { t.plan(2); - const fakeCompiler = { plugin: () => {} }; + const fakeCompiler = { + hooks: { + emit: { + tapAsync: (name, handler) => {} + }, + compilation: { + tap: (name, handler) => {} + } + } + }; const dependencyPlugin = { apply: compiler => { @@ -35,7 +44,16 @@ test.cb("dependency plugins are applied", t => { test.cb("overridden manifest plugins applied", t => { t.plan(2); - const fakeCompiler = { plugin: () => {} }; + const fakeCompiler = { + hooks: { + emit: { + tapAsync: (name, handler) => {} + }, + compilation: { + tap: (name, handler) => {} + } + } + }; const dependencyPlugin = { apply: compiler => { diff --git a/test/plugin-create-asset-test.js b/test/plugin-create-asset-test.js index f368fcf..7763e5a 100644 --- a/test/plugin-create-asset-test.js +++ b/test/plugin-create-asset-test.js @@ -7,42 +7,54 @@ test.cb("create asset", t => { const manifestVariable = "manifest-variable"; const chunkManifestVariable = "chunk-manifest-variable"; - const compilationPluginEvent = (compilationEvent, alterAssets) => { - if (compilationEvent === "html-webpack-plugin-before-html-generation") { - const htmlPluginData = { - assets: {} - }; - - alterAssets(htmlPluginData, (_, result) => { - const asset = htmlPluginData.assets[chunkManifestVariable]; - - t.is( - asset, - `` - ); - - t.end(); - }); - } + const compilationPluginEvent = (name, alterAssets) => { + const htmlPluginData = { + assets: {} + }; + + alterAssets(htmlPluginData, (_, result) => { + const asset = htmlPluginData.assets[chunkManifestVariable]; + + t.is( + asset, + `` + ); + + t.end(); + }); }; - const pluginEvent = (event, compile) => { - if (event === "compilation") { - const assets = {}; - assets[manifestFilename] = { - source: () => manifestFileContent - }; + const pluginEvent = (name, compile) => { + const assets = {}; + assets[manifestFilename] = { + source: () => manifestFileContent + }; - const compilation = { - plugin: compilationPluginEvent, - assets: assets - }; + const compilation = { + hooks: { + htmlWebpackPluginAlterAssetTags: { + tapAsync: () => {} + }, + htmlWebpackPluginBeforeHtmlGeneration: { + tapAsync: compilationPluginEvent + } + }, + assets: assets + }; - compile(compilation); - } + compile(compilation); }; - const fakeCompiler = { plugin: pluginEvent }; + const fakeCompiler = { + hooks: { + emit: { + tapAsync: (name, handler) => {} + }, + compilation: { + tap: pluginEvent + } + } + }; const plugin = new InlineChunkManifestHtmlWebpackPlugin({ filename: manifestFilename, diff --git a/test/plugin-drop-asset-test.js b/test/plugin-drop-asset-test.js index 6231947..bb2c69d 100644 --- a/test/plugin-drop-asset-test.js +++ b/test/plugin-drop-asset-test.js @@ -27,17 +27,22 @@ function isDropped(dropAsset, callback) { source: () => manifestFileContent }; - const pluginEvent = (event, emit) => { - if (event === "emit") { - emit(compilation, () => { - const asset = compilation.assets[manifestFilename]; - callback(asset); - }); + const fakeCompiler = { + hooks: { + emit: { + tapAsync: (name, handler) => { + handler(compilation, () => { + const asset = compilation.assets[manifestFilename]; + callback(asset); + }); + } + }, + compilation: { + tap: (name, handler) => {} + } } }; - const fakeCompiler = { plugin: pluginEvent }; - const plugin = new InlineChunkManifestHtmlWebpackPlugin({ filename: manifestFilename, manifestVariable: manifestVariable, diff --git a/test/plugin-generate-chunk-manifest-asset-test.js b/test/plugin-generate-chunk-manifest-asset-test.js index dbcc2c5..1555efc 100644 --- a/test/plugin-generate-chunk-manifest-asset-test.js +++ b/test/plugin-generate-chunk-manifest-asset-test.js @@ -12,14 +12,18 @@ test.cb("generate asset for chunk manifest", t => { const chunk = { id: 1, hasRuntime: () => true, - chunks: [ + groupsIterable: [ { - id: 2, - hasRuntime: () => false, - chunks: [] - }, - { - id: 2 + chunks: [ + { + id: 2, + hasRuntime: () => false, + groupsIterable: [] + }, + { + id: 2 + } + ] } ] }; @@ -31,47 +35,49 @@ test.cb("generate asset for chunk manifest", t => { }) ); - const compilationPluginEvent = (compilationEvent, ensure) => { - if (compilationEvent === "require-ensure") { - ensure.apply( - { - outputOptions: { - chunkFilename: filenamePlaceholder - } - }, - [undefined, chunk, "a1234"] - ); - } + const compilationPluginEvent = (name, ensure) => { + ensure(undefined, chunk, "a1234"); }; - const applyPluginsWaterfall = (event, filename, data) => { - if (event === "asset-path") - return filename.replace( - filenamePlaceholder, - `${data.chunk.id}-${data.hash}.js` - ); - - t.fail(); + const getAssetPath = (filename, data) => { + return filename.replace( + filenamePlaceholder, + `${data.chunk.id}-${data.hash}.js` + ); }; - const pluginEvent = (event, compile) => { - if (event === "this-compilation") { - const compilation = { - mainTemplate: { - plugin: compilationPluginEvent, - applyPluginsWaterfall + const pluginEvent = (name, compile) => { + const compilation = { + mainTemplate: { + hooks: { + requireEnsure: { + tap: compilationPluginEvent + } }, - assets: {} - }; + getAssetPath + }, + assets: {}, + outputOptions: { + chunkFilename: filenamePlaceholder + } + }; - compile(compilation); + compile(compilation); - t.deepEqual(compilation.assets, expected); - t.end(); - } + t.deepEqual(compilation.assets, expected); + t.end(); }; - const fakeCompiler = { plugin: pluginEvent }; + const fakeCompiler = { + hooks: { + thisCompilation: { + tap: pluginEvent + }, + compilation: { + tap: () => {} + } + } + }; const plugin = new ChunkManifestPlugin({ filename: manifestFilename diff --git a/test/plugin-inject-manifest-test.js b/test/plugin-inject-manifest-test.js index 1376ac0..4956fdc 100644 --- a/test/plugin-inject-manifest-test.js +++ b/test/plugin-inject-manifest-test.js @@ -6,44 +6,56 @@ test.cb("inject manifest in head", t => { const manifestFileContent = "source-content"; const manifestVariable = "manifest-variable"; - const compilationPluginEvent = (compilationEvent, alterAssets) => { - if (compilationEvent === "html-webpack-plugin-alter-asset-tags") { - const htmlPluginData = { - head: [] - }; - - alterAssets(htmlPluginData, (_, result) => { - t.is(result.head.length, 1); - const asset = result.head[0]; - t.is(asset.tagName, "script"); - t.is(asset.closeTag, true); - t.is(asset.attributes.type, "text/javascript"); - t.is( - asset.innerHTML, - `window.${manifestVariable}=${manifestFileContent}` - ); - t.end(); - }); - } + const compilationPluginEvent = (name, alterAssets) => { + const htmlPluginData = { + head: [] + }; + + alterAssets(htmlPluginData, (_, result) => { + t.is(result.head.length, 1); + const asset = result.head[0]; + t.is(asset.tagName, "script"); + t.is(asset.closeTag, true); + t.is(asset.attributes.type, "text/javascript"); + t.is( + asset.innerHTML, + `window.${manifestVariable}=${manifestFileContent}` + ); + t.end(); + }); }; - const pluginEvent = (event, compile) => { - if (event === "compilation") { - const assets = {}; - assets[manifestFilename] = { - source: () => manifestFileContent - }; + const pluginEvent = (name, compile) => { + const assets = {}; + assets[manifestFilename] = { + source: () => manifestFileContent + }; - const compilation = { - plugin: compilationPluginEvent, - assets: assets - }; + const compilation = { + hooks: { + htmlWebpackPluginAlterAssetTags: { + tapAsync: compilationPluginEvent + }, + htmlWebpackPluginBeforeHtmlGeneration: { + tapAsync: () => {} + } + }, + assets: assets + }; - compile(compilation); - } + compile(compilation); }; - const fakeCompiler = { plugin: pluginEvent }; + const fakeCompiler = { + hooks: { + emit: { + tapAsync: () => {} + }, + compilation: { + tap: pluginEvent + } + } + }; const plugin = new InlineChunkManifestHtmlWebpackPlugin({ filename: manifestFilename, diff --git a/test/plugin-reset-chunk-filename-test.js b/test/plugin-reset-chunk-filename-test.js index 7b7a47f..6b4a8d4 100644 --- a/test/plugin-reset-chunk-filename-test.js +++ b/test/plugin-reset-chunk-filename-test.js @@ -8,50 +8,69 @@ test.cb("generate asset for chunk manifest", t => { const chunk = { id: 1, hasRuntime: () => true, - chunks: [] + chunks: [], + groupsIterable: [] }; - const thisCompilationPluginEvent = (compilationEvent, ensure) => { - if (compilationEvent === "require-ensure") { - const outputOptions = { chunkFilename }; - - ensure.apply({ outputOptions }, [undefined, chunk]); + const thisCompilationPluginEvent = (name, ensure) => { + ensure(undefined, chunk); + }; - t.is(outputOptions.chunkFilename, "__CHUNK_MANIFEST__"); - } + const compilationPluginEvent = (name, ensure) => { + ensure("", chunk); }; - const compilationPluginEvent = (compilationEvent, ensure) => { - if (compilationEvent === "require-ensure") { - const outputOptions = { chunkFilename: "overwrite-this" }; + const pluginThisCompilationEvent = (name, compile) => { + const compilation = { + mainTemplate: { + hooks: { + requireEnsure: { + tap: thisCompilationPluginEvent + } + } + }, + outputOptions: { + chunkFilename + }, + assets: {} + }; - ensure.apply({ outputOptions }, ["", chunk]); + compile(compilation); - t.is(outputOptions.chunkFilename, chunkFilename); - t.end(); - } + t.is(compilation.outputOptions.chunkFilename, "__CHUNK_MANIFEST__"); }; - const pluginEvent = (event, compile) => { + const pluginCompilationEvent = (name, compile) => { const compilation = { mainTemplate: { - plugin: undefined + hooks: { + requireEnsure: { + tap: compilationPluginEvent + } + } + }, + outputOptions: { + chunkFilename: "overwrite-this" }, assets: {} }; - if (event === "this-compilation") { - compilation.mainTemplate.plugin = thisCompilationPluginEvent; - compile(compilation); - } + compile(compilation); - if (event === "compilation") { - compilation.mainTemplate.plugin = compilationPluginEvent; - compile(compilation); - } + t.is(compilation.outputOptions.chunkFilename, chunkFilename); + t.end(); }; - const fakeCompiler = { plugin: pluginEvent }; + const fakeCompiler = { + hooks: { + thisCompilation: { + tap: pluginThisCompilationEvent + }, + compilation: { + tap: pluginCompilationEvent + } + } + }; const plugin = new ChunkManifestPlugin(); diff --git a/test/plugin-runtime-replacement-test.js b/test/plugin-runtime-replacement-test.js index ae191ea..c5f16d1 100644 --- a/test/plugin-runtime-replacement-test.js +++ b/test/plugin-runtime-replacement-test.js @@ -17,31 +17,44 @@ test.cb("replace runtime's chunk manifest with lookup", t => { let expected = [...runtimeSource]; expected[1] = `window["${manifestVariable}"][${chunkIdVariableName}]`; - const compilationPluginEvent = (compilationEvent, ensure) => { - if (compilationEvent === "require-ensure") { - const updatedSource = ensure( - runtimeSource.join(""), - undefined, - undefined, - chunkIdVariableName - ); - t.is(updatedSource, expected.join("")); - t.end(); - } + const compilationPluginEvent = (name, ensure) => { + const updatedSource = ensure( + runtimeSource.join(""), + undefined, + undefined, + chunkIdVariableName + ); + t.is(updatedSource, expected.join("")); + t.end(); }; - const pluginEvent = (event, compile) => { - if (event === "compilation") { - const compilation = { - mainTemplate: { - plugin: compilationPluginEvent + const pluginEvent = (name, compile) => { + const compilation = { + outputOptions: { + chunkFilename: "" + }, + mainTemplate: { + hooks: { + requireEnsure: { + tap: compilationPluginEvent + } } - }; - compile(compilation); - } + } + }; + + compile(compilation); }; - const fakeCompiler = { plugin: pluginEvent }; + const fakeCompiler = { + hooks: { + thisCompilation: { + tap: () => {} + }, + compilation: { + tap: pluginEvent + } + } + }; const plugin = new ChunkManifestPlugin({ manifestVariable