Skip to content

Instantly share code, notes, and snippets.

@Hendrixer
Created August 28, 2016 19:17
Show Gist options
  • Save Hendrixer/46bcf8ddfa3edad2f28e007f9cff6d43 to your computer and use it in GitHub Desktop.
Save Hendrixer/46bcf8ddfa3edad2f28e007f9cff6d43 to your computer and use it in GitHub Desktop.
list and install npm packages before webpack build
const thenify = require('thenify')
const webpack = require('webpack')
const MemoryFS = require('memory-fs')
const validateNpmPackageName = require('validate-npm-package-name')
class InstallMissingModules {
constructor(options) {
this.options = options
}
apply(compiler) {
const runCompilerThenCallback = (...args) => {
const callback = args[args.length - 1]
this._runCompiler(compiler)
.then(() => callback(), callback)
};
compiler.plugin(`run`, runCompilerThenCallback)
compiler.plugin(`watch-run`, runCompilerThenCallback)
}
_runCompiler(compiler) {
const { options } = compiler
const { plugins } = options
return this._findMissingModuleList(Object.assign({}, options, {
plugins: plugins.filter(plugin => plugin.constructor !== InstallMissingModules)
}))
.then(list => this.options.callback(list))
}
_findMissingModuleList(webpackConfig) {
const webpackCompiler = webpack(webpackConfig)
webpackCompiler.outputFileSystem = new MemoryFS()
return new Promise((resolve, reject) => {
webpackCompiler.run((error, stats) => {
const { errors } = stats.toJson()
const list = errors.map(error => {
if (/Module not found: Error: Cannot resolve module '(\S+)' in/.test(error)) {
return RegExp.$1
} else if (/Cannot find module '(\S+)'/.test(error)) {
return RegExp.$1
} else {
return undefined
}
})
.filter(it => !!it)
.map(it => it.split('/')[0])
.filter(it => validateNpmPackageName(it).validForNewPackages)
resolve(list)
})
})
}
}
module.exports = InstallMissingModules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment