Skip to content

Commit 92017f7

Browse files
committed
Use mini-css-extract-plugin@^0.6.0 and embed webpack-manifest-plugin into Encore
1 parent ba08baf commit 92017f7

File tree

8 files changed

+315
-58
lines changed

8 files changed

+315
-58
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lib/webpack/webpack-manifest-plugin.js

lib/plugins/manifest.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
'use strict';
1111

1212
const WebpackConfig = require('../WebpackConfig'); //eslint-disable-line no-unused-vars
13-
const ManifestPlugin = require('webpack-manifest-plugin');
13+
const ManifestPlugin = require('../webpack/webpack-manifest-plugin');
1414
const PluginPriorities = require('./plugin-priorities');
1515
const applyOptionsCallback = require('../utils/apply-options-callback');
1616
const sharedEntryTmpName = require('../utils/sharedEntryTmpName');
Lines changed: 250 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,257 @@
11
/*
2-
* This file is part of the Symfony Webpack Encore package.
2+
* This code is based on the "lib/plugin.js" file provided by the
3+
* [email protected] (https://github.com/danethurber/webpack-manifest-plugin)
34
*
4-
* (c) Fabien Potencier <[email protected]>
5+
* It adds the changes made by @karlvr in pull request #176 that
6+
* allow the plugin to work with mini-css-extract-plugin > 0.4.2
57
*
6-
* For the full copyright and license information, please view the LICENSE
7-
* file that was distributed with this source code.
8+
* The library is licensed as MIT.
89
*/
910

10-
'use strict';
11+
var path = require('path');
12+
var fse = require('fs-extra');
13+
var _ = require('lodash');
1114

12-
const logger = require('../logger');
13-
logger.deprecation('The lib/webpack/webpack-manifest-plugin.js module is deprecated: require the library directly now: require(\'webpack-manifest-plugin\').');
15+
const emitCountMap = new Map();
1416

15-
module.exports = require('webpack-manifest-plugin');
17+
function ManifestPlugin(opts) {
18+
this.opts = _.assign({
19+
publicPath: null,
20+
basePath: '',
21+
fileName: 'manifest.json',
22+
transformExtensions: /^(gz|map)$/i,
23+
writeToFileEmit: false,
24+
seed: null,
25+
filter: null,
26+
map: null,
27+
generate: null,
28+
sort: null,
29+
serialize: function(manifest) {
30+
return JSON.stringify(manifest, null, 2);
31+
},
32+
}, opts || {});
33+
}
34+
35+
ManifestPlugin.prototype.getFileType = function(str) {
36+
str = str.replace(/\?.*/, '');
37+
var split = str.split('.');
38+
var ext = split.pop();
39+
if (this.opts.transformExtensions.test(ext)) {
40+
ext = split.pop() + '.' + ext;
41+
}
42+
return ext;
43+
};
44+
45+
ManifestPlugin.prototype.apply = function(compiler) {
46+
var moduleAssets = {};
47+
48+
var outputFolder = compiler.options.output.path;
49+
var outputFile = path.resolve(outputFolder, this.opts.fileName);
50+
var outputName = path.relative(outputFolder, outputFile);
51+
52+
var moduleAsset = function (module, file) {
53+
if (module.userRequest) {
54+
moduleAssets[file] = path.join(
55+
path.dirname(file),
56+
path.basename(module.userRequest)
57+
);
58+
}
59+
};
60+
61+
var normalModuleLoader = function (loaderContext, module) {
62+
const { emitFile } = loaderContext;
63+
64+
loaderContext.emitFile = (file, content, sourceMap) => {
65+
if (module.userRequest && !moduleAssets[file]) {
66+
moduleAssets[file] = path.join(
67+
path.dirname(file),
68+
path.basename(module.userRequest)
69+
);
70+
}
71+
72+
return emitFile.call(module, file, content, sourceMap);
73+
};
74+
};
75+
76+
var emit = function(compilation, compileCallback) {
77+
const emitCount = emitCountMap.get(outputFile) - 1
78+
emitCountMap.set(outputFile, emitCount);
79+
80+
var seed = this.opts.seed || {};
81+
82+
var publicPath = this.opts.publicPath != null ? this.opts.publicPath : compilation.options.output.publicPath;
83+
var stats = compilation.getStats().toJson();
84+
85+
var files = compilation.chunks.reduce(function(files, chunk) {
86+
return chunk.files.reduce(function (files, path) {
87+
var name = chunk.name ? chunk.name : null;
88+
89+
if (name) {
90+
name = name + '.' + this.getFileType(path);
91+
} else {
92+
// For nameless chunks, just map the files directly.
93+
name = path;
94+
}
95+
96+
// Webpack 4: .isOnlyInitial()
97+
// Webpack 3: .isInitial()
98+
// Webpack 1/2: .initial
99+
return files.concat({
100+
path: path,
101+
chunk: chunk,
102+
name: name,
103+
isInitial: chunk.isOnlyInitial ? chunk.isOnlyInitial() : (chunk.isInitial ? chunk.isInitial() : chunk.initial),
104+
isChunk: true,
105+
isAsset: false,
106+
isModuleAsset: false
107+
});
108+
}.bind(this), files);
109+
}.bind(this), []);
110+
111+
// module assets don't show up in assetsByChunkName.
112+
// we're getting them this way;
113+
files = stats.assets.reduce(function (files, asset) {
114+
var name = moduleAssets[asset.name];
115+
if (name) {
116+
return files.concat({
117+
path: asset.name,
118+
name: name,
119+
isInitial: false,
120+
isChunk: false,
121+
isAsset: true,
122+
isModuleAsset: true
123+
});
124+
}
125+
126+
var isEntryAsset = asset.chunks.length > 0;
127+
if (isEntryAsset) {
128+
return files;
129+
}
130+
131+
return files.concat({
132+
path: asset.name,
133+
name: asset.name,
134+
isInitial: false,
135+
isChunk: false,
136+
isAsset: true,
137+
isModuleAsset: false
138+
});
139+
}, files);
140+
141+
files = files.filter(function (file) {
142+
// Don't add hot updates to manifest
143+
var isUpdateChunk = file.path.indexOf('hot-update') >= 0;
144+
// Don't add manifest from another instance
145+
var isManifest = emitCountMap.get(path.join(outputFolder, file.name)) !== undefined;
146+
147+
return !isUpdateChunk && !isManifest;
148+
});
149+
150+
// Append optional basepath onto all references.
151+
// This allows output path to be reflected in the manifest.
152+
if (this.opts.basePath) {
153+
files = files.map(function(file) {
154+
file.name = this.opts.basePath + file.name;
155+
return file;
156+
}.bind(this));
157+
}
158+
159+
if (publicPath) {
160+
// Similar to basePath but only affects the value (similar to how
161+
// output.publicPath turns require('foo/bar') into '/public/foo/bar', see
162+
// https://github.com/webpack/docs/wiki/configuration#outputpublicpath
163+
files = files.map(function(file) {
164+
file.path = publicPath + file.path;
165+
return file;
166+
}.bind(this));
167+
}
168+
169+
files = files.map(file => {
170+
file.name = file.name.replace(/\\/g, '/');
171+
file.path = file.path.replace(/\\/g, '/');
172+
return file;
173+
});
174+
175+
if (this.opts.filter) {
176+
files = files.filter(this.opts.filter);
177+
}
178+
179+
if (this.opts.map) {
180+
files = files.map(this.opts.map);
181+
}
182+
183+
if (this.opts.sort) {
184+
files = files.sort(this.opts.sort);
185+
}
186+
187+
var manifest;
188+
if (this.opts.generate) {
189+
manifest = this.opts.generate(seed, files);
190+
} else {
191+
manifest = files.reduce(function (manifest, file) {
192+
manifest[file.name] = file.path;
193+
return manifest;
194+
}, seed);
195+
}
196+
197+
const isLastEmit = emitCount === 0
198+
if (isLastEmit) {
199+
var output = this.opts.serialize(manifest);
200+
201+
compilation.assets[outputName] = {
202+
source: function() {
203+
return output;
204+
},
205+
size: function() {
206+
return output.length;
207+
}
208+
};
209+
210+
if (this.opts.writeToFileEmit) {
211+
fse.outputFileSync(outputFile, output);
212+
}
213+
}
214+
215+
if (compiler.hooks) {
216+
compiler.hooks.webpackManifestPluginAfterEmit.call(manifest);
217+
} else {
218+
compilation.applyPluginsAsync('webpack-manifest-plugin-after-emit', manifest, compileCallback);
219+
}
220+
}.bind(this);
221+
222+
function beforeRun (compiler, callback) {
223+
let emitCount = emitCountMap.get(outputFile) || 0;
224+
emitCountMap.set(outputFile, emitCount + 1);
225+
226+
if (callback) {
227+
callback();
228+
}
229+
}
230+
231+
if (compiler.hooks) {
232+
const SyncWaterfallHook = require('tapable').SyncWaterfallHook;
233+
const pluginOptions = {
234+
name: 'ManifestPlugin',
235+
stage: Infinity
236+
};
237+
compiler.hooks.webpackManifestPluginAfterEmit = new SyncWaterfallHook(['manifest']);
238+
239+
compiler.hooks.compilation.tap(pluginOptions, function (compilation) {
240+
compilation.hooks.normalModuleLoader.tap(pluginOptions, normalModuleLoader);
241+
});
242+
compiler.hooks.emit.tap(pluginOptions, emit);
243+
244+
compiler.hooks.run.tap(pluginOptions, beforeRun);
245+
compiler.hooks.watchRun.tap(pluginOptions, beforeRun);
246+
} else {
247+
compiler.plugin('compilation', function (compilation) {
248+
compilation.plugin('module-asset', moduleAsset);
249+
});
250+
compiler.plugin('emit', emit);
251+
252+
compiler.plugin('before-run', beforeRun);
253+
compiler.plugin('watch-run', beforeRun);
254+
}
255+
};
256+
257+
module.exports = ManifestPlugin;

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,20 @@
3939
"fs-extra": "^2.0.0",
4040
"loader-utils": "^1.1.0",
4141
"lodash": ">=3.5 <5",
42-
"mini-css-extract-plugin": ">=0.4.0 <0.4.3",
42+
"mini-css-extract-plugin": "^0.6.0",
4343
"optimize-css-assets-webpack-plugin": "^5.0.1",
4444
"pkg-up": "^1.0.0",
4545
"pretty-error": "^2.1.1",
4646
"resolve-url-loader": "^3.0.1",
4747
"semver": "^5.5.0",
4848
"style-loader": "^0.21.0",
49+
"tapable": "^1.0.0",
4950
"terser-webpack-plugin": "^1.1.0",
5051
"tmp": "^0.0.33",
5152
"webpack": "^4.20.0",
5253
"webpack-chunk-hash": "^0.6.0",
5354
"webpack-cli": "^3.0.0",
5455
"webpack-dev-server": "^3.1.14",
55-
"webpack-manifest-plugin": "^2.0.2",
5656
"webpack-sources": "^1.3.0",
5757
"yargs-parser": "^12.0.0"
5858
},

test/config-generator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const WebpackConfig = require('../lib/WebpackConfig');
1414
const RuntimeConfig = require('../lib/config/RuntimeConfig');
1515
const configGenerator = require('../lib/config-generator');
1616
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
17-
const ManifestPlugin = require('webpack-manifest-plugin');
17+
const ManifestPlugin = require('../lib/webpack/webpack-manifest-plugin');
1818
const CleanWebpackPlugin = require('clean-webpack-plugin');
1919
const webpack = require('webpack');
2020
const path = require('path');

0 commit comments

Comments
 (0)