From ac17265d942b48217887d091ed1ffd461740427f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=8F=E9=83=B8?= Date: Fri, 20 Apr 2018 02:04:39 +0800 Subject: [PATCH] fix: fixes #290 - MultiCompiler exception with writeToDisk Fix the exception thrown when `writeToDisk` is enabled in multi-compiler mode (#301) * fix writeToDisk option in multi-compiler * rmdir -> rmdirSync * use a better solution of toDisk for multi-compilers * use a shorten method name --- lib/fs.js | 59 ++++++++++--------- .../server-test/webpack.array.config.js | 6 +- test/tests/server.js | 45 ++++++++++++++ 3 files changed, 80 insertions(+), 30 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index 51121c6c0..b98e1961c 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -12,42 +12,45 @@ const { mkdirp } = new NodeOutputFileSystem(); module.exports = { toDisk(context) { - context.compiler.hooks.afterEmit.tap('WebpackDevMiddleware', (compilation) => { - const { assets, compiler } = compilation; - const { log } = context; - const { writeToDisk: filter } = context.options; - let { outputPath } = compiler; + const compilers = context.compiler.compilers || [context.compiler]; + for (const compiler of compilers) { + compiler.hooks.afterEmit.tap('WebpackDevMiddleware', (compilation) => { + const { assets } = compilation; + const { log } = context; + const { writeToDisk: filter } = context.options; + let { outputPath } = compiler; - if (outputPath === '/') { - outputPath = compiler.context; - } + if (outputPath === '/') { + outputPath = compiler.context; + } - for (const assetPath of Object.keys(assets)) { - const asset = assets[assetPath]; - const source = asset.source(); - const isAbsolute = pathabs(assetPath); - const writePath = isAbsolute ? assetPath : path.join(outputPath, assetPath); - const relativePath = path.relative(process.cwd(), writePath); - const allowWrite = filter && typeof filter === 'function' ? filter(writePath) : true; + for (const assetPath of Object.keys(assets)) { + const asset = assets[assetPath]; + const source = asset.source(); + const isAbsolute = pathabs(assetPath); + const writePath = isAbsolute ? assetPath : path.join(outputPath, assetPath); + const relativePath = path.relative(process.cwd(), writePath); + const allowWrite = filter && typeof filter === 'function' ? filter(writePath) : true; - if (allowWrite) { - let output = source; + if (allowWrite) { + let output = source; - mkdirp.sync(path.dirname(writePath)); + mkdirp.sync(path.dirname(writePath)); - if (Array.isArray(source)) { - output = source.join('\n'); - } + if (Array.isArray(source)) { + output = source.join('\n'); + } - try { - fs.writeFileSync(writePath, output, 'utf-8'); - log.debug(chalk`{cyan Asset written to disk}: ${relativePath}`); - } catch (e) { - log.error(`Unable to write asset to disk:\n${e}`); + try { + fs.writeFileSync(writePath, output, 'utf-8'); + log.debug(chalk`{cyan Asset written to disk}: ${relativePath}`); + } catch (e) { + log.error(`Unable to write asset to disk:\n${e}`); + } } } - } - }); + }); + } }, setFs(context, compiler) { diff --git a/test/fixtures/server-test/webpack.array.config.js b/test/fixtures/server-test/webpack.array.config.js index 96060bcc1..e00826f7e 100644 --- a/test/fixtures/server-test/webpack.array.config.js +++ b/test/fixtures/server-test/webpack.array.config.js @@ -1,12 +1,14 @@ 'use strict'; +const path = require('path'); + module.exports = [{ mode: 'development', context: __dirname, entry: './foo.js', output: { filename: 'foo.js', - path: '/js1', + path: path.resolve(__dirname, 'js1'), publicPath: '/js1/' }, module: { @@ -24,7 +26,7 @@ module.exports = [{ entry: './bar.js', output: { filename: 'bar.js', - path: '/js2', + path: path.resolve(__dirname, 'js2'), publicPath: '/js2/' } }]; diff --git a/test/tests/server.js b/test/tests/server.js index 2d34de8ff..af851daf4 100644 --- a/test/tests/server.js +++ b/test/tests/server.js @@ -377,4 +377,49 @@ describe('Server', () => { }); }); }); + + function multiToDisk(value, done) { + app = express(); + const compiler = webpack(webpackMultiConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + writeToDisk: value + }); + app.use(instance); + app.use((req, res) => { + res.sendStatus(200); + }); + listen = listenShorthand(done); + } + + describe('write to disk with MultiCompiler', () => { + before((done) => { + multiToDisk(true, done); + }); + after(close); + + it('should find the bundle files on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundleFiles = [ + '../fixtures/server-test/js1/foo.js', + '../fixtures/server-test/js1/index.html', + '../fixtures/server-test/js1/svg.svg', + '../fixtures/server-test/js2/bar.js' + ]; + + for (const bundleFile of bundleFiles) { + const bundlePath = path.join(__dirname, bundleFile); + assert(fs.existsSync(bundlePath)); + fs.unlinkSync(bundlePath); + } + + fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js1/')); + fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js2/')); + + done(); + }); + }); + }); });