From 8e973315b07e2edc8e65a3d8c7d13a7bdd6e1fdb Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Tue, 12 Jun 2018 18:20:09 +0200 Subject: [PATCH 1/4] feat: collect assets from modules --- src/index.js | 9 ++++++++- src/loader.js | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 4f584441..488f8960 100644 --- a/src/index.js +++ b/src/index.js @@ -138,7 +138,7 @@ class MiniCssExtractPlugin { compilation.hooks.normalModuleLoader.tap(pluginName, (lc, m) => { const loaderContext = lc; const module = m; - loaderContext[MODULE_TYPE] = (content) => { + loaderContext[MODULE_TYPE] = (content, assets) => { if (!Array.isArray(content) && content != null) { throw new Error( `Exported value was not extracted as an array: ${JSON.stringify( @@ -146,6 +146,13 @@ class MiniCssExtractPlugin { )}` ); } + + module.buildInfo = module.buildInfo || { assets: {} }; + module.buildInfo.assets = { + ...module.buildInfo.assets, + ...assets, + }; + const identifierCountMap = new Map(); for (const line of content) { const count = identifierCountMap.get(line.identifier) || 0; diff --git a/src/loader.js b/src/loader.js index cd8fefbc..70f37503 100644 --- a/src/loader.js +++ b/src/loader.js @@ -76,11 +76,19 @@ export function pitch(request) { ); let source; + let assets = {}; childCompiler.hooks.afterCompile.tap(pluginName, (compilation) => { source = compilation.assets[childFilename] && compilation.assets[childFilename].source(); + // Collect assets from modules + compilation.modules.forEach((module) => { + if (module.buildInfo && module.buildInfo.assets) { + assets = { ...assets, ...module.buildInfo.assets }; + } + }); + // Remove all chunk assets compilation.chunks.forEach((chunk) => { chunk.files.forEach((file) => { @@ -123,7 +131,7 @@ export function pitch(request) { }; }); } - this[MODULE_TYPE](text); + this[MODULE_TYPE](text, assets); } catch (e) { return callback(e); } From 23ea2cbdc2d3a8cf7fdd301c801978aed3b0103e Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Mon, 18 Jun 2018 05:58:02 +0200 Subject: [PATCH 2/4] fix: review changes --- src/index.js | 2 +- src/loader.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index 488f8960..7fe3cf1e 100644 --- a/src/index.js +++ b/src/index.js @@ -147,7 +147,7 @@ class MiniCssExtractPlugin { ); } - module.buildInfo = module.buildInfo || { assets: {} }; + module.buildInfo = module.buildInfo || {}; module.buildInfo.assets = { ...module.buildInfo.assets, ...assets, diff --git a/src/loader.js b/src/loader.js index 70f37503..f8fb19b1 100644 --- a/src/loader.js +++ b/src/loader.js @@ -76,7 +76,7 @@ export function pitch(request) { ); let source; - let assets = {}; + const assets = {}; childCompiler.hooks.afterCompile.tap(pluginName, (compilation) => { source = compilation.assets[childFilename] && @@ -85,7 +85,7 @@ export function pitch(request) { // Collect assets from modules compilation.modules.forEach((module) => { if (module.buildInfo && module.buildInfo.assets) { - assets = { ...assets, ...module.buildInfo.assets }; + Object.assign(assets, module.buildInfo.assets); } }); From 124407a41cd5b65bf2153296e4960bab58e5cc22 Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Wed, 12 Sep 2018 18:25:50 +0200 Subject: [PATCH 3/4] fix: override emitFile in child compilation, pass call directly --- src/index.js | 8 +------- src/loader.js | 11 ++--------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/index.js b/src/index.js index 7fe3cf1e..57d915d6 100644 --- a/src/index.js +++ b/src/index.js @@ -138,7 +138,7 @@ class MiniCssExtractPlugin { compilation.hooks.normalModuleLoader.tap(pluginName, (lc, m) => { const loaderContext = lc; const module = m; - loaderContext[MODULE_TYPE] = (content, assets) => { + loaderContext[MODULE_TYPE] = (content) => { if (!Array.isArray(content) && content != null) { throw new Error( `Exported value was not extracted as an array: ${JSON.stringify( @@ -147,12 +147,6 @@ class MiniCssExtractPlugin { ); } - module.buildInfo = module.buildInfo || {}; - module.buildInfo.assets = { - ...module.buildInfo.assets, - ...assets, - }; - const identifierCountMap = new Map(); for (const line of content) { const count = identifierCountMap.get(line.identifier) || 0; diff --git a/src/loader.js b/src/loader.js index f8fb19b1..9801d590 100644 --- a/src/loader.js +++ b/src/loader.js @@ -59,6 +59,7 @@ export function pitch(request) { compilation.hooks.normalModuleLoader.tap( `${pluginName} loader`, (loaderContext, module) => { + loaderContext.emitFile = this.emitFile; loaderContext[MODULE_TYPE] = false; // eslint-disable-line no-param-reassign if (module.request === request) { // eslint-disable-next-line no-param-reassign @@ -76,19 +77,11 @@ export function pitch(request) { ); let source; - const assets = {}; childCompiler.hooks.afterCompile.tap(pluginName, (compilation) => { source = compilation.assets[childFilename] && compilation.assets[childFilename].source(); - // Collect assets from modules - compilation.modules.forEach((module) => { - if (module.buildInfo && module.buildInfo.assets) { - Object.assign(assets, module.buildInfo.assets); - } - }); - // Remove all chunk assets compilation.chunks.forEach((chunk) => { chunk.files.forEach((file) => { @@ -131,7 +124,7 @@ export function pitch(request) { }; }); } - this[MODULE_TYPE](text, assets); + this[MODULE_TYPE](text); } catch (e) { return callback(e); } From d3bed082eb6ee59380a7023d64ad7f82e1c6d92c Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Wed, 12 Sep 2018 21:46:23 +0200 Subject: [PATCH 4/4] test: wip, preserve asset even if not emitted --- test/TestMemoryFS.test.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/TestMemoryFS.test.js diff --git a/test/TestMemoryFS.test.js b/test/TestMemoryFS.test.js new file mode 100644 index 00000000..f2344d9c --- /dev/null +++ b/test/TestMemoryFS.test.js @@ -0,0 +1,39 @@ +import path from 'path'; + +import MemoryFS from 'memory-fs'; +import webpack from 'webpack'; + +const assetsNames = (json) => json.assets.map((asset) => asset.name); + +describe('TestMemoryFS', () => { + it('should preserve asset even if not emitted', (done) => { + const casesDirectory = path.resolve(__dirname, 'cases'); + const directoryForCase = path.resolve(casesDirectory, 'simple-publicpath'); + const webpackConfig = require(path.resolve( + directoryForCase, + 'webpack.config.js' + )); + const compiler = webpack({ + ...webpackConfig, + mode: 'development', + context: directoryForCase, + }); + compiler.outputFileSystem = new MemoryFS(); + compiler.run((err1, stats1) => { + if (err1) { + done(err1); + return; + } + compiler.run((err2, stats2) => { + if (err2) { + done(err2); + return; + } + expect(assetsNames(stats1.toJson())).toEqual( + assetsNames(stats2.toJson()) + ); + done(); + }); + }); + }); +});