Created
November 20, 2018 23:22
-
-
Save dlebedynskyi/7fd345f3d193bb78790c0e122e23012c to your computer and use it in GitHub Desktop.
loadable-component emit file webpack plugin
This file contains hidden or 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
const path = require('path') | |
const fs = require('fs') | |
class LoadablePlugin { | |
constructor({ filename = 'loadable-stats.json', writeToDisk = false } = {}) { | |
this.opts = { filename, writeToDisk } | |
} | |
gather = (hookCompiler, callback) => { | |
const stats = hookCompiler.getStats().toJson({ | |
hash: true, | |
publicPath: true, | |
assets: true, | |
chunks: false, | |
modules: false, | |
source: false, | |
errorDetails: false, | |
timings: false, | |
}) | |
const result = JSON.stringify(stats, null, 2) | |
hookCompiler.assets[this.opts.filename] = { | |
source() { | |
return result | |
}, | |
size() { | |
return result.length | |
}, | |
} | |
if (this.opts.writeToDisk) { | |
this.writeAssetsFile(result) | |
} | |
callback() | |
} | |
/** | |
* Check if request is from Dev Server | |
* aka webpack-dev-server | |
* @method isRequestFromDevServer | |
* @returns {boolean} - True or False | |
*/ | |
isRequestFromDevServer = () => { | |
if (process.argv.some(arg => arg.includes('webpack-dev-server'))) { | |
return true | |
} | |
return ( | |
this.compiler.outputFileSystem && | |
this.compiler.outputFileSystem.constructor.name === 'MemoryFileSystem' | |
) | |
} | |
/** | |
* Get assets manifest output path | |
* @see https://github.com/webdeveric/webpack-assets-manifest/blob/master/src/WebpackAssetsManifest.js | |
* @method getManifestOutputPath | |
* @returns {string} - Output path containing path + filename. | |
*/ | |
getManifestOutputPath = () => { | |
if (path.isAbsolute(this.opts.filename)) { | |
return this.opts.filename | |
} | |
if (this.isRequestFromDevServer() && this.compiler.options.devServer) { | |
let outputPath = | |
this.compiler.options.devServer.outputPath || | |
this.compiler.outputPath || | |
'/' | |
if (outputPath === '/') { | |
// eslint-disable-next-line no-console | |
console.warn( | |
'Please use an absolute path in options.output when using webpack-dev-server.', | |
) | |
outputPath = this.compiler.context || process.cwd() | |
} | |
return path.resolve(outputPath, this.opts.filename) | |
} | |
return path.resolve(this.compiler.outputPath, this.opts.filename) | |
} | |
/** | |
* Write Assets Manifest file | |
* @method writeAssetsFile | |
*/ | |
writeAssetsFile = manifest => { | |
const filePath = this.getManifestOutputPath() | |
const fileDir = path.dirname(filePath) | |
try { | |
if (!fs.existsSync(fileDir)) { | |
fs.mkdirSync(fileDir) | |
} | |
} catch (err) { | |
if (err.code !== 'EEXIST') { | |
throw err | |
} | |
} | |
fs.writeFileSync(filePath, manifest) | |
} | |
apply(compiler) { | |
// Add a custom output.jsonpFunction: __LOADABLE_LOADED_CHUNKS__ | |
compiler.options.output.jsonpFunction = '__LOADABLE_LOADED_CHUNKS__' | |
compiler.hooks.emit.tapAsync('@loadable/webpack-plugin', this.gather) | |
} | |
} | |
module.exports = LoadablePlugin | |
module.exports.default = LoadablePlugin |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment