Browse Source

Upgrading to webpack-chain v3, add more tests for full presets

v5.0.0-beta
Eli Perelman 8 years ago
parent
commit
49b9e296ff
  1. 5
      package.json
  2. 14
      packages/neutrino-middleware-banner/index.js
  3. 9
      packages/neutrino-middleware-chunk/index.js
  4. 4
      packages/neutrino-middleware-clean/index.js
  5. 22
      packages/neutrino-middleware-compile-loader/index.js
  6. 3
      packages/neutrino-middleware-compile-loader/package.json
  7. 1602
      packages/neutrino-middleware-compile-loader/yarn.lock
  8. 8
      packages/neutrino-middleware-copy/index.js
  9. 5
      packages/neutrino-middleware-env/index.js
  10. 66
      packages/neutrino-middleware-eslint/index.js
  11. 1
      packages/neutrino-middleware-eslint/package.json
  12. 4
      packages/neutrino-middleware-eslint/yarn.lock
  13. 11
      packages/neutrino-middleware-font-loader/index.js
  14. 2
      packages/neutrino-middleware-hot/index.js
  15. 4
      packages/neutrino-middleware-html-loader/index.js
  16. 30
      packages/neutrino-middleware-html-template/index.js
  17. 3
      packages/neutrino-middleware-html-template/package.json
  18. 1568
      packages/neutrino-middleware-html-template/yarn.lock
  19. 11
      packages/neutrino-middleware-image-loader/index.js
  20. 3
      packages/neutrino-middleware-loader-merge/index.js
  21. 2
      packages/neutrino-middleware-minify/index.js
  22. 2
      packages/neutrino-middleware-named-modules/index.js
  23. 2
      packages/neutrino-middleware-progress/index.js
  24. 3
      packages/neutrino-middleware-progress/package.json
  25. 1687
      packages/neutrino-middleware-progress/yarn.lock
  26. 2
      packages/neutrino-middleware-start-server/index.js
  27. 4
      packages/neutrino-middleware-style-loader/index.js
  28. 45
      packages/neutrino-preset-airbnb-base/index.js
  29. 57
      packages/neutrino-preset-jest/src/index.js
  30. 16
      packages/neutrino-preset-karma/index.js
  31. 2
      packages/neutrino-preset-mocha/src/index.js
  32. 33
      packages/neutrino-preset-node/index.js
  33. 23
      packages/neutrino-preset-node/test/web_test.js
  34. 12
      packages/neutrino-preset-react/index.js
  35. 23
      packages/neutrino-preset-react/test/web_test.js
  36. 30
      packages/neutrino-preset-web/index.js
  37. 23
      packages/neutrino-preset-web/test/web_test.js
  38. 8
      packages/neutrino/bin/neutrino
  39. 3
      packages/neutrino/package.json
  40. 17
      packages/neutrino/src/neutrino.js
  41. 12
      packages/neutrino/test/api_test.js
  42. 6
      packages/neutrino/yarn.lock
  43. 718
      yarn.lock

5
package.json

@ -13,7 +13,7 @@
"deps:add": "oao add", "deps:add": "oao add",
"deps:remove": "oao remove", "deps:remove": "oao remove",
"deps:upgrade": "oao upgrade", "deps:upgrade": "oao upgrade",
"deps:clean": "rm -rf packages/**/node_modules", "deps:clean": "oao clean",
"docs:build": "gitbook build && cp CNAME _book", "docs:build": "gitbook build && cp CNAME _book",
"docs:deploy": "yarn docs:build && gh-pages --dist _book --remote upstream", "docs:deploy": "yarn docs:build && gh-pages --dist _book --remote upstream",
"docs:serve": "gitbook serve", "docs:serve": "gitbook serve",
@ -31,6 +31,7 @@
"gitbook-plugin-github": "^2.0.0", "gitbook-plugin-github": "^2.0.0",
"gitbook-plugin-npmsearchlist": "^1.0.0", "gitbook-plugin-npmsearchlist": "^1.0.0",
"gitbook-plugin-prism": "^2.1.0", "gitbook-plugin-prism": "^2.1.0",
"oao": "^0.7.2" "oao": "^0.7.2",
"webpack": "^2.2.1"
} }
} }

14
packages/neutrino-middleware-banner/index.js

@ -1,8 +1,12 @@
const { BannerPlugin } = require('webpack'); const { BannerPlugin } = require('webpack');
const merge = require('deepmerge'); const merge = require('deepmerge');
module.exports = ({ config }, options) => config.plugin('banner', BannerPlugin, merge({ module.exports = ({ config }, options) => config
banner: `require('source-map-support').install();`, .plugin('banner')
raw: true, .use(BannerPlugin, [
entryOnly: true merge({
}, options)); banner: `require('source-map-support').install();`,
raw: true,
entryOnly: true
}, options)
]);

9
packages/neutrino-middleware-chunk/index.js

@ -1,7 +1,8 @@
const { CommonsChunkPlugin } = require('webpack').optimize; const { CommonsChunkPlugin } = require('webpack').optimize;
const merge = require('deepmerge'); const merge = require('deepmerge');
module.exports = ({ config }, options) => config.plugin('chunk', CommonsChunkPlugin, merge({ module.exports = ({ config }, options) => config
minChunks: Infinity, .plugin('chunk')
names: ['vendor', 'manifest'] .use(CommonsChunkPlugin, [
}, options)); merge({ minChunks: Infinity, names: ['vendor', 'manifest'] }, options)
]);

4
packages/neutrino-middleware-clean/index.js

@ -4,5 +4,7 @@ const merge = require('deepmerge');
module.exports = ({ config }, options) => { module.exports = ({ config }, options) => {
const { paths, root } = merge({ paths: [], root: process.cwd() }, options); const { paths, root } = merge({ paths: [], root: process.cwd() }, options);
config.plugin('clean', CleanPlugin, paths, { root }); config
.plugin('clean')
.use(CleanPlugin, [paths, { root }]);
}; };

22
packages/neutrino-middleware-compile-loader/index.js

@ -1,5 +1,17 @@
module.exports = ({ config }, options) => config.module module.exports = ({ config }, options) => {
.rule('compile') const rule = config.module
.test(/\.jsx?$/) .rule('compile')
.include(...options.include) .test(options.test || /\.jsx?$/)
.loader('babel', require.resolve('babel-loader'), options.babel); .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);
}
};

3
packages/neutrino-middleware-compile-loader/package.json

@ -16,7 +16,8 @@
"bugs": "https://github.com/mozilla-neutrino/neutrino-dev/issues", "bugs": "https://github.com/mozilla-neutrino/neutrino-dev/issues",
"dependencies": { "dependencies": {
"babel-core": "^6.23.1", "babel-core": "^6.23.1",
"babel-loader": "^6.3.2" "babel-loader": "^6.3.2",
"webpack": "^2.2.1"
}, },
"peerDependencies": { "peerDependencies": {
"neutrino": "^5.0.0" "neutrino": "^5.0.0"

1602
packages/neutrino-middleware-compile-loader/yarn.lock

File diff suppressed because it is too large

8
packages/neutrino-middleware-copy/index.js

@ -1,8 +1,10 @@
const CopyPlugin = require('copy-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin');
const merge = require('deepmerge'); const merge = require('deepmerge');
module.exports = ({ config }, options) => { module.exports = ({ config }, opts) => {
const opts = merge({ patterns: [], options: {} }, options); const { patterns, options } = merge({ patterns: [], options: {} }, opts);
config.plugin('copy', CopyPlugin, opts.patterns, opts.options); config
.plugin('copy')
.use(CopyPlugin, [patterns, options]);
}; };

5
packages/neutrino-middleware-env/index.js

@ -1,4 +1,5 @@
const { EnvironmentPlugin } = require('webpack'); const { EnvironmentPlugin } = require('webpack');
module.exports = ({ config }, envs = []) => config.plugin('env', EnvironmentPlugin, module.exports = ({ config }, envs = []) => config
['NODE_ENV', ...(Array.isArray(envs) ? envs : [])]); .plugin('env')
.use(EnvironmentPlugin, ['NODE_ENV', ...(Array.isArray(envs) ? envs : [])]);

66
packages/neutrino-middleware-eslint/index.js

@ -7,41 +7,51 @@ const MODULES = join(__dirname, 'node_modules');
module.exports = (neutrino, options) => { module.exports = (neutrino, options) => {
const { config } = neutrino; const { config } = neutrino;
const lint = config.module.rule('lint');
config.resolve.modules.add(MODULES); config.resolve.modules.add(MODULES);
config.resolveLoader.modules.add(MODULES); config.resolveLoader.modules.add(MODULES);
config.module
.rule('lint') lint
.test(options.test || /\.(js|jsx)$/) .test(options.test || /\.(js|jsx)$/)
.pre() .pre()
.include(options.include) .use('eslint')
.loader('eslint', require.resolve('eslint-loader'), merge({ .loader(require.resolve('eslint-loader'))
failOnError: IF_NOT_DEV, .options(merge({
emitWarning: IF_NOT_DEV, failOnError: IF_NOT_DEV,
emitError: IF_NOT_DEV, emitWarning: IF_NOT_DEV,
cwd: process.cwd(), emitError: IF_NOT_DEV,
useEslintrc: false, cwd: neutrino.options.root,
root: true, useEslintrc: false,
plugins: ['babel'], root: true,
baseConfig: {}, plugins: ['babel'],
envs: ['es6'], baseConfig: {},
parser: 'babel-eslint', envs: ['es6'],
parserOptions: { parser: 'babel-eslint',
ecmaVersion: 2017, parserOptions: {
sourceType: 'module', ecmaVersion: 2017,
ecmaFeatures: { sourceType: 'module',
objectLiteralDuplicateProperties: false, ecmaFeatures: {
generators: true, objectLiteralDuplicateProperties: false,
impliedStrict: true generators: true,
} impliedStrict: true
}, }
settings: {}, },
globals: ['process'], settings: {},
rules: {} globals: ['process'],
}, options.eslint || {})); rules: {}
}, options.eslint || {}));
if (options.include) {
rule.include.merge(options.include);
}
if (options.exclude) {
rule.exclude.merge(options.exclude);
}
neutrino.eslintrc = () => { neutrino.eslintrc = () => {
const options = clone(config.module.rule('lint').loaders.get('eslint').options); const options = clone(config.module.rule('lint').use('eslint').get('options'));
options.extends = options.baseConfig.extends; options.extends = options.baseConfig.extends;
options.useEslintrc = true; options.useEslintrc = true;

1
packages/neutrino-middleware-eslint/package.json

@ -18,6 +18,7 @@
"babel-eslint": "^7.1.1", "babel-eslint": "^7.1.1",
"deepmerge": "^1.3.2", "deepmerge": "^1.3.2",
"eslint": "^3.16.1", "eslint": "^3.16.1",
"eslint-config-airbnb-base": "^11.1.1",
"eslint-loader": "^1.6.3", "eslint-loader": "^1.6.3",
"eslint-plugin-babel": "^4.1.0", "eslint-plugin-babel": "^4.1.0",
"eslint-plugin-import": "^2.2.0", "eslint-plugin-import": "^2.2.0",

4
packages/neutrino-middleware-eslint/yarn.lock

@ -324,6 +324,10 @@ escope@^3.6.0:
esrecurse "^4.1.0" esrecurse "^4.1.0"
estraverse "^4.1.1" estraverse "^4.1.1"
eslint-config-airbnb-base@^11.1.1:
version "11.1.1"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.1.1.tgz#61e9e89e4eb89f474f6913ac817be9fbb59063e0"
eslint-import-resolver-node@^0.2.0: eslint-import-resolver-node@^0.2.0:
version "0.2.3" version "0.2.3"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c"

11
packages/neutrino-middleware-font-loader/index.js

@ -8,15 +8,20 @@ module.exports = ({ config }, options) => {
config.module config.module
.rule('woff') .rule('woff')
.test(/\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/) .test(/\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/)
.loader('url', urlLoader, { limit, mimetype: 'application/font-woff' }); .use('url')
.loader(urlLoader)
.options({ limit, mimetype: 'application/font-woff' });
config.module config.module
.rule('ttf') .rule('ttf')
.test(/\.ttf(\?v=\d+\.\d+\.\d+)?$/) .test(/\.ttf(\?v=\d+\.\d+\.\d+)?$/)
.loader('url', urlLoader, { limit, mimetype: 'application/octet-stream' }); .use('url')
.loader(urlLoader)
.options({ limit, mimetype: 'application/octet-stream' });
config.module config.module
.rule('eot') .rule('eot')
.test(/\.eot(\?v=\d+\.\d+\.\d+)?$/) .test(/\.eot(\?v=\d+\.\d+\.\d+)?$/)
.loader('file', fileLoader); .use('file')
.loader(fileLoader);
}; };

2
packages/neutrino-middleware-hot/index.js

@ -1,3 +1,3 @@
const { HotModuleReplacementPlugin } = require('webpack'); const { HotModuleReplacementPlugin } = require('webpack');
module.exports = ({ config }) => config.plugin('hot', HotModuleReplacementPlugin); module.exports = ({ config }) => config.plugin('hot').use(HotModuleReplacementPlugin);

4
packages/neutrino-middleware-html-loader/index.js

@ -1,4 +1,6 @@
module.exports = ({ config }) => config.module module.exports = ({ config }) => config.module
.rule('html') .rule('html')
.test(/\.html$/) .test(/\.html$/)
.loader('file', require.resolve('file-loader'), { name: '[name].[ext]' }); .use('file')
.loader(require.resolve('file-loader'))
.options({ name: '[name].[ext]' });

30
packages/neutrino-middleware-html-template/index.js

@ -2,16 +2,20 @@ const HtmlPlugin = require('html-webpack-plugin');
const template = require('html-webpack-template'); const template = require('html-webpack-template');
const merge = require('deepmerge'); const merge = require('deepmerge');
module.exports = ({ config }, options) => config.plugin('html', HtmlPlugin, merge({ module.exports = ({ config }, options) => config
template, .plugin('html')
inject: false, .use(HtmlPlugin, [
appMountId: 'root', merge({
xhtml: true, template,
mobile: true, inject: false,
minify: { appMountId: 'root',
useShortDoctype: true, xhtml: true,
keepClosingSlash: true, mobile: true,
collapseWhitespace: true, minify: {
preserveLineBreaks: true, useShortDoctype: true,
} keepClosingSlash: true,
}, options)); collapseWhitespace: true,
preserveLineBreaks: true,
}
}, options)
]);

3
packages/neutrino-middleware-html-template/package.json

@ -17,7 +17,8 @@
"dependencies": { "dependencies": {
"deepmerge": "^1.3.2", "deepmerge": "^1.3.2",
"html-webpack-plugin": "^2.28.0", "html-webpack-plugin": "^2.28.0",
"html-webpack-template": "^6.0.1" "html-webpack-template": "^6.0.1",
"webpack": "^2.2.1"
}, },
"peerDependencies": { "peerDependencies": {
"neutrino": "^5.0.0" "neutrino": "^5.0.0"

1568
packages/neutrino-middleware-html-template/yarn.lock

File diff suppressed because it is too large

11
packages/neutrino-middleware-image-loader/index.js

@ -7,15 +7,20 @@ module.exports = ({ config }, options) => {
config.module config.module
.rule('svg') .rule('svg')
.test(/\.svg(\?v=\d+\.\d+\.\d+)?$/) .test(/\.svg(\?v=\d+\.\d+\.\d+)?$/)
.loader('url', urlLoader, { limit, mimetype: 'application/svg+xml' }); .use('url')
.loader(urlLoader)
.options({ limit, mimetype: 'application/svg+xml' });
config.module config.module
.rule('img') .rule('img')
.test(/\.(png|jpg|jpeg|gif)$/) .test(/\.(png|jpg|jpeg|gif)$/)
.loader('url', urlLoader, { limit }); .use('url')
.loader(urlLoader)
.options({ limit });
config.module config.module
.rule('ico') .rule('ico')
.test(/\.ico(\?v=\d+\.\d+\.\d+)?$/) .test(/\.ico(\?v=\d+\.\d+\.\d+)?$/)
.loader('url', urlLoader); .use('url')
.loader(urlLoader);
}; };

3
packages/neutrino-middleware-loader-merge/index.js

@ -2,4 +2,5 @@ const merge = require('deepmerge');
module.exports = (ruleId, loaderId) => ({ config }, options) => config.module module.exports = (ruleId, loaderId) => ({ config }, options) => config.module
.rule(ruleId) .rule(ruleId)
.loader(loaderId, _opts => merge(_opts, options)); .use(loaderId)
.tap(opts => merge(opts, options));

2
packages/neutrino-middleware-minify/index.js

@ -1,3 +1,3 @@
const BabiliPlugin = require('babili-webpack-plugin'); const BabiliPlugin = require('babili-webpack-plugin');
module.exports = ({ config }) => config.plugin('minify', BabiliPlugin); module.exports = ({ config }) => config.plugin('minify').use(BabiliPlugin);

2
packages/neutrino-middleware-named-modules/index.js

@ -1,3 +1,3 @@
const { NamedModulesPlugin } = require('webpack'); const { NamedModulesPlugin } = require('webpack');
module.exports = ({ config }) => config.plugin('named-modules', NamedModulesPlugin); module.exports = ({ config }) => config.plugin('named-modules').use(NamedModulesPlugin);

2
packages/neutrino-middleware-progress/index.js

@ -1,3 +1,3 @@
const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const ProgressBarPlugin = require('progress-bar-webpack-plugin');
module.exports = ({ config }) => config.plugin('progress', ProgressBarPlugin); module.exports = ({ config }) => config.plugin('progress').use(ProgressBarPlugin);

3
packages/neutrino-middleware-progress/package.json

@ -15,7 +15,8 @@
"homepage": "https://neutrino.js.org", "homepage": "https://neutrino.js.org",
"bugs": "https://github.com/mozilla-neutrino/neutrino-dev/issues", "bugs": "https://github.com/mozilla-neutrino/neutrino-dev/issues",
"dependencies": { "dependencies": {
"progress-bar-webpack-plugin": "^1.9.3" "progress-bar-webpack-plugin": "^1.9.3",
"webpack": "^2.2.1"
}, },
"peerDependencies": { "peerDependencies": {
"neutrino": "^5.0.0" "neutrino": "^5.0.0"

1687
packages/neutrino-middleware-progress/yarn.lock

File diff suppressed because it is too large

2
packages/neutrino-middleware-start-server/index.js

@ -1,3 +1,3 @@
const StartServerPlugin = require('start-server-webpack-plugin'); const StartServerPlugin = require('start-server-webpack-plugin');
module.exports = ({ config }, options) => config.plugin('start-server', StartServerPlugin, options.name); module.exports = ({ config }, options) => config.plugin('start-server').use(StartServerPlugin, [options.name]);

4
packages/neutrino-middleware-style-loader/index.js

@ -1,5 +1,5 @@
module.exports = ({ config }) => config.module module.exports = ({ config }) => config.module
.rule('style') .rule('style')
.test(/\.css$/) .test(/\.css$/)
.loader('style', require.resolve('style-loader')) .use('style').loader(require.resolve('style-loader')).end()
.loader('css', require.resolve('css-loader')); .use('css').loader(require.resolve('css-loader'));

45
packages/neutrino-preset-airbnb-base/index.js

@ -1,28 +1,35 @@
const lint = require('neutrino-middleware-eslint'); const lint = require('neutrino-middleware-eslint');
const merge = require('deepmerge'); const merge = require('deepmerge');
const { join } = require('path');
module.exports = (neutrino, options) => neutrino.use(lint, merge({ module.exports = (neutrino, options) => {
include: options.include ? [] : [join(process.cwd(), 'SRC')], neutrino.use(lint, merge({
eslint: { eslint: {
baseConfig: { baseConfig: {
extends: ['airbnb-base'] extends: ['airbnb-base']
}, },
rules: { rules: {
// handled by babel rules // handled by babel rules
'new-cap': 'off', 'new-cap': 'off',
// handled by babel rules // handled by babel rules
'object-curly-spacing': 'off', 'object-curly-spacing': 'off',
// require a capital letter for constructors // require a capital letter for constructors
'babel/new-cap': ['error', { newIsCap: true }], 'babel/new-cap': ['error', { newIsCap: true }],
// require padding inside curly braces // require padding inside curly braces
'babel/object-curly-spacing': ['error', 'always'], 'babel/object-curly-spacing': ['error', 'always'],
// guard against awaiting async functions inside of a loop // guard against awaiting async functions inside of a loop
'babel/no-await-in-loop': 'error' 'babel/no-await-in-loop': 'error'
}
} }
}, options));
if (!options.include && !options.exclude) {
neutrino.config.module
.rule('lint')
.include
.add(neutrino.options.source);
} }
}, options)); };

57
packages/neutrino-preset-jest/src/index.js

@ -1,19 +1,18 @@
const { runCLI } = require('jest-cli'); const { runCLI } = require('jest-cli');
const fs = require('fs'); const { writeFileSync } = require('fs');
const path = require('path'); const { join } = require('path');
const merge = require('deepmerge'); const merge = require('deepmerge');
const os = require('os'); const { tmpdir } = require('os');
const clone = require('lodash.clonedeep'); const clone = require('lodash.clonedeep');
const loaderMerge = require('neutrino-middleware-loader-merge'); const loaderMerge = require('neutrino-middleware-loader-merge');
const pkg = require(path.join(process.cwd(), 'package.json'));
function normalizeJestOptions(jestOptions, config, args) { function normalizeJestOptions(jestOptions, config, args) {
const options = clone(jestOptions); const options = clone(jestOptions);
const aliases = config.options.get('alias') || {}; const aliases = config.resolve.alias.entries() || {};
Object Object
.keys(aliases) .keys(aliases)
.map(key => options.moduleNameMapper[key] = path.join('<rootDir>', aliases[key])); .map(key => options.moduleNameMapper[key] = join('<rootDir>', aliases[key]));
options.moduleFileExtensions = [...new Set([ options.moduleFileExtensions = [...new Set([
...options.moduleFileExtensions, ...options.moduleFileExtensions,
@ -24,7 +23,7 @@ function normalizeJestOptions(jestOptions, config, args) {
...config.resolve.modules.values() ...config.resolve.modules.values()
])]; ])];
options.globals = Object.assign({ options.globals = Object.assign({
BABEL_OPTIONS: config.module.rule('compile').loaders.get('babel').options BABEL_OPTIONS: config.module.rule('compile').use('babel').get('options')
}, options.globals); }, options.globals);
if (args.files.length) { if (args.files.length) {
@ -35,24 +34,20 @@ function normalizeJestOptions(jestOptions, config, args) {
} }
module.exports = neutrino => { module.exports = neutrino => {
const jestOptions = merge.all([ const jestOptions = merge({
{ bail: true,
bail: true, transform: {
transform: { "\\.(js|jsx)$": require.resolve('./transformer')
"\\.(js|jsx)$": require.resolve('./transformer')
},
roots: [path.join(process.cwd(), 'test')],
testRegex: '(_test|_spec|\\.test|\\.spec)\\.jsx?$',
moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: [path.join(__dirname, '../node_modules')],
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': require.resolve('./file-mock'),
'\\.(css|less|sass)$': require.resolve('./style-mock')
}
}, },
pkg.jest || {}, roots: [neutrino.options.tests],
neutrino.options.jest || {} testRegex: '(_test|_spec|\\.test|\\.spec)\\.jsx?$',
]); moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: [join(__dirname, '../node_modules')],
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': require.resolve('./file-mock'),
'\\.(css|less|sass)$': require.resolve('./style-mock')
}
}, neutrino.options.jest || {});
neutrino.use(loaderMerge('compile', 'babel'), { neutrino.use(loaderMerge('compile', 'babel'), {
env: { env: {
@ -73,20 +68,14 @@ module.exports = neutrino => {
neutrino.on('test', args => { neutrino.on('test', args => {
const options = normalizeJestOptions(jestOptions, neutrino.config, args); const options = normalizeJestOptions(jestOptions, neutrino.config, args);
const configFile = path.join(os.tmpdir(), 'config.json'); const configFile = join(tmpdir(), 'config.json');
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const cliOptions = { config: configFile, coverage: args.coverage, watch: args.watch }; const cliOptions = { config: configFile, coverage: args.coverage, watch: args.watch };
const dir = options.rootDir || process.cwd(); const dir = options.rootDir || neutrino.options.root;
fs.writeFileSync(configFile, `${JSON.stringify(options, null, 2)}\n`); writeFileSync(configFile, `${JSON.stringify(options, null, 2)}\n`);
runCLI(cliOptions, dir, result => { runCLI(cliOptions, dir, result => result.numFailedTests || result.numFailedTestSuites ? reject() : resolve());
if (result.numFailedTests || result.numFailedTestSuites) {
reject();
} else {
resolve();
}
});
}); });
}); });
}; };

16
packages/neutrino-preset-karma/index.js

@ -1,7 +1,11 @@
const { Server } = require('karma'); const { Server } = require('karma');
const merge = require('deepmerge'); const merge = require('deepmerge');
const { join } = require('path');
module.exports = neutrino => { module.exports = neutrino => {
const tests = join(neutrino.options.tests, '**/*_test.js');
const sources = join(neutrino.options.source, '**/*.js');
const defaults = { const defaults = {
plugins: [ plugins: [
require.resolve('karma-webpack'), require.resolve('karma-webpack'),
@ -10,7 +14,7 @@ module.exports = neutrino => {
require.resolve('karma-mocha'), require.resolve('karma-mocha'),
require.resolve('karma-mocha-reporter') require.resolve('karma-mocha-reporter')
], ],
basePath: process.cwd(), basePath: neutrino.options.root,
browsers: [process.env.CI ? 'ChromeCI' : 'Chrome'], browsers: [process.env.CI ? 'ChromeCI' : 'Chrome'],
customLaunchers: { customLaunchers: {
ChromeCI: { ChromeCI: {
@ -19,10 +23,10 @@ module.exports = neutrino => {
} }
}, },
frameworks: ['mocha'], frameworks: ['mocha'],
files: ['test/**/*_test.js'], files: [tests],
preprocessors: { preprocessors: {
'test/**/*_test.js': ['webpack'], [tests]: ['webpack'],
'src/**/*.js': ['webpack'] [sources]: ['webpack']
}, },
webpackMiddleware: { noInfo: true }, webpackMiddleware: { noInfo: true },
reporters: ['mocha', 'coverage'], reporters: ['mocha', 'coverage'],
@ -52,8 +56,6 @@ module.exports = neutrino => {
karma.files = files; karma.files = files;
} }
return new Promise(resolve => { return new Promise(resolve => new Server(karma, resolve).start());
new Server(karma, resolve).start();
});
}); });
}; };

2
packages/neutrino-preset-mocha/src/index.js

@ -13,7 +13,7 @@ module.exports = neutrino => {
neutrino.on('test', ({ files }) => mocha( neutrino.on('test', ({ files }) => mocha(
merge({ reporter: 'spec', ui: 'tdd', bail: true }, neutrino.options.mocha || {}), merge({ reporter: 'spec', ui: 'tdd', bail: true }, neutrino.options.mocha || {}),
neutrino.config.module.rule('compile').loaders.get('babel').options, neutrino.config.module.rule('compile').use('babel').get('options'),
files files
)); ));
}; };

33
packages/neutrino-preset-node/index.js

@ -10,20 +10,19 @@ const namedModules = require('neutrino-middleware-named-modules');
const nodeExternals = require('webpack-node-externals'); const nodeExternals = require('webpack-node-externals');
const { join } = require('path'); const { join } = require('path');
const CWD = process.cwd();
const SRC = join(CWD, 'src');
const BUILD = join(CWD, 'build');
const TEST = join(CWD, 'test');
const PROJECT_MODULES = join(CWD, 'node_modules');
const MODULES = join(__dirname, 'node_modules'); const MODULES = join(__dirname, 'node_modules');
const PKG = require(join(CWD, 'package.json'));
module.exports = neutrino => { module.exports = neutrino => {
const { config } = neutrino; const { config } = neutrino;
let pkg = {};
try {
pkg = require(join(neutrino.options.root, 'package.json'));
} catch (ex) {}
neutrino.use(namedModules); neutrino.use(namedModules);
neutrino.use(compile, { neutrino.use(compile, {
include: [SRC, TEST], include: [neutrino.options.source, neutrino.options.tests],
babel: { babel: {
plugins: [require.resolve('babel-plugin-dynamic-import-node')], plugins: [require.resolve('babel-plugin-dynamic-import-node')],
presets: [ presets: [
@ -46,19 +45,19 @@ module.exports = neutrino => {
.end() .end()
.devtool('source-map') .devtool('source-map')
.externals([nodeExternals({ whitelist: [/^webpack/] })]) .externals([nodeExternals({ whitelist: [/^webpack/] })])
.context(CWD) .context(neutrino.options.root)
.entry('index') .entry('index')
.add(join(SRC, 'index.js')) .add(neutrino.options.entry)
.end() .end()
.output .output
.path(BUILD) .path(neutrino.options.output)
.filename('[name].js') .filename('[name].js')
.libraryTarget('commonjs2') .libraryTarget('commonjs2')
.chunkFilename('[id].[hash:5]-[chunkhash:7].js') .chunkFilename('[id].[hash:5]-[chunkhash:7].js')
.end() .end()
.resolve .resolve
.modules .modules
.add(PROJECT_MODULES) .add(neutrino.options.node_modules)
.add(MODULES) .add(MODULES)
.end() .end()
.extensions .extensions
@ -68,21 +67,21 @@ module.exports = neutrino => {
.end() .end()
.resolveLoader .resolveLoader
.modules .modules
.add(PROJECT_MODULES) .add(neutrino.options.node_modules)
.add(MODULES); .add(MODULES);
const hasSourceMap = (PKG.dependencies && 'source-map-support' in PKG.dependencies) || const hasSourceMap = (pkg.dependencies && 'source-map-support' in pkg.dependencies) ||
(PKG.devDependencies && 'source-map-support' in PKG.devDependencies); (pkg.devDependencies && 'source-map-support' in pkg.devDependencies);
if (hasSourceMap) { if (hasSourceMap) {
neutrino.use(banner); neutrino.use(banner);
} }
if (process.env.NODE_ENV !== 'development') { if (process.env.NODE_ENV !== 'development') {
neutrino.use(clean, { paths: [BUILD] }); neutrino.use(clean, { paths: [neutrino.options.output] });
neutrino.use(progress); neutrino.use(progress);
neutrino.use(copy, { neutrino.use(copy, {
patterns: [{ context: SRC, from: `**/*` }], patterns: [{ context: neutrino.options.source, from: `**/*` }],
options: { ignore: ['*.js*'] } options: { ignore: ['*.js*'] }
}); });
} else { } else {
@ -90,7 +89,7 @@ module.exports = neutrino => {
config.entry('index').add('webpack/hot/poll?1000'); config.entry('index').add('webpack/hot/poll?1000');
config.output.devtoolModuleFilenameTemplate('[absolute-resource-path]'); config.output.devtoolModuleFilenameTemplate('[absolute-resource-path]');
neutrino.use(hot); neutrino.use(hot);
neutrino.use(startServer, join(SRC, 'index.js')); neutrino.use(startServer, neutrino.options.entry);
} }
if (config.module.rules.has('lint')) { if (config.module.rules.has('lint')) {

23
packages/neutrino-preset-node/test/web_test.js

@ -0,0 +1,23 @@
import test from 'ava';
import { validate } from 'webpack';
import Neutrino from 'neutrino';
test('loads preset', t => {
t.notThrows(() => require('..'));
});
test('uses preset', t => {
const api = new Neutrino();
t.notThrows(() => api.use(require('..')));
});
test('valid preset', t => {
const api = new Neutrino();
api.use(require('..'));
const errors = validate(api.getWebpackOptions());
t.is(errors.length, 0);
});

12
packages/neutrino-preset-react/index.js

@ -21,13 +21,11 @@ module.exports = neutrino => {
config.resolve.modules.add(MODULES); config.resolve.modules.add(MODULES);
config.resolve.extensions.add('.jsx'); config.resolve.extensions.add('.jsx');
config.resolveLoader.modules.add(MODULES); config.resolveLoader.modules.add(MODULES);
config.externals({
config 'react/addons': true,
.externals({ 'react/lib/ExecutionEnvironment': true,
'react/addons': true, 'react/lib/ReactContext': 'window'
'react/lib/ExecutionEnvironment': true, });
'react/lib/ReactContext': 'window'
});
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
config config

23
packages/neutrino-preset-react/test/web_test.js

@ -0,0 +1,23 @@
import test from 'ava';
import { validate } from 'webpack';
import Neutrino from 'neutrino';
test('loads preset', t => {
t.notThrows(() => require('..'));
});
test('uses preset', t => {
const api = new Neutrino();
t.notThrows(() => api.use(require('..')));
});
test('valid preset', t => {
const api = new Neutrino();
api.use(require('..'));
const errors = validate(api.getWebpackOptions());
t.is(errors.length, 0);
});

30
packages/neutrino-preset-web/index.js

@ -16,12 +16,6 @@ const namedModules = require('neutrino-middleware-named-modules');
const { join } = require('path'); const { join } = require('path');
const { pathOr } = require('ramda'); const { pathOr } = require('ramda');
const CWD = process.cwd();
const SRC = join(CWD, 'src');
const BUILD = join(CWD, 'build');
const TEST = join(CWD, 'test');
const PKG = require(join(CWD, 'package.json'));
const PROJECT_MODULES = join(CWD, 'node_modules');
const MODULES = join(__dirname, 'node_modules'); const MODULES = join(__dirname, 'node_modules');
module.exports = neutrino => { module.exports = neutrino => {
@ -35,7 +29,7 @@ module.exports = neutrino => {
neutrino.use(htmlTemplate); neutrino.use(htmlTemplate);
neutrino.use(namedModules); neutrino.use(namedModules);
neutrino.use(compileLoader, { neutrino.use(compileLoader, {
include: [SRC, TEST], include: [neutrino.options.source, neutrino.options.tests],
babel: { babel: {
plugins: [require.resolve('babel-plugin-syntax-dynamic-import')], plugins: [require.resolve('babel-plugin-syntax-dynamic-import')],
presets: [ presets: [
@ -64,20 +58,20 @@ module.exports = neutrino => {
config config
.target('web') .target('web')
.context(CWD) .context(neutrino.options.root)
.entry('index') .entry('index')
.add(require.resolve('babel-polyfill')) .add(require.resolve('babel-polyfill'))
.add(join(SRC, 'index.js')); .add(neutrino.options.entry);
config.output config.output
.path(BUILD) .path(neutrino.options.output)
.publicPath('./') .publicPath('./')
.filename('[name].bundle.js') .filename('[name].bundle.js')
.chunkFilename('[id].[chunkhash].js'); .chunkFilename('[id].[chunkhash].js');
config.resolve.modules.add(PROJECT_MODULES).add(MODULES); config.resolve.modules.add(neutrino.options.node_modules).add(MODULES);
config.resolve.extensions.add('.js').add('.json'); config.resolve.extensions.add('.js').add('.json');
config.resolveLoader.modules.add(PROJECT_MODULES).add(MODULES); config.resolveLoader.modules.add(neutrino.options.node_modules).add(MODULES);
config.node config.node
.set('console', false) .set('console', false)
@ -99,15 +93,15 @@ module.exports = neutrino => {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
const protocol = !!process.env.HTTPS ? 'https' : 'http'; const protocol = !!process.env.HTTPS ? 'https' : 'http';
const host = process.env.HOST || pathOr('localhost', ['neutrino', 'config', 'devServer', 'host'], PKG); const host = process.env.HOST || pathOr('localhost', ['options', 'config', 'devServer', 'host'], neutrino);
const port = process.env.PORT || pathOr(5000, ['neutrino', 'config', 'devServer', 'port'], PKG); const port = process.env.PORT || pathOr(5000, ['options', 'config', 'devServer', 'port'], neutrino);
neutrino.use(hot); neutrino.use(hot);
neutrino.use(devServer, { neutrino.use(devServer, {
host, host,
port, port,
https: protocol === 'https', https: pathOr(protocol === 'https', ['options', 'config', 'devServer', 'https'], neutrino),
contentBase: SRC contentBase: neutrino.options.source
}); });
config config
@ -116,11 +110,11 @@ module.exports = neutrino => {
.add(`webpack-dev-server/client?${protocol}://${host}:${port}/`) .add(`webpack-dev-server/client?${protocol}://${host}:${port}/`)
.add('webpack/hot/dev-server'); .add('webpack/hot/dev-server');
} else { } else {
neutrino.use(clean, { paths: [BUILD] }); neutrino.use(clean, { paths: [neutrino.options.output] });
neutrino.use(progress); neutrino.use(progress);
neutrino.use(minify); neutrino.use(minify);
neutrino.use(copy, { neutrino.use(copy, {
patterns: [{ context: SRC, from: `**/*` }], patterns: [{ context: neutrino.options.source, from: `**/*` }],
options: { ignore: ['*.js*'] } options: { ignore: ['*.js*'] }
}); });
config.output.filename('[name].[chunkhash].bundle.js'); config.output.filename('[name].[chunkhash].bundle.js');

23
packages/neutrino-preset-web/test/web_test.js

@ -0,0 +1,23 @@
import test from 'ava';
import { validate } from 'webpack';
import Neutrino from 'neutrino';
test('loads preset', t => {
t.notThrows(() => require('..'));
});
test('uses preset', t => {
const api = new Neutrino();
t.notThrows(() => api.use(require('..')));
});
test('valid preset', t => {
const api = new Neutrino();
api.use(require('..'));
const errors = validate(api.getWebpackOptions());
t.is(errors.length, 0);
});

8
packages/neutrino/bin/neutrino

@ -59,8 +59,8 @@ function run(command, presets) {
process.env.NODE_ENV = environments[command]; process.env.NODE_ENV = environments[command];
const options = pathOr({}, ['neutrino', 'options'], pkg); const options = pathOr({}, ['neutrino', 'options'], pkg);
const api = new Neutrino(options); const config = pathOr({}, ['neutrino', 'config'], pkg);
const cwd = process.cwd(); const api = new Neutrino(Object.assign(options, { config }));
// Grab all presets and merge them into a single webpack-chain config instance // Grab all presets and merge them into a single webpack-chain config instance
presets.forEach(preset => { presets.forEach(preset => {
@ -89,8 +89,8 @@ function run(command, presets) {
}); });
// Also grab any Neutrino config from package.json and merge it into the config at a higher precedence // Also grab any Neutrino config from package.json and merge it into the config at a higher precedence
if (pkg.neutrino && pkg.neutrino.config) { if (Object.keys(config).length) {
api.config.merge(pkg.neutrino.config); api.config.merge(config);
} }
if (args.inspect) { if (args.inspect) {

3
packages/neutrino/package.json

@ -23,11 +23,12 @@
}, },
"dependencies": { "dependencies": {
"deep-sort-object": "^1.0.1", "deep-sort-object": "^1.0.1",
"deepmerge": "^1.3.2",
"javascript-stringify": "^1.6.0", "javascript-stringify": "^1.6.0",
"ora": "^1.1.0", "ora": "^1.1.0",
"ramda": "^0.23.0", "ramda": "^0.23.0",
"webpack": "^2.2.1", "webpack": "^2.2.1",
"webpack-chain": "^2.0.0", "webpack-chain": "^3.0.0",
"webpack-dev-server": "^2.4.1", "webpack-dev-server": "^2.4.1",
"yargs": "^6.6.0" "yargs": "^6.6.0"
} }

17
packages/neutrino/src/neutrino.js

@ -1,15 +1,24 @@
const path = require('path'); const { join } = require('path');
const EventEmitter = require('events').EventEmitter; const { EventEmitter } = require('events');
const DevServer = require('webpack-dev-server'); const DevServer = require('webpack-dev-server');
const webpack = require('webpack'); const webpack = require('webpack');
const Config = require('webpack-chain'); const Config = require('webpack-chain');
const ora = require('ora'); const ora = require('ora');
const merge = require('deepmerge');
class Neutrino extends EventEmitter { class Neutrino extends EventEmitter {
constructor(options) { constructor(options = {}) {
super(); super();
const root = options.root || process.cwd();
const source = options.source || join(root, 'src');
const output = options.output || join(root, 'build');
const tests = options.tests || join(root, 'test');
const node_modules = options.node_modules || join(root, 'node_modules');
const entry = options.entry || join(source, 'index.js');
this.config = new Config(); this.config = new Config();
this.options = options; this.options = merge(options, { root, source, output, tests, node_modules, entry });
} }
use(preset, options = {}) { use(preset, options = {}) {

12
packages/neutrino/test/api_test.js

@ -13,7 +13,9 @@ test('initialization stores options', t => {
const options = { alpha: 'a', beta: 'b', gamma: 'c' }; const options = { alpha: 'a', beta: 'b', gamma: 'c' };
const api = new Neutrino(options); const api = new Neutrino(options);
t.deepEqual(options, api.options); t.is(api.options.alpha, options.alpha);
t.is(api.options.beta, options.beta);
t.is(api.options.gamma, options.gamma);
}); });
test('creates an instance of webpack-chain', t => { test('creates an instance of webpack-chain', t => {
@ -91,8 +93,12 @@ test('creates a Webpack config', t => {
api.config.module api.config.module
.rule('compile') .rule('compile')
.test(/\.js$/) .test(/\.js$/)
.include('src') .include
.loader('babel', 'babel-loader', { alpha: 'a', beta: 'b' }); .add('src')
.end()
.use('babel')
.loader('babel-loader')
.options({ alpha: 'a', beta: 'b' });
}); });
t.deepEqual(api.getWebpackOptions(), { t.deepEqual(api.getWebpackOptions(), {

6
packages/neutrino/yarn.lock

@ -2157,9 +2157,9 @@ wbuf@^1.1.0, wbuf@^1.4.0:
dependencies: dependencies:
minimalistic-assert "^1.0.0" minimalistic-assert "^1.0.0"
webpack-chain@^2.0.0: webpack-chain@^3.0.0:
version "2.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-2.0.0.tgz#ddf52623b110e552684cec7e85f97b24a7b57f10" resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-3.0.0.tgz#20d0b92e84cb294035e1fa03ce2fb8805cce51b6"
dependencies: dependencies:
deepmerge "^1.3.2" deepmerge "^1.3.2"

718
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save