diff options
Diffstat (limited to 'node_modules/@webpack-contrib/config-loader/lib')
8 files changed, 331 insertions, 0 deletions
diff --git a/node_modules/@webpack-contrib/config-loader/lib/LoadConfigError.js b/node_modules/@webpack-contrib/config-loader/lib/LoadConfigError.js new file mode 100644 index 00000000..5c6e0c45 --- /dev/null +++ b/node_modules/@webpack-contrib/config-loader/lib/LoadConfigError.js @@ -0,0 +1,13 @@ +module.exports = class LoadConfigError extends Error { + constructor(error, configPath) { + super(error.message); + + this.name = 'LoadConfigError'; + + const stack = error.stack.split('\n').slice(1); + stack.unshift(this.toString()); + + this.stack = stack.join('\n'); + this.meta = { configPath }; + } +}; diff --git a/node_modules/@webpack-contrib/config-loader/lib/RequireModuleError.js b/node_modules/@webpack-contrib/config-loader/lib/RequireModuleError.js new file mode 100644 index 00000000..ecaeae33 --- /dev/null +++ b/node_modules/@webpack-contrib/config-loader/lib/RequireModuleError.js @@ -0,0 +1,13 @@ +module.exports = class RequireModuleError extends Error { + constructor(error, moduleName) { + super(error.message); + + this.name = 'RequireModuleError'; + + const stack = error.stack.split('\n').slice(1); + stack.unshift(this.toString()); + + this.stack = stack.join('\n'); + this.meta = { moduleName }; + } +}; diff --git a/node_modules/@webpack-contrib/config-loader/lib/extend.js b/node_modules/@webpack-contrib/config-loader/lib/extend.js new file mode 100644 index 00000000..0854032a --- /dev/null +++ b/node_modules/@webpack-contrib/config-loader/lib/extend.js @@ -0,0 +1,96 @@ +const path = require('path'); + +const isPlainObj = require('is-plain-obj'); +const merge = require('merge-options').bind({ concatArrays: true }); + +const load = require('./load'); +const resolve = require('./resolve'); +const pluginFilters = require('./filters/plugins'); +const ruleFilters = require('./filters/rules'); + +const loadExtends = (extent, options) => { + let result; + /* istanbul ignore else */ + if (path.isAbsolute(extent)) { + result = load({ allowMissing: true, configPath: extent }); + } else { + // eslint-disable-next-line import/no-dynamic-require, global-require + result = { config: require(extent), configPath: extent }; + } + + // eslint-disable-next-line no-use-before-define + return resolve(result).then(({ config }) => mergeExtend(config, options)); +}; + +const filterPlugins = (config, options = {}) => { + const filterName = options.plugins || 'default'; + const filter = pluginFilters[filterName] || pluginFilters.default; + + return filter(config); +}; + +const filterRules = (config, options = {}) => { + const filterName = options.rules || 'default'; + const filter = ruleFilters[filterName] || ruleFilters.default; + + return filter(config); +}; + +const filterModule = (config, options = {}) => { + const { module } = config; + /* istanbul ignore else */ + if (module) { + module.rules = filterRules(config, options); + } + + return module; +}; + +const filter = (config, options = {}) => { + /* eslint-disable no-param-reassign */ + config.module = filterModule(config, options); + config.plugins = filterPlugins(config, options); + + return config; +}; + +const mergeExtend = (config, options = {}) => { + let { extends: configExtends } = config; + + if (configExtends) { + if (isPlainObj(configExtends)) { + // eslint-disable-next-line no-param-reassign + options = configExtends.filters; + configExtends = configExtends.configs; + } + + configExtends = [].concat(configExtends); + + const result = configExtends.reduceRight( + (prev, conf) => + loadExtends(conf, options).then((extent) => + prev.then((prevConfig) => filter(merge(extent, prevConfig), options)) + ), + Promise.resolve(config) + ); + + return result; + } + + return Promise.resolve(config); +}; + +module.exports = { + extend(config, options) { + const promises = [].concat(config).map((conf) => + mergeExtend(conf, options).then((result) => { + delete result.extends; + return result; + }) + ); + + return Promise.all(promises).then( + (results) => (results.length > 1 ? results : results[0]) + ); + }, +}; diff --git a/node_modules/@webpack-contrib/config-loader/lib/filters/plugins.js b/node_modules/@webpack-contrib/config-loader/lib/filters/plugins.js new file mode 100644 index 00000000..925c2068 --- /dev/null +++ b/node_modules/@webpack-contrib/config-loader/lib/filters/plugins.js @@ -0,0 +1,21 @@ +module.exports = { + default: (config) => config.plugins, + + constructor: (config) => { + const { plugins } = config; + /* istanbul ignore if */ + if (!plugins || !plugins.length) { + return plugins; + } + + return plugins.reduceRight( + (array, other) => + array.findIndex( + (plugin) => plugin.constructor.name === other.constructor.name + ) < 0 + ? [...array, other] + : array, + [] + ); + }, +}; diff --git a/node_modules/@webpack-contrib/config-loader/lib/filters/rules.js b/node_modules/@webpack-contrib/config-loader/lib/filters/rules.js new file mode 100644 index 00000000..87a29303 --- /dev/null +++ b/node_modules/@webpack-contrib/config-loader/lib/filters/rules.js @@ -0,0 +1,30 @@ +const regexEqual = (reg, exp) => + reg instanceof RegExp && + exp instanceof RegExp && + reg.source === exp.source && + reg.global === exp.global && + reg.ignoreCase === exp.ignoreCase && + reg.multiline === exp.multiline; + +module.exports = { + default: (config) => { + const { rules } = config.module; + /* istanbul ignore if */ + if (!rules || !rules.length) { + return rules; + } + + return rules.reduce( + (array, other) => + array.findIndex( + (rule) => + rule.test === other.test || regexEqual(rule.test, other.test) + ) < 0 + ? [...array, other] + : array, + [] + ); + }, + + none: (config) => config.module.rules, +}; diff --git a/node_modules/@webpack-contrib/config-loader/lib/index.js b/node_modules/@webpack-contrib/config-loader/lib/index.js new file mode 100644 index 00000000..cafce44c --- /dev/null +++ b/node_modules/@webpack-contrib/config-loader/lib/index.js @@ -0,0 +1,29 @@ +const merge = require('merge-options'); +const webpackLog = require('webpack-log'); +const validate = require('@webpack-contrib/schema-utils'); +const webpackSchema = require('webpack/schemas/WebpackOptions.json'); + +const { extend } = require('./extend'); +const load = require('./load'); +const resolve = require('./resolve'); + +module.exports = (options = {}) => { + webpackLog({ name: 'config', id: 'webpack-config-loader' }); + + const name = 'config-loader'; + const raw = load(options); + const schema = merge({}, options.schema, webpackSchema); + + return resolve(raw).then((result) => { + const { config, configPath } = result; + + return extend(config).then((finalConfig) => { + // finalConfig may be a single Object or it may be an Array[Object] + // for simplicity, concat into an array and treat both types the same. + for (const target of [].concat(finalConfig)) { + validate({ name, schema, target }); + } + return { config: finalConfig, configPath }; + }); + }); +}; diff --git a/node_modules/@webpack-contrib/config-loader/lib/load.js b/node_modules/@webpack-contrib/config-loader/lib/load.js new file mode 100644 index 00000000..62279036 --- /dev/null +++ b/node_modules/@webpack-contrib/config-loader/lib/load.js @@ -0,0 +1,99 @@ +const chalk = require('chalk'); +const cosmiconfig = require('cosmiconfig'); +const resolvePath = require('resolve').sync; +const webpackLog = require('webpack-log'); + +const LoadConfigError = require('./LoadConfigError'); +const RequireModuleError = require('./RequireModuleError'); + +const cwd = process.cwd(); +const { loadJs } = cosmiconfig; +const prefix = 'webpack'; +const cosmicOptions = { + loaders: { + '.es6': loadJs, + '.flow': loadJs, + '.mjs': loadJs, + '.ts': loadJs, + }, + searchPlaces: [ + `${prefix}.config.js`, + `${prefix}.config.es6`, + `${prefix}.config.flow`, + `${prefix}.config.mjs`, + `${prefix}.config.ts`, + `.${prefix}rc`, + 'package.json', + `.${prefix}rc.json`, + `.${prefix}rc.yaml`, + `.${prefix}rc.yml`, + ], +}; + +module.exports = (options = {}) => { + const log = webpackLog({ name: 'config', id: 'webpack-config-loader' }); + const requires = [].concat(options.require).filter((r) => !!r); + + // eslint-disable-next-line no-param-reassign + options = Object.assign({ cwd: process.cwd() }, options); + + for (const module of requires) { + try { + const modulePath = resolvePath(module, { basedir: cwd }); + + log.info(chalk`Requiring the {cyan ${module}} module`); + + if (options.requireOptions) { + const { requireOptions } = options; + // eslint-disable-next-line import/no-dynamic-require, global-require + require(modulePath)(requireOptions); + } else { + // eslint-disable-next-line import/no-dynamic-require, global-require + require(modulePath); + } + } catch (e) { + log.error(chalk`An error occurred while requiring: {grey ${module}}`); + throw new RequireModuleError(e, module); + } + } + + let config = {}; + let { configPath } = options; + + const explorer = cosmiconfig(prefix, cosmicOptions); + + try { + let result; + if (configPath) { + result = explorer.loadSync(configPath) || {}; + } else { + result = explorer.searchSync(options.cwd) || {}; + } + + ({ config, filepath: configPath } = result); + + log.debug(chalk`Found config at {grey ${configPath}}`); + } catch (e) { + /* istanbul ignore else */ + if (configPath) { + log.error(chalk`An error occurred while trying to load {grey ${configPath}} + Did you forget to specify a --require?`); + } else { + log.error(chalk`An error occurred while trying to find a config file + Did you forget to specify a --require?`); + } + throw new LoadConfigError(e, configPath); + } + + if (!configPath && !options.allowMissing) { + // prettier-ignore + log.error(chalk`Unable to load a config from: {grey ${options.cwd}}`); + const e = new Error(`Unable to load a config from: ${options.cwd}`); + throw new LoadConfigError(e, configPath); + } else { + config = config || {}; + configPath = configPath || ''; + } + + return { config, configPath }; +}; diff --git a/node_modules/@webpack-contrib/config-loader/lib/resolve.js b/node_modules/@webpack-contrib/config-loader/lib/resolve.js new file mode 100644 index 00000000..2ed5cf1a --- /dev/null +++ b/node_modules/@webpack-contrib/config-loader/lib/resolve.js @@ -0,0 +1,30 @@ +const minimist = require('minimist'); + +const fromFunction = (config, argv) => { + const result = config(argv); + + return Promise.resolve(result); +}; + +const fromObject = (config) => Promise.resolve(config); + +const handlers = { + function: fromFunction, + object: fromObject, +}; + +module.exports = (configSet, argv) => { + const { config, configPath } = configSet; + const type = typeof (config.default || config); + const handler = handlers[type]; + + // eslint-disable-next-line no-param-reassign + argv = argv || minimist(process.argv.slice(2)); + + return handler(config.default || config, argv).then((configResult) => { + return { + config: configResult, + configPath, + }; + }); +}; |
