From d009882e6d2dbbefe5c450472e689817dbc753af Mon Sep 17 00:00:00 2001 From: Eli Perelman Date: Thu, 30 Mar 2017 07:19:21 -0500 Subject: [PATCH] Upgrading webpack-chain to v3.1 (#157) --- .../index.js | 25 ++-- packages/neutrino-middleware-eslint/index.js | 91 ++++++------ packages/neutrino-preset-airbnb-base/index.js | 9 +- packages/neutrino-preset-jest/src/index.js | 7 +- packages/neutrino-preset-node/index.js | 131 +++++++++--------- packages/neutrino-preset-react/index.js | 102 +++++++------- packages/neutrino-preset-web/index.js | 124 +++++++++-------- packages/neutrino/package.json | 2 +- packages/neutrino/yarn.lock | 6 +- 9 files changed, 247 insertions(+), 250 deletions(-) diff --git a/packages/neutrino-middleware-compile-loader/index.js b/packages/neutrino-middleware-compile-loader/index.js index 999f0fa..1a646bf 100644 --- a/packages/neutrino-middleware-compile-loader/index.js +++ b/packages/neutrino-middleware-compile-loader/index.js @@ -1,17 +1,8 @@ -module.exports = ({ config }, options) => { - const rule = config.module - .rule('compile') - .test(options.test || /\.jsx?$/) - .use('babel') - .loader(require.resolve('babel-loader')) - .options(options.babel) - .end(); - - if (options.include) { - rule.include.merge(options.include); - } - - if (options.exclude) { - rule.exclude.merge(options.exclude); - } -}; +module.exports = ({ config }, options) => config.module + .rule('compile') + .test(options.test || /\.jsx?$/) + .when(options.include, rule => rule.include.merge(options.include)) + .when(options.exclude, rule => rule.exclude.merge(options.exclude)) + .use('babel') + .loader(require.resolve('babel-loader')) + .options(options.babel); diff --git a/packages/neutrino-middleware-eslint/index.js b/packages/neutrino-middleware-eslint/index.js index 179ac32..83c28d4 100644 --- a/packages/neutrino-middleware-eslint/index.js +++ b/packages/neutrino-middleware-eslint/index.js @@ -2,57 +2,14 @@ const merge = require('deepmerge'); const clone = require('lodash.clonedeep'); const { join } = require('path'); -const IF_NOT_DEV = process.env.NODE_ENV !== 'development'; const MODULES = join(__dirname, 'node_modules'); module.exports = (neutrino, options) => { - const { config } = neutrino; - const lint = config.module.rule('lint'); - - config.resolve.modules.add(MODULES); - config.resolveLoader.modules.add(MODULES); - - lint - .test(options.test || /\.(js|jsx)$/) - .pre() - .use('eslint') - .loader(require.resolve('eslint-loader')) - .options(merge({ - failOnError: IF_NOT_DEV, - emitWarning: IF_NOT_DEV, - emitError: IF_NOT_DEV, - cwd: neutrino.options.root, - useEslintrc: false, - root: true, - plugins: ['babel'], - baseConfig: {}, - envs: ['es6'], - parser: 'babel-eslint', - parserOptions: { - ecmaVersion: 2017, - sourceType: 'module', - ecmaFeatures: { - objectLiteralDuplicateProperties: false, - generators: true, - impliedStrict: true - } - }, - settings: {}, - globals: ['process'], - rules: {} - }, options.eslint || {})); - - if (options.include) { - lint.include.merge(options.include); - } - - if (options.exclude) { - lint.exclude.merge(options.exclude); - } + const isNotDev = process.env.NODE_ENV !== 'development'; // eslint-disable-next-line no-param-reassign neutrino.eslintrc = () => { - const options = clone(config.module.rule('lint').use('eslint').get('options')); + const options = clone(neutrino.config.module.rule('lint').use('eslint').get('options')); options.extends = options.baseConfig.extends; options.useEslintrc = true; @@ -62,4 +19,48 @@ module.exports = (neutrino, options) => { return options; }; + + neutrino.config + .resolve + .modules + .add(MODULES) + .end() + .end() + .resolveLoader + .modules + .add(MODULES) + .end() + .end() + .module + .rule('lint') + .test(options.test || /\.(js|jsx)$/) + .pre() + .when(options.include, rule => rule.include.merge(options.include)) + .when(options.exclude, rule => rule.exclude.merge(options.exclude)) + .use('eslint') + .loader(require.resolve('eslint-loader')) + .options(merge({ + failOnError: isNotDev, + emitWarning: isNotDev, + emitError: isNotDev, + cwd: neutrino.options.root, + useEslintrc: false, + root: true, + plugins: ['babel'], + baseConfig: {}, + envs: ['es6'], + parser: 'babel-eslint', + parserOptions: { + ecmaVersion: 2017, + sourceType: 'module', + ecmaFeatures: { + objectLiteralDuplicateProperties: false, + generators: true, + impliedStrict: true + } + }, + settings: {}, + globals: ['process'], + rules: {} + }, options.eslint || {})); }; diff --git a/packages/neutrino-preset-airbnb-base/index.js b/packages/neutrino-preset-airbnb-base/index.js index f4c5707..3236bf2 100644 --- a/packages/neutrino-preset-airbnb-base/index.js +++ b/packages/neutrino-preset-airbnb-base/index.js @@ -23,10 +23,7 @@ module.exports = (neutrino, options) => { } }, options)); - if (!options.include && !options.exclude) { - neutrino.config.module - .rule('lint') - .include - .add(neutrino.options.source); - } + neutrino.config.module.rule('lint') + .when(!options.include && !options.exclude, + rule => rule.include.add(neutrino.options.source)); }; diff --git a/packages/neutrino-preset-jest/src/index.js b/packages/neutrino-preset-jest/src/index.js index 45f1a72..36d3e69 100644 --- a/packages/neutrino-preset-jest/src/index.js +++ b/packages/neutrino-preset-jest/src/index.js @@ -60,12 +60,11 @@ module.exports = (neutrino) => { } }); - if (neutrino.config.module.rules.has('lint')) { - neutrino.use(loaderMerge('lint', 'eslint'), { + neutrino.config.when(neutrino.config.module.rules.has('lint'), () => neutrino + .use(loaderMerge('lint', 'eslint'), { plugins: ['jest'], envs: ['jest'] - }); - } + })); const options = normalizeJestOptions(jestOptions, neutrino.config, args); const configFile = join(tmpdir(), 'config.json'); diff --git a/packages/neutrino-preset-node/index.js b/packages/neutrino-preset-node/index.js index 3eec2a9..cacef45 100644 --- a/packages/neutrino-preset-node/index.js +++ b/packages/neutrino-preset-node/index.js @@ -13,7 +13,6 @@ const { path } = require('ramda'); const MODULES = join(__dirname, 'node_modules'); module.exports = (neutrino) => { - const { config } = neutrino; let pkg = {}; /* eslint-disable global-require, no-empty */ @@ -46,8 +45,14 @@ module.exports = (neutrino) => { } }); - config.performance.hints(false); - config + const hasSourceMap = (pkg.dependencies && 'source-map-support' in pkg.dependencies) || + (pkg.devDependencies && 'source-map-support' in pkg.devDependencies); + + neutrino.config + .when(hasSourceMap, () => neutrino.use(banner)) + .performance + .hints(false) + .end() .target('node') .node .set('__filename', false) @@ -79,68 +84,60 @@ module.exports = (neutrino) => { .resolveLoader .modules .add(neutrino.options.node_modules) - .add(MODULES); - - const hasSourceMap = (pkg.dependencies && 'source-map-support' in pkg.dependencies) || - (pkg.devDependencies && 'source-map-support' in pkg.devDependencies); - - if (hasSourceMap) { - neutrino.use(banner); - } - - if (process.env.NODE_ENV !== 'development') { - neutrino.use(clean, { paths: [neutrino.options.output] }); - neutrino.use(copy, { - patterns: [{ context: neutrino.options.source, from: '**/*' }], - options: { ignore: ['*.js*'] } - }); - } else { - config.devtool('inline-sourcemap'); - config.entry('index').add('webpack/hot/poll?1000'); - config.output.devtoolModuleFilenameTemplate('[absolute-resource-path]'); - neutrino.use(hot); - neutrino.use(startServer, neutrino.options.entry); - } - - if (config.module.rules.has('lint')) { - neutrino.use(loaderMerge('lint', 'eslint'), { - envs: ['node'], - rules: { - // enforce return after a callback - 'callback-return': 'off', - - // require all requires be top-level - // http://eslint.org/docs/rules/global-require - 'global-require': 'error', - - // enforces error handling in callbacks (node environment) - 'handle-callback-err': 'off', - - // Allow console in Node.js - 'no-console': 'off', - - // disallow mixing regular variable and require declarations - 'no-mixed-requires': ['off', false], - - // disallow use of new operator with the require function - 'no-new-require': 'error', - - // disallow string concatenation with __dirname and __filename - // http://eslint.org/docs/rules/no-path-concat - 'no-path-concat': 'error', - - // disallow use of process.env - 'no-process-env': 'off', - - // disallow process.exit() - 'no-process-exit': 'off', - - // restrict usage of specified node modules - 'no-restricted-modules': 'off', - - // disallow use of synchronous methods (off by default) - 'no-sync': 'off' - } - }); - } + .add(MODULES) + .end() + .end() + .when(process.env.NODE_ENV !== 'development', () => { + neutrino.use(clean, { paths: [neutrino.options.output] }); + neutrino.use(copy, { + patterns: [{ context: neutrino.options.source, from: '**/*' }], + options: { ignore: ['*.js*'] } + }); + }, (config) => { + config.devtool('inline-sourcemap'); + config.entry('index').add('webpack/hot/poll?1000'); + config.output.devtoolModuleFilenameTemplate('[absolute-resource-path]'); + neutrino.use(hot); + neutrino.use(startServer, neutrino.options.entry); + }) + .when(neutrino.config.module.rules.has('lint'), () => neutrino + .use(loaderMerge('lint', 'eslint'), { + envs: ['node'], + rules: { + // enforce return after a callback + 'callback-return': 'off', + + // require all requires be top-level + // http://eslint.org/docs/rules/global-require + 'global-require': 'error', + + // enforces error handling in callbacks (node environment) + 'handle-callback-err': 'off', + + // Allow console in Node.js + 'no-console': 'off', + + // disallow mixing regular variable and require declarations + 'no-mixed-requires': ['off', false], + + // disallow use of new operator with the require function + 'no-new-require': 'error', + + // disallow string concatenation with __dirname and __filename + // http://eslint.org/docs/rules/no-path-concat + 'no-path-concat': 'error', + + // disallow use of process.env + 'no-process-env': 'off', + + // disallow process.exit() + 'no-process-exit': 'off', + + // restrict usage of specified node modules + 'no-restricted-modules': 'off', + + // disallow use of synchronous methods (off by default) + 'no-sync': 'off' + } + })); }; diff --git a/packages/neutrino-preset-react/index.js b/packages/neutrino-preset-react/index.js index 0467283..fafecd8 100644 --- a/packages/neutrino-preset-react/index.js +++ b/packages/neutrino-preset-react/index.js @@ -5,8 +5,6 @@ const { join } = require('path'); const MODULES = join(__dirname, 'node_modules'); module.exports = (neutrino) => { - const { config } = neutrino; - neutrino.use(web); neutrino.use(loaderMerge('compile', 'babel'), { presets: [require.resolve('babel-preset-react')], @@ -18,52 +16,60 @@ module.exports = (neutrino) => { } }); - config.resolve.modules.add(MODULES); - config.resolve.extensions.add('.jsx'); - config.resolve.alias.set('react-native', 'react-native-web'); - config.resolveLoader.modules.add(MODULES); - config.externals({ - 'react/addons': true, - 'react/lib/ExecutionEnvironment': true, - 'react/lib/ReactContext': 'window' - }); - - if (process.env.NODE_ENV === 'development') { - config + neutrino.config + .resolve + .modules + .add(MODULES) + .end() + .extensions + .add('.jsx') + .end() + .alias + .set('react-native', 'react-native-web') + .end() + .end() + .resolveLoader + .modules + .add(MODULES) + .end() + .end() + .externals({ + 'react/addons': true, + 'react/lib/ExecutionEnvironment': true, + 'react/lib/ReactContext': 'window' + }) + .when(process.env.NODE_ENV === 'development', config => config .entry('index') - .prepend(require.resolve('react-hot-loader/patch')); - } - - if (config.module.rules.has('lint')) { - neutrino.use(loaderMerge('lint', 'eslint'), { - plugins: ['react'], - baseConfig: { - extends: ['plugin:react/recommended'] - }, - parserOptions: { - ecmaFeatures: { - experimentalObjectRestSpread: true + .prepend(require.resolve('react-hot-loader/patch'))) + .when(neutrino.config.module.rules.has('lint'), () => neutrino + .use(loaderMerge('lint', 'eslint'), { + plugins: ['react'], + baseConfig: { + extends: ['plugin:react/recommended'] + }, + parserOptions: { + ecmaFeatures: { + experimentalObjectRestSpread: true + } + }, + rules: { + 'react/prop-types': ['off'], + 'jsx-quotes': ['error', 'prefer-double'], + 'class-methods-use-this': ['error', { + exceptMethods: [ + 'render', + 'getInitialState', + 'getDefaultProps', + 'getChildContext', + 'componentWillMount', + 'componentDidMount', + 'componentWillReceiveProps', + 'shouldComponentUpdate', + 'componentWillUpdate', + 'componentDidUpdate', + 'componentWillUnmount' + ] + }] } - }, - rules: { - 'react/prop-types': ['off'], - 'jsx-quotes': ['error', 'prefer-double'], - 'class-methods-use-this': ['error', { - exceptMethods: [ - 'render', - 'getInitialState', - 'getDefaultProps', - 'getChildContext', - 'componentWillMount', - 'componentDidMount', - 'componentWillReceiveProps', - 'shouldComponentUpdate', - 'componentWillUpdate', - 'componentDidUpdate', - 'componentWillUnmount' - ] - }] - } - }); - } + })); }; diff --git a/packages/neutrino-preset-web/index.js b/packages/neutrino-preset-web/index.js index 4b843e8..97cc2d0 100644 --- a/packages/neutrino-preset-web/index.js +++ b/packages/neutrino-preset-web/index.js @@ -42,8 +42,6 @@ function devServer({ config }, options) { } module.exports = (neutrino) => { - const { config } = neutrino; - if (!path(['options', 'compile', 'targets', 'browsers'], neutrino)) { Object.assign(neutrino.options, { compile: { @@ -83,70 +81,78 @@ module.exports = (neutrino) => { } }); - if (process.env.NODE_ENV !== 'test') { - neutrino.use(chunk); - } - - config + neutrino.config + .when(process.env.NODE_ENV !== 'test', () => neutrino.use(chunk)) .target('web') .context(neutrino.options.root) .entry('index') .add(require.resolve('babel-polyfill')) - .add(neutrino.options.entry); - - config.output - .path(neutrino.options.output) - .publicPath('./') - .filename('[name].bundle.js') - .chunkFilename('[id].[chunkhash].js'); - - config.resolve.modules.add('node_modules').add(neutrino.options.node_modules).add(MODULES); - config.resolve.extensions.add('.js').add('.json'); - config.resolveLoader.modules.add(neutrino.options.node_modules).add(MODULES); - - config.node - .set('console', false) - .set('global', true) - .set('process', true) - .set('Buffer', true) - .set('__filename', 'mock') - .set('__dirname', 'mock') - .set('setImmediate', true) - .set('fs', 'empty') - .set('tls', 'empty'); + .add(neutrino.options.entry) + .end() + .output + .path(neutrino.options.output) + .publicPath('./') + .filename('[name].bundle.js') + .chunkFilename('[id].[chunkhash].js') + .end() + .resolve + .modules + .add('node_modules') + .add(neutrino.options.node_modules) + .add(MODULES) + .end() + .extensions + .add('.js') + .add('.json') + .end() + .end() + .resolveLoader + .modules + .add(neutrino.options.node_modules) + .add(MODULES) + .end() + .end() + .node + .set('console', false) + .set('global', true) + .set('process', true) + .set('Buffer', true) + .set('__filename', 'mock') + .set('__dirname', 'mock') + .set('setImmediate', true) + .set('fs', 'empty') + .set('tls', 'empty') + .end() + .when(neutrino.config.module.rules.has('lint'), () => neutrino + .use(loaderMerge('lint', 'eslint'), { + globals: ['Buffer'], + envs: ['browser', 'commonjs'] + })) + .when(process.env.NODE_ENV === 'development', (config) => { + const protocol = process.env.HTTPS ? 'https' : 'http'; + const host = process.env.HOST || pathOr('localhost', ['options', 'config', 'devServer', 'host'], neutrino); + const port = process.env.PORT || pathOr(5000, ['options', 'config', 'devServer', 'port'], neutrino); - if (config.module.rules.has('lint')) { - neutrino.use(loaderMerge('lint', 'eslint'), { - globals: ['Buffer'], - envs: ['browser', 'commonjs'] - }); - } - - if (process.env.NODE_ENV === 'development') { - const protocol = process.env.HTTPS ? 'https' : 'http'; - const host = process.env.HOST || pathOr('localhost', ['options', 'config', 'devServer', 'host'], neutrino); - const port = process.env.PORT || pathOr(5000, ['options', 'config', 'devServer', 'port'], neutrino); + neutrino.use(hot); + neutrino.use(devServer, { + host, + port, + https: pathOr(protocol === 'https', ['options', 'config', 'devServer', 'https'], neutrino), + contentBase: neutrino.options.source + }); - neutrino.use(hot); - neutrino.use(devServer, { - host, - port, - https: pathOr(protocol === 'https', ['options', 'config', 'devServer', 'https'], neutrino), - contentBase: neutrino.options.source - }); - - config - .devtool('source-map') - .entry('index') + config + .devtool('source-map') + .entry('index') .add(`webpack-dev-server/client?${protocol}://${host}:${port}/`) .add('webpack/hot/dev-server'); - } else { - neutrino.use(clean, { paths: [neutrino.options.output] }); - neutrino.use(minify); - neutrino.use(copy, { - patterns: [{ context: neutrino.options.source, from: '**/*' }], - options: { ignore: ['*.js*'] } + }, (config) => { + neutrino.use(clean, { paths: [neutrino.options.output] }); + neutrino.use(minify); + neutrino.use(copy, { + patterns: [{ context: neutrino.options.source, from: '**/*' }], + options: { ignore: ['*.js*'] } + }); + config.output.filename('[name].[chunkhash].bundle.js'); }); - config.output.filename('[name].[chunkhash].bundle.js'); - } }; diff --git a/packages/neutrino/package.json b/packages/neutrino/package.json index 2eb6cff..ec6a855 100644 --- a/packages/neutrino/package.json +++ b/packages/neutrino/package.json @@ -34,7 +34,7 @@ "ramda": "^0.23.0", "ramda-fantasy": "^0.7.0", "webpack": "^2.3.1", - "webpack-chain": "^3.0.0", + "webpack-chain": "^3.1.0", "webpack-dev-server": "^2.4.2", "yargs": "^7.0.2" }, diff --git a/packages/neutrino/yarn.lock b/packages/neutrino/yarn.lock index 9f36ef2..85bab8d 100644 --- a/packages/neutrino/yarn.lock +++ b/packages/neutrino/yarn.lock @@ -2218,9 +2218,9 @@ wbuf@^1.1.0, wbuf@^1.4.0: dependencies: minimalistic-assert "^1.0.0" -webpack-chain@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-3.0.0.tgz#20d0b92e84cb294035e1fa03ce2fb8805cce51b6" +webpack-chain@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-3.1.0.tgz#53e82857624d48794443238db99248e598550e03" dependencies: deepmerge "^1.3.2"