-
-
Notifications
You must be signed in to change notification settings - Fork 199
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use mini-css-extract-plugin@^0.6.0 and embed webpack-manifest-plugin …
…into Encore
- Loading branch information
Showing
8 changed files
with
315 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
lib/webpack/webpack-manifest-plugin.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,257 @@ | ||
/* | ||
* This file is part of the Symfony Webpack Encore package. | ||
* This code is based on the "lib/plugin.js" file provided by the | ||
* [email protected] (https://github.com/danethurber/webpack-manifest-plugin) | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* It adds the changes made by @karlvr in pull request #176 that | ||
* allow the plugin to work with mini-css-extract-plugin > 0.4.2 | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
* The library is licensed as MIT. | ||
*/ | ||
|
||
'use strict'; | ||
var path = require('path'); | ||
var fse = require('fs-extra'); | ||
var _ = require('lodash'); | ||
|
||
const logger = require('../logger'); | ||
logger.deprecation('The lib/webpack/webpack-manifest-plugin.js module is deprecated: require the library directly now: require(\'webpack-manifest-plugin\').'); | ||
const emitCountMap = new Map(); | ||
|
||
module.exports = require('webpack-manifest-plugin'); | ||
function ManifestPlugin(opts) { | ||
this.opts = _.assign({ | ||
publicPath: null, | ||
basePath: '', | ||
fileName: 'manifest.json', | ||
transformExtensions: /^(gz|map)$/i, | ||
writeToFileEmit: false, | ||
seed: null, | ||
filter: null, | ||
map: null, | ||
generate: null, | ||
sort: null, | ||
serialize: function(manifest) { | ||
return JSON.stringify(manifest, null, 2); | ||
}, | ||
}, opts || {}); | ||
} | ||
|
||
ManifestPlugin.prototype.getFileType = function(str) { | ||
str = str.replace(/\?.*/, ''); | ||
var split = str.split('.'); | ||
var ext = split.pop(); | ||
if (this.opts.transformExtensions.test(ext)) { | ||
ext = split.pop() + '.' + ext; | ||
} | ||
return ext; | ||
}; | ||
|
||
ManifestPlugin.prototype.apply = function(compiler) { | ||
var moduleAssets = {}; | ||
|
||
var outputFolder = compiler.options.output.path; | ||
var outputFile = path.resolve(outputFolder, this.opts.fileName); | ||
var outputName = path.relative(outputFolder, outputFile); | ||
|
||
var moduleAsset = function (module, file) { | ||
if (module.userRequest) { | ||
moduleAssets[file] = path.join( | ||
path.dirname(file), | ||
path.basename(module.userRequest) | ||
); | ||
} | ||
}; | ||
|
||
var normalModuleLoader = function (loaderContext, module) { | ||
const { emitFile } = loaderContext; | ||
|
||
loaderContext.emitFile = (file, content, sourceMap) => { | ||
if (module.userRequest && !moduleAssets[file]) { | ||
moduleAssets[file] = path.join( | ||
path.dirname(file), | ||
path.basename(module.userRequest) | ||
); | ||
} | ||
|
||
return emitFile.call(module, file, content, sourceMap); | ||
}; | ||
}; | ||
|
||
var emit = function(compilation, compileCallback) { | ||
const emitCount = emitCountMap.get(outputFile) - 1 | ||
emitCountMap.set(outputFile, emitCount); | ||
|
||
var seed = this.opts.seed || {}; | ||
|
||
var publicPath = this.opts.publicPath != null ? this.opts.publicPath : compilation.options.output.publicPath; | ||
var stats = compilation.getStats().toJson(); | ||
|
||
var files = compilation.chunks.reduce(function(files, chunk) { | ||
return chunk.files.reduce(function (files, path) { | ||
var name = chunk.name ? chunk.name : null; | ||
|
||
if (name) { | ||
name = name + '.' + this.getFileType(path); | ||
} else { | ||
// For nameless chunks, just map the files directly. | ||
name = path; | ||
} | ||
|
||
// Webpack 4: .isOnlyInitial() | ||
// Webpack 3: .isInitial() | ||
// Webpack 1/2: .initial | ||
return files.concat({ | ||
path: path, | ||
chunk: chunk, | ||
name: name, | ||
isInitial: chunk.isOnlyInitial ? chunk.isOnlyInitial() : (chunk.isInitial ? chunk.isInitial() : chunk.initial), | ||
isChunk: true, | ||
isAsset: false, | ||
isModuleAsset: false | ||
}); | ||
}.bind(this), files); | ||
}.bind(this), []); | ||
|
||
// module assets don't show up in assetsByChunkName. | ||
// we're getting them this way; | ||
files = stats.assets.reduce(function (files, asset) { | ||
var name = moduleAssets[asset.name]; | ||
if (name) { | ||
return files.concat({ | ||
path: asset.name, | ||
name: name, | ||
isInitial: false, | ||
isChunk: false, | ||
isAsset: true, | ||
isModuleAsset: true | ||
}); | ||
} | ||
|
||
var isEntryAsset = asset.chunks.length > 0; | ||
if (isEntryAsset) { | ||
return files; | ||
} | ||
|
||
return files.concat({ | ||
path: asset.name, | ||
name: asset.name, | ||
isInitial: false, | ||
isChunk: false, | ||
isAsset: true, | ||
isModuleAsset: false | ||
}); | ||
}, files); | ||
|
||
files = files.filter(function (file) { | ||
// Don't add hot updates to manifest | ||
var isUpdateChunk = file.path.indexOf('hot-update') >= 0; | ||
// Don't add manifest from another instance | ||
var isManifest = emitCountMap.get(path.join(outputFolder, file.name)) !== undefined; | ||
|
||
return !isUpdateChunk && !isManifest; | ||
}); | ||
|
||
// Append optional basepath onto all references. | ||
// This allows output path to be reflected in the manifest. | ||
if (this.opts.basePath) { | ||
files = files.map(function(file) { | ||
file.name = this.opts.basePath + file.name; | ||
return file; | ||
}.bind(this)); | ||
} | ||
|
||
if (publicPath) { | ||
// Similar to basePath but only affects the value (similar to how | ||
// output.publicPath turns require('foo/bar') into '/public/foo/bar', see | ||
// https://github.com/webpack/docs/wiki/configuration#outputpublicpath | ||
files = files.map(function(file) { | ||
file.path = publicPath + file.path; | ||
return file; | ||
}.bind(this)); | ||
} | ||
|
||
files = files.map(file => { | ||
file.name = file.name.replace(/\\/g, '/'); | ||
file.path = file.path.replace(/\\/g, '/'); | ||
return file; | ||
}); | ||
|
||
if (this.opts.filter) { | ||
files = files.filter(this.opts.filter); | ||
} | ||
|
||
if (this.opts.map) { | ||
files = files.map(this.opts.map); | ||
} | ||
|
||
if (this.opts.sort) { | ||
files = files.sort(this.opts.sort); | ||
} | ||
|
||
var manifest; | ||
if (this.opts.generate) { | ||
manifest = this.opts.generate(seed, files); | ||
} else { | ||
manifest = files.reduce(function (manifest, file) { | ||
manifest[file.name] = file.path; | ||
return manifest; | ||
}, seed); | ||
} | ||
|
||
const isLastEmit = emitCount === 0 | ||
if (isLastEmit) { | ||
var output = this.opts.serialize(manifest); | ||
|
||
compilation.assets[outputName] = { | ||
source: function() { | ||
return output; | ||
}, | ||
size: function() { | ||
return output.length; | ||
} | ||
}; | ||
|
||
if (this.opts.writeToFileEmit) { | ||
fse.outputFileSync(outputFile, output); | ||
} | ||
} | ||
|
||
if (compiler.hooks) { | ||
compiler.hooks.webpackManifestPluginAfterEmit.call(manifest); | ||
} else { | ||
compilation.applyPluginsAsync('webpack-manifest-plugin-after-emit', manifest, compileCallback); | ||
} | ||
}.bind(this); | ||
|
||
function beforeRun (compiler, callback) { | ||
let emitCount = emitCountMap.get(outputFile) || 0; | ||
emitCountMap.set(outputFile, emitCount + 1); | ||
|
||
if (callback) { | ||
callback(); | ||
} | ||
} | ||
|
||
if (compiler.hooks) { | ||
const SyncWaterfallHook = require('tapable').SyncWaterfallHook; | ||
const pluginOptions = { | ||
name: 'ManifestPlugin', | ||
stage: Infinity | ||
}; | ||
compiler.hooks.webpackManifestPluginAfterEmit = new SyncWaterfallHook(['manifest']); | ||
|
||
compiler.hooks.compilation.tap(pluginOptions, function (compilation) { | ||
compilation.hooks.normalModuleLoader.tap(pluginOptions, normalModuleLoader); | ||
}); | ||
compiler.hooks.emit.tap(pluginOptions, emit); | ||
|
||
compiler.hooks.run.tap(pluginOptions, beforeRun); | ||
compiler.hooks.watchRun.tap(pluginOptions, beforeRun); | ||
} else { | ||
compiler.plugin('compilation', function (compilation) { | ||
compilation.plugin('module-asset', moduleAsset); | ||
}); | ||
compiler.plugin('emit', emit); | ||
|
||
compiler.plugin('before-run', beforeRun); | ||
compiler.plugin('watch-run', beforeRun); | ||
} | ||
}; | ||
|
||
module.exports = ManifestPlugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.