diff --git a/lib/config-generator.js b/lib/config-generator.js index 0c1927be..fed64aee 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -48,6 +48,7 @@ const path = require('path'); const stringEscaper = require('./utils/string-escaper'); const crypto = require('crypto'); const logger = require('./logger'); +const os = require('os'); class ConfigGenerator { /** @@ -131,14 +132,19 @@ class ConfigGenerator { * * See shared-entry-concat-plugin.js for more details. */ - const tmpFileObject = tmp.fileSync(); + const staticHashKey = crypto + .createHash('md4') + .update(this.webpackConfig.outputPath) + .digest('hex') + .slice(0, 8); + const tmpFilename = path.join(os.tmpdir(), '_webpack_encore_tmp_module' + staticHashKey + '.js'); const pathToRequire = path.resolve(this.webpackConfig.getContext(), this.webpackConfig.sharedCommonsEntryFile); fs.writeFileSync( - tmpFileObject.name, + tmpFilename, `require('${stringEscaper(pathToRequire)}')` ); - entry[sharedEntryTmpName] = tmpFileObject.name; + entry[sharedEntryTmpName] = tmpFilename; } if (this.webpackConfig.copyFilesConfigs.length > 0) { diff --git a/lib/plugins/shared-entry-concat.js b/lib/plugins/shared-entry-concat.js index c49def11..ce1e9f42 100644 --- a/lib/plugins/shared-entry-concat.js +++ b/lib/plugins/shared-entry-concat.js @@ -24,8 +24,7 @@ module.exports = function(plugins, webpackConfig) { plugins.push({ plugin: new SharedEntryConcatPlugin( - webpackConfig.sharedCommonsEntryName, - webpackConfig.outputPath + webpackConfig.sharedCommonsEntryName ), priority: PluginPriorities.SharedEntryContactPlugin }); diff --git a/lib/webpack/shared-entry-concat-plugin.js b/lib/webpack/shared-entry-concat-plugin.js index fc48fb4a..0f57f7b4 100644 --- a/lib/webpack/shared-entry-concat-plugin.js +++ b/lib/webpack/shared-entry-concat-plugin.js @@ -9,17 +9,15 @@ 'use strict'; -const fs = require('fs'); -const path = require('path'); const sharedEntryTmpName = require('../utils/sharedEntryTmpName'); +const RawSource = require('webpack-sources/lib/RawSource'); -function SharedEntryConcatPlugin(sharedEntryName, buildDir) { +function SharedEntryConcatPlugin(sharedEntryName) { this.sharedEntryName = sharedEntryName; - this.buildDir = buildDir; } -function getChunkFilename(stats, chunkName) { - const chunk = stats.compilation.namedChunks.get(chunkName); +function getChunkFilename(compilation, chunkName) { + const chunk = compilation.namedChunks.get(chunkName); if (!chunk) { throw new Error(`Cannot find chunk ${chunkName}`); @@ -36,12 +34,21 @@ function getChunkFilename(stats, chunkName) { return jsFiles[0]; } -SharedEntryConcatPlugin.prototype.apply = function(compiler) { - const done = (stats) => { - if (stats.hasErrors()) { - return; - } +/** + * @param {Source} asset + * @return {string} + */ +function getAssetSource(asset) { + let content = asset.source(); + if (Buffer.isBuffer(content)) { + content = Buffer.toString('utf-8'); + } + return content; +} + +SharedEntryConcatPlugin.prototype.apply = function(compiler) { + const emit = (compilation) => { /* * This is a hack. See ConfigGenerator.buildEntryConfig() * for other details. @@ -59,28 +66,31 @@ SharedEntryConcatPlugin.prototype.apply = function(compiler) { * executed. This fixes that. */ - const sharedEntryOutputFile = path.join(this.buildDir, getChunkFilename(stats, this.sharedEntryName)); - const tmpEntryBootstrapFile = path.join(this.buildDir, getChunkFilename(stats, sharedEntryTmpName)); + const sharedEntryOutputFile = getChunkFilename(compilation, this.sharedEntryName); + const tmpEntryFile = getChunkFilename(compilation, sharedEntryTmpName); + const assets = compilation.assets; + + const sharedEntryAsset = assets[sharedEntryOutputFile]; + const tmpEntryAsset = assets[tmpEntryFile]; - if (!fs.existsSync(sharedEntryOutputFile)) { + if (typeof sharedEntryAsset === 'undefined') { throw new Error(`Could not find shared entry output file: ${sharedEntryOutputFile}`); } - if (!fs.existsSync(tmpEntryBootstrapFile)) { - throw new Error(`Could not find temporary shared entry bootstrap file: ${tmpEntryBootstrapFile}`); + if (typeof assets[tmpEntryFile] === 'undefined') { + throw new Error(`Could not find temporary shared entry bootstrap file: ${tmpEntryFile}`); } - fs.writeFileSync( - sharedEntryOutputFile, - [fs.readFileSync(sharedEntryOutputFile), fs.readFileSync(tmpEntryBootstrapFile)].join('\n') + assets[sharedEntryOutputFile] = new RawSource( + [getAssetSource(sharedEntryAsset), getAssetSource(tmpEntryAsset)].join('\n') ); - fs.unlinkSync(tmpEntryBootstrapFile); + delete(assets[tmpEntryFile]); }; - compiler.hooks.done.tap( + compiler.hooks.emit.tap( { name: 'SharedEntryConcatPlugin' }, - done + emit ); }; diff --git a/package.json b/package.json index c5c025d4..f5abc338 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "webpack-cli": "^3.0.0", "webpack-dev-server": "^3.1.4", "webpack-manifest-plugin": "^2.0.2", + "webpack-sources": "^1.3.0", "yargs": "^8.0.1" }, "devDependencies": {