'use strict'; const fs = require('fs'); const path = require('path'); const MemoryFileSystem = require('memory-fs'); const { colors } = require('webpack-log'); const NodeOutputFileSystem = require('webpack/lib/node/NodeOutputFileSystem'); const DevMiddlewareError = require('./DevMiddlewareError'); const { mkdirp } = new NodeOutputFileSystem(); module.exports = { toDisk(context) { 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; } for (const assetPath of Object.keys(assets)) { let targetFile = assetPath; const queryStringIdx = targetFile.indexOf('?'); if (queryStringIdx >= 0) { targetFile = targetFile.substr(0, queryStringIdx); } const targetPath = path.isAbsolute(targetFile) ? targetFile : path.join(outputPath, targetFile); const allowWrite = filter && typeof filter === 'function' ? filter(targetPath) : true; if (allowWrite) { const asset = assets[assetPath]; let content = asset.source(); if (!Buffer.isBuffer(content)) { // TODO need remove in next major release if (Array.isArray(content)) { content = content.join('\n'); } content = Buffer.from(content, 'utf8'); } mkdirp.sync(path.dirname(targetPath)); try { fs.writeFileSync(targetPath, content, 'utf-8'); log.debug( colors.cyan( `Asset written to disk: ${path.relative( process.cwd(), targetPath )}` ) ); } catch (e) { log.error(`Unable to write asset to disk:\n${e}`); } } } }); } }, setFs(context, compiler) { if ( typeof compiler.outputPath === 'string' && !path.posix.isAbsolute(compiler.outputPath) && !path.win32.isAbsolute(compiler.outputPath) ) { throw new DevMiddlewareError( '`output.path` needs to be an absolute path or `/`.' ); } let fileSystem; // store our files in memory const isConfiguredFs = context.options.fs; const isMemoryFs = !isConfiguredFs && !compiler.compilers && compiler.outputFileSystem instanceof MemoryFileSystem; if (isConfiguredFs) { // eslint-disable-next-line no-shadow const { fs } = context.options; if (typeof fs.join !== 'function') { // very shallow check throw new Error( 'Invalid options: options.fs.join() method is expected' ); } // eslint-disable-next-line no-param-reassign compiler.outputFileSystem = fs; fileSystem = fs; } else if (isMemoryFs) { fileSystem = compiler.outputFileSystem; } else { fileSystem = new MemoryFileSystem(); // eslint-disable-next-line no-param-reassign compiler.outputFileSystem = fileSystem; } // eslint-disable-next-line no-param-reassign context.fs = fileSystem; }, };