Browse Source

ESLint fixes and webpack-chain integration

plugin-mode
Eli Perelman 8 years ago
parent
commit
c358c0c31e
  1. 1
      package.json
  2. 1
      packages/neutrino-preset-base/package.json
  3. 8
      packages/neutrino-preset-base/src/eslint.js
  4. 141
      packages/neutrino-preset-base/src/index.js
  5. 27
      packages/neutrino-preset-base/yarn.lock
  6. 1
      packages/neutrino-preset-node/package.json
  7. 154
      packages/neutrino-preset-node/src/index.js
  8. 4
      packages/neutrino-preset-node/yarn.lock
  9. 105
      packages/neutrino-preset-react/src/index.js
  10. 342
      packages/neutrino-preset-web/src/index.js
  11. 8
      packages/neutrino-preset-web/yarn.lock
  12. 10
      packages/neutrino/src/get-preset.js
  13. 18
      packages/neutrino/yarn.lock

1
package.json

@ -8,6 +8,7 @@
"author": "Eli Perelman <eli@eliperelman.com>", "author": "Eli Perelman <eli@eliperelman.com>",
"license": "MPL-2.0", "license": "MPL-2.0",
"scripts": { "scripts": {
"bootstrap": "autolink bootstrap",
"postinstall": "autolink bootstrap", "postinstall": "autolink bootstrap",
"clean-all": "autolink clean", "clean-all": "autolink clean",
"link-all": "autolink link", "link-all": "autolink link",

1
packages/neutrino-preset-base/package.json

@ -27,6 +27,7 @@
"imports-loader": "^0.7.0", "imports-loader": "^0.7.0",
"progress-bar-webpack-plugin": "^1.9.3", "progress-bar-webpack-plugin": "^1.9.3",
"webpack": "^2.2.1", "webpack": "^2.2.1",
"webpack-chain": "^1.0.0",
"webpack-merge": "^2.6.1" "webpack-merge": "^2.6.1"
}, },
"peerDependencies": { "peerDependencies": {

8
packages/neutrino-preset-base/src/eslint.js

@ -3,12 +3,10 @@ const eslint = {
useEslintrc: false, useEslintrc: false,
root: true, root: true,
plugins: ['babel', 'mocha'], plugins: ['babel', 'mocha'],
extends: [ baseConfig: {
'eslint:recommended', extends: ['eslint:recommended']
],
env: {
es6: true
}, },
envs: ['es6'],
parser: 'babel-eslint', parser: 'babel-eslint',
parserOptions: { parserOptions: {
ecmaVersion: 2017, ecmaVersion: 2017,

141
packages/neutrino-preset-base/src/index.js

@ -1,5 +1,6 @@
'use strict'; 'use strict';
const Config = require('webpack-chain');
const CleanPlugin = require('clean-webpack-plugin'); const CleanPlugin = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin');
const path = require('path'); const path = require('path');
@ -14,83 +15,81 @@ const BASE_MODULES = path.join(__dirname, '../node_modules');
const SRC = path.join(CWD, 'src'); const SRC = path.join(CWD, 'src');
const TEST = path.join(CWD, 'test'); const TEST = path.join(CWD, 'test');
const config = { const config = new Config();
context: CWD,
entry: { config
index: [path.join(SRC, 'index.js')] .context(CWD)
}, .entry('index')
output: { .add(path.join(SRC, 'index.js'))
path: BUILD, .end()
filename: '[name].bundle.js', .output
chunkFilename: '[id].[chunkhash].js' .path(path.join(process.cwd(), 'build'))
}, .filename('[name].bundle.js')
plugins: [], .chunkFilename('[id].[chunkhash].js')
resolve: { .end()
modules: [PROJECT_MODULES, BASE_MODULES], .resolve
extensions: ['.js', '.json'] .modules
}, .add(PROJECT_MODULES)
resolveLoader: { .add(BASE_MODULES)
modules: [PROJECT_MODULES, BASE_MODULES] .end()
}, .extensions
module: { .add('.js')
rules: [ .add('json')
{ .end()
test: /\.js$/, .end()
include: [SRC], .resolveLoader
enforce: 'pre', .modules
use: { .add(PROJECT_MODULES)
loader: require.resolve('eslint-loader'), .add(BASE_MODULES);
options: lint
} config
}, .module
{ .rule('lint')
test: /\.js$/, .test(/\.js$/)
include: [SRC, TEST], .pre()
use: { .include(SRC)
loader: require.resolve('babel-loader'), .loader('eslint', require.resolve('eslint-loader'), Object.assign({
options: { failOnError: process.env.NODE_ENV !== 'development',
presets: [ emitWarning: process.env.NODE_ENV !== 'development',
[require.resolve('babel-preset-env'), { modules: false, targets: {} }] emitError: process.env.NODE_ENV !== 'development'
], }, lint));
plugins: [],
env: { config
test: { .module
plugins: [ .rule('compile')
// FIXME: This currently breaks the coverage .test(/\.js$/)
//[require.resolve('babel-plugin-istanbul'), { exclude: ['test/**/*'] }] .include(SRC, TEST)
] .loader('babel', require.resolve('babel-loader'), {
} presets: [
} [require.resolve('babel-preset-env'), { modules: false, targets: {} }]
],
plugins: [],
env: {
test: {
plugins: [
// FIXME: This currently breaks the coverage
//[require.resolve('babel-plugin-istanbul'), { exclude: ['test/**/*'] }]
]
} }
} }
} });
]
}
};
const eslint = {
emitError: true,
failOnError: true
};
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
config.devtool = 'eval'; config.devtool('eval');
eslint.failOnError = false;
eslint.emitWarning = false;
eslint.emitError = false;
} else { } else {
// Copy all files except JS files, since they will be Babel-compiled to the output directory. config.output.filename('[name].[chunkhash].bundle.js');
// This only needs to be done in production since in development assets should be served from the
// webpack-development-server via the source directory.
config.plugins.push(
new CopyPlugin([{ context: SRC, from: `**/*` }], { ignore: ['*.js*'] }),
new ProgressBarPlugin(),
new CleanPlugin([BUILD], { root: CWD })
);
config.output.filename = '[name].[chunkhash].bundle.js'; config
} .plugin('copy')
.use(CopyPlugin, [{ context: SRC, from: `**/*` }], { ignore: ['*.js*'] });
config.plugins.push(new webpack.LoaderOptionsPlugin({ options: { eslint }})); config
.plugin('progress')
.use(ProgressBarPlugin);
config
.plugin('clean')
.use(CleanPlugin, [BUILD], { root: CWD });
}
module.exports = config; module.exports = config;

27
packages/neutrino-preset-base/yarn.lock

@ -18,7 +18,7 @@ acorn-jsx@^3.0.0:
dependencies: dependencies:
acorn "^3.0.4" acorn "^3.0.4"
acorn@4.0.4, acorn@^4.0.3, acorn@^4.0.4: acorn@4.0.4:
version "4.0.4" version "4.0.4"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a"
@ -26,6 +26,10 @@ acorn@^3.0.4:
version "3.3.0" version "3.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
acorn@^4.0.3, acorn@^4.0.4:
version "4.0.8"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.8.tgz#f41e52020ce78118a3c68ed0e9215eb8fc68b5b1"
ajv-keywords@^1.0.0, ajv-keywords@^1.1.1: ajv-keywords@^1.0.0, ajv-keywords@^1.1.1:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
@ -1097,20 +1101,13 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0" miller-rabin "^4.0.0"
randombytes "^2.0.0" randombytes "^2.0.0"
doctrine@1.5.0: doctrine@1.5.0, doctrine@^1.2.2:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
dependencies: dependencies:
esutils "^2.0.2" esutils "^2.0.2"
isarray "^1.0.0" isarray "^1.0.0"
doctrine@^1.2.2:
version "1.3.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.3.0.tgz#13e75682b55518424276f7c173783456ef913d26"
dependencies:
esutils "^2.0.2"
isarray "^1.0.0"
domain-browser@^1.1.1: domain-browser@^1.1.1:
version "1.1.7" version "1.1.7"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
@ -1274,8 +1271,8 @@ eslint-plugin-mocha@^4.8.0:
ramda "^0.22.1" ramda "^0.22.1"
eslint@^3.14.1: eslint@^3.14.1:
version "3.14.1" version "3.15.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.14.1.tgz#8a62175f2255109494747a1b25128d97b8eb3d97" resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.15.0.tgz#bdcc6a6c5ffe08160e7b93c066695362a91e30f2"
dependencies: dependencies:
babel-code-frame "^6.16.0" babel-code-frame "^6.16.0"
chalk "^1.1.3" chalk "^1.1.3"
@ -1283,7 +1280,7 @@ eslint@^3.14.1:
debug "^2.1.1" debug "^2.1.1"
doctrine "^1.2.2" doctrine "^1.2.2"
escope "^3.6.0" escope "^3.6.0"
espree "^3.3.1" espree "^3.4.0"
estraverse "^4.2.0" estraverse "^4.2.0"
esutils "^2.0.2" esutils "^2.0.2"
file-entry-cache "^2.0.0" file-entry-cache "^2.0.0"
@ -1312,7 +1309,7 @@ eslint@^3.14.1:
text-table "~0.2.0" text-table "~0.2.0"
user-home "^2.0.0" user-home "^2.0.0"
espree@^3.3.1: espree@^3.4.0:
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.0.tgz#41656fa5628e042878025ef467e78f125cb86e1d" resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.0.tgz#41656fa5628e042878025ef467e78f125cb86e1d"
dependencies: dependencies:
@ -3005,6 +3002,10 @@ watchpack@^1.2.0:
chokidar "^1.4.3" chokidar "^1.4.3"
graceful-fs "^4.1.2" graceful-fs "^4.1.2"
webpack-chain@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-1.0.0.tgz#42da40d66e98200ccca3fa274f7fc111b1e1c2c1"
webpack-merge@^2.6.1: webpack-merge@^2.6.1:
version "2.6.1" version "2.6.1"
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-2.6.1.tgz#f1d801d2c5d39f83ffec9f119240b3e3be994a1c" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-2.6.1.tgz#f1d801d2c5d39f83ffec9f119240b3e3be994a1c"

1
packages/neutrino-preset-node/package.json

@ -12,6 +12,7 @@
"repository": "mozilla-neutrino/neutrino-dev", "repository": "mozilla-neutrino/neutrino-dev",
"dependencies": { "dependencies": {
"babel-runtime": "^6.22.0", "babel-runtime": "^6.22.0",
"deepmerge": "^1.3.2",
"source-map-support": "^0.4.6", "source-map-support": "^0.4.6",
"webpack": "^2.2.1", "webpack": "^2.2.1",
"webpack-merge": "^2.6.1", "webpack-merge": "^2.6.1",

154
packages/neutrino-preset-node/src/index.js

@ -1,99 +1,105 @@
'use strict'; 'use strict';
const merge = require('webpack-merge').smart; const config = require('neutrino-preset-base');
const preset = require('neutrino-preset-base');
const nodeExternals = require('webpack-node-externals'); const nodeExternals = require('webpack-node-externals');
const path = require('path'); const path = require('path');
const webpack = require('webpack'); const webpack = require('webpack');
const merge = require('deepmerge');
const MODULES = path.join(__dirname, '../node_modules'); const MODULES = path.join(__dirname, '../node_modules');
const config = merge(preset, { config
target: 'node', .target('node')
output: { .devtool('source-map')
filename: '[name].js', .externals([nodeExternals()])
libraryTarget: 'commonjs2' .node
}, .set('__filename', false)
resolve: { .set('__dirname', false)
modules: [MODULES] .end()
}, .output
resolveLoader: { .filename('[name].js')
modules: [MODULES] .libraryTarget('commonjs2');
},
devtool: 'source-map', config.resolve.modules.add(MODULES);
node: { config.resolveLoader.modules.add(MODULES);
__filename: false,
__dirname: false config
}, .plugin('options')
plugins: [ .use(webpack.LoaderOptionsPlugin, {
new webpack.LoaderOptionsPlugin({ emitError: true,
options: { failOnError: true,
emitError: true, mocha: {
failOnError: true, reporter: 'spec',
mocha: { ui: 'tdd',
reporter: 'spec', bail: true
ui: 'tdd', }
bail: true });
}
} config
}), .plugin('banner')
new webpack.BannerPlugin({ .use(webpack.BannerPlugin, {
banner: 'require("source-map-support").install();', banner: `require('source-map-support').install();`,
raw: true, raw: true,
entryOnly: true entryOnly: true
}) });
],
externals: [nodeExternals()], config.options.set('performance', {
performance: { hints: false
hints: false
}
}); });
const babelLoader = config.module.rules.find(r => r.use && r.use.loader && r.use.loader.includes('babel')); config.module
.rule('compile')
// Polyfill based on Node.js LTS 6.9.0 .loader('babel', ({ options }) => {
babelLoader.use.options.presets[0][1].targets.node = 6.9; options.presets[0][1].targets.node = 6.9;
const eslintLoader = config.module.rules.find(r => r.use && r.use.loader && r.use.loader.includes('eslint'));
eslintLoader.use.options.env.node = true; return { options };
});
Object.assign(eslintLoader.use.options.rules, { config.module
// enforce return after a callback .rule('lint')
'callback-return': 'off', .loader('eslint', ({ options }) => {
return {
options: merge(options, {
envs: ['node'],
rules: {
// enforce return after a callback
'callback-return': 'off',
// require all requires be top-level // require all requires be top-level
// http://eslint.org/docs/rules/global-require // http://eslint.org/docs/rules/global-require
'global-require': 'error', 'global-require': 'error',
// enforces error handling in callbacks (node environment) // enforces error handling in callbacks (node environment)
'handle-callback-err': 'off', 'handle-callback-err': 'off',
// Allow console in Node.js // Allow console in Node.js
'no-console': 'off', 'no-console': 'off',
// disallow mixing regular variable and require declarations // disallow mixing regular variable and require declarations
'no-mixed-requires': ['off', false], 'no-mixed-requires': ['off', false],
// disallow use of new operator with the require function // disallow use of new operator with the require function
'no-new-require': 'error', 'no-new-require': 'error',
// disallow string concatenation with __dirname and __filename // disallow string concatenation with __dirname and __filename
// http://eslint.org/docs/rules/no-path-concat // http://eslint.org/docs/rules/no-path-concat
'no-path-concat': 'error', 'no-path-concat': 'error',
// disallow use of process.env // disallow use of process.env
'no-process-env': 'off', 'no-process-env': 'off',
// disallow process.exit() // disallow process.exit()
'no-process-exit': 'off', 'no-process-exit': 'off',
// restrict usage of specified node modules // restrict usage of specified node modules
'no-restricted-modules': 'off', 'no-restricted-modules': 'off',
// disallow use of synchronous methods (off by default) // disallow use of synchronous methods (off by default)
'no-sync': 'off' 'no-sync': 'off'
}); }
})
};
});
module.exports = config; module.exports = config;

4
packages/neutrino-preset-node/yarn.lock

@ -450,6 +450,10 @@ deep-extend@~0.4.0:
version "0.4.1" version "0.4.1"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
deepmerge@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.3.2.tgz#1663691629d4dbfe364fa12a2a4f0aa86aa3a050"
delayed-stream@~1.0.0: delayed-stream@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"

105
packages/neutrino-preset-react/src/index.js

@ -1,62 +1,75 @@
'use strict'; 'use strict';
const preset = require('neutrino-preset-web'); const config = require('neutrino-preset-web');
const merge = require('deepmerge'); const merge = require('deepmerge');
const webpackMerge = require('webpack-merge').smart;
const path = require('path'); const path = require('path');
const webpack = require('webpack'); const webpack = require('webpack');
const MODULES = path.join(__dirname, '../node_modules'); const MODULES = path.join(__dirname, '../node_modules');
const eslintLoader = preset.module.rules.find(r => r.use && r.use.loader && r.use.loader.includes('eslint'));
const babelLoader = preset.module.rules.find(r => r.use && r.use.loader && r.use.loader.includes('babel')); // modify lint rule and loader
config.module
eslintLoader.test = /\.jsx?$/; .rule('lint')
babelLoader.test = /\.jsx?$/; .test(/\.jsx?$/)
babelLoader.use.options.presets.push(require.resolve('babel-preset-stage-0')); .loader('eslint', ({ options }) => {
babelLoader.use.options.presets.push(require.resolve('babel-preset-react')); return {
options: merge(options, {
eslintLoader.use.options = merge(eslintLoader.use.options, { plugins: ['react'],
plugins: ['react'], baseConfig: {
extends: [ extends: ['plugin:react/recommended']
'plugin:react/recommended' },
], parserOptions: {
settings: { ecmaFeatures: {
pragma: 'React', experimentalObjectRestSpread: true
version: '15.0' }
}, },
parserOptions: { rules: {
ecmaFeatures: { 'react/prop-types': ['off'],
experimentalObjectRestSpread: true, 'jsx-quotes': ['error', 'prefer-double']
jsx: true }
})
};
});
// modify babel rule and loader
config.module
.rule('compile')
.test(/\.jsx?$/)
.loader('babel', ({ options }) => {
if (process.env.NODE_ENV === 'development') {
options.plugins.push(require.resolve('react-hot-loader/babel'));
} }
},
rules: { return {
'react/prop-types': ['off'], options: merge(options, {
presets: [
// specify whether double or single quotes should be used in JSX attributes require.resolve('babel-preset-stage-0'),
// http://eslint.org/docs/rules/jsx-quotes require.resolve('babel-preset-react')
'jsx-quotes': ['error', 'prefer-double'] ]
} })
}); };
});
const config = webpackMerge(preset, {
resolve: { config.resolve
modules: [MODULES], .modules
extensions: ['.jsx'] .add(MODULES)
}, .end()
resolveLoader: { .extensions
modules: [MODULES] .add('.jsx');
},
externals: { config.resolveLoader.modules.add(MODULES);
config
.externals({
'react/addons': true, 'react/addons': true,
'react/lib/ExecutionEnvironment': true, 'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': 'window' 'react/lib/ReactContext': 'window'
} });
});
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
config.entry.index.unshift(require.resolve('react-hot-loader/patch')); config
babelLoader.use.options.plugins.push(require.resolve('react-hot-loader/babel')); .entry('index')
.add(require.resolve('react-hot-loader/patch'));
} }
module.exports = config; module.exports = config;

342
packages/neutrino-preset-web/src/index.js

@ -4,9 +4,8 @@ const exists = require('exists-file');
const webpack = require('webpack'); const webpack = require('webpack');
const HtmlPlugin = require('html-webpack-plugin'); const HtmlPlugin = require('html-webpack-plugin');
const merge = require('deepmerge'); const merge = require('deepmerge');
const preset = require('neutrino-preset-base'); const config = require('neutrino-preset-base');
const path = require('path'); const path = require('path');
const webpackMerge = require('webpack-merge').smart;
const CWD = process.cwd(); const CWD = process.cwd();
const SRC = path.join(CWD, 'src'); const SRC = path.join(CWD, 'src');
@ -34,122 +33,116 @@ function findTemplate() {
return PROJECT_TEMPLATE; return PROJECT_TEMPLATE;
} }
const config = webpackMerge(preset, { config.target('web');
target: 'web', config.output.publicPath('./');
node: { config.resolve.modules.add(MODULES);
console: false, config.resolveLoader.modules.add(MODULES);
global: true,
process: true,
Buffer: true,
__filename: 'mock',
__dirname: 'mock',
setImmediate: true,
fs: 'empty',
tls: 'empty'
},
output: {
publicPath: './'
},
plugins: [
new webpack.EnvironmentPlugin(['NODE_ENV']),
new HtmlPlugin({
template: findTemplate(),
inject: 'body',
xhtml: true
})
],
resolve: {
modules: [MODULES]
},
resolveLoader: {
modules: [MODULES]
},
module: {
rules: [
{
test: /\.html$/,
use: {
loader: FILE_LOADER,
options: {
name: '[name].[ext]'
}
}
},
{
test: /\.css$/,
loaders: [STYLE_LOADER, CSS_LOADER]
},
{
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: URL_LOADER,
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: URL_LOADER,
options: {
limit: '10000',
mimetype: 'application/octet-stream'
}
}
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: FILE_LOADER
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: URL_LOADER,
options: {
limit: '10000',
mimetype: 'application/svg+xml'
}
}
},
{
test: /\.(png|jpg)$/,
use: {
loader: URL_LOADER,
options: {
limit: 8192
}
}
},
{
test: /\.ico(\?v=\d+\.\d+\.\d+)?$/,
use: URL_LOADER
}
]
}
});
const babelLoader = config.module.rules.find(r => r.use && r.use.loader && r.use.loader.includes('babel')); 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');
// Polyfill based on last 2 major browser versions config.module
babelLoader.use.options.presets[0][1].targets.browsers = ['last 2 versions']; .rule('html')
.test(/\.html$/)
.loader('file', FILE_LOADER, {
name: '[name].[ext]'
});
const eslintLoader = config.module.rules.find(r => r.use && r.use.loader && r.use.loader.includes('eslint')); config.module
.rule('css')
.test(/\.css$/)
.loader('style', STYLE_LOADER)
.loader('css', CSS_LOADER);
eslintLoader.use.options = merge(eslintLoader.use.options, { config.module
globals: ['Buffer'], .rule('woff')
env: { .test(/\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/)
browser: true, .loader('url', URL_LOADER, {
commonjs: true limit: '10000',
} mimetype: 'application/font-woff'
}); });
config.module
.rule('ttf')
.test(/\.ttf(\?v=\d+\.\d+\.\d+)?$/)
.loader('url', URL_LOADER, {
limit: '10000',
mimetype: 'application/octet-stream'
});
config.module
.rule('eot')
.test(/\.eot(\?v=\d+\.\d+\.\d+)?$/)
.loader('file', FILE_LOADER);
config.module
.rule('svg')
.test(/\.svg(\?v=\d+\.\d+\.\d+)?$/)
.loader('url', URL_LOADER, {
limit: '10000',
mimetype: 'application/svg+xml'
});
config.module
.rule('img')
.test(/\.(png|jpg)$/)
.loader('url', URL_LOADER, {
limit: 8192
});
config.module
.rule('ico')
.test(/\.ico(\?v=\d+\.\d+\.\d+)?$/)
.loader('url', URL_LOADER);
// modify the babel loader
config.module
.rule('compile')
.loader('babel', ({ options }) => {
options.presets[0][1].targets.browsers = ['last 2 versions'];
return { options };
});
// modify the lint loader
config.module
.rule('lint')
.loader('eslint', ({ options }) => {
return {
options: merge(options, {
globals: ['Buffer'],
envs: ['browser', 'commonjs']
})
};
});
config
.plugin('env')
.use(webpack.EnvironmentPlugin, ['NODE_ENV']);
config
.plugin('html')
.use(HtmlPlugin, {
template: findTemplate(),
inject: 'body',
xhtml: true
});
if (process.env.NODE_ENV !== 'test') { if (process.env.NODE_ENV !== 'test') {
config.plugins.push(new webpack.optimize.CommonsChunkPlugin({ config
names: ['vendor', 'manifest'], .plugin('chunk')
minChunks: Infinity .use(webpack.optimize.CommonsChunkPlugin, {
})); names: ['vendor', 'manifest'],
minChunks: Infinity
});
} }
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
@ -157,67 +150,82 @@ if (process.env.NODE_ENV === 'development') {
const host = process.env.HOST || 'localhost'; const host = process.env.HOST || 'localhost';
const port = parseInt(process.env.PORT) || 5000; const port = parseInt(process.env.PORT) || 5000;
config.devServer = { config
host, .devServer
port, .host(host)
https: protocol === 'https', .port(port)
contentBase: SRC, .https(protocol === 'https')
// Enable history API fallback so HTML5 History API based .contentBase(SRC)
// routing works. This is a good default that will come .historyApiFallback(true)
// in handy in more complicated setups. .stats({
historyApiFallback: true,
stats: {
colors: true,
chunks: false,
version: false,
assets: false, assets: false,
modules: false,
children: false, children: false,
source: false chunks: false,
} colors: true,
}; errors: true,
errorDetails: true,
hash: false,
modules: false,
publicPath: false,
timings: false,
version: false,
warnings: true
});
config
.entry('index')
.add(`webpack-dev-server/client?${protocol}://${host}:${port}/`)
.add('webpack/hot/dev-server');
config.entry.index.push(`webpack-dev-server/client?${protocol}://${host}:${port}/`); config
config.entry.index.push(`webpack/hot/dev-server`); .plugin('hot')
config.plugins.push(new webpack.HotModuleReplacementPlugin()); .use(webpack.HotModuleReplacementPlugin);
} else if (process.env.NODE_ENV === 'production') { } else if (process.env.NODE_ENV === 'production') {
config.plugins.push( config
new webpack.optimize.UglifyJsPlugin({ sourceMap: false, compress: { warnings: false }}), .plugin('minify')
new webpack.LoaderOptionsPlugin({ minimize: true }) .use(webpack.optimize.UglifyJsPlugin, {
); sourceMap: false,
compress: { warnings: false }
});
config
.plugin('minimize')
.use(webpack.LoaderOptionsPlugin, { minimize: true });
} else if (process.env.NODE_ENV === 'test') { } else if (process.env.NODE_ENV === 'test') {
config.karma = { config
plugins: [ .options
require.resolve('karma-webpack'), .set('karma', {
require.resolve('karma-chrome-launcher'), plugins: [
require.resolve('karma-coverage'), require.resolve('karma-webpack'),
require.resolve('karma-mocha'), require.resolve('karma-chrome-launcher'),
require.resolve('karma-mocha-reporter') require.resolve('karma-coverage'),
], require.resolve('karma-mocha'),
basePath: process.cwd(), require.resolve('karma-mocha-reporter')
browsers: [process.env.CI ? 'ChromeCI' : 'Chrome'], ],
customLaunchers: { basePath: process.cwd(),
ChromeCI: { browsers: [process.env.CI ? 'ChromeCI' : 'Chrome'],
base: 'Chrome', customLaunchers: {
flags: ['--no-sandbox'] ChromeCI: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
frameworks: ['mocha'],
files: ['test/**/*_test.js'],
preprocessors: {
'test/**/*_test.js': ['webpack'],
'src/**/*.js': ['webpack']
},
webpackMiddleware: { noInfo: true },
reporters: ['mocha', 'coverage'],
coverageReporter: {
dir: '.coverage',
reporters: [
{ type: 'html', subdir: 'report-html' },
{ type: 'lcov', subdir: 'report-lcov' }
]
} }
}, });
frameworks: ['mocha'],
files: ['test/**/*_test.js'],
preprocessors: {
'test/**/*_test.js': ['webpack'],
'src/**/*.js': ['webpack']
},
webpackMiddleware: { noInfo: true },
reporters: ['mocha', 'coverage'],
coverageReporter: {
dir: '.coverage',
reporters: [
{ type: 'html', subdir: 'report-html' },
{ type: 'lcov', subdir: 'report-lcov' }
]
}
};
} }
module.exports = config; module.exports = config;

8
packages/neutrino-preset-web/yarn.lock

@ -523,8 +523,8 @@ clap@^1.0.9:
chalk "^1.1.3" chalk "^1.1.3"
clean-css@4.0.x: clean-css@4.0.x:
version "4.0.3" version "4.0.4"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.0.3.tgz#9da7b59301d940c345757f175e6dfa6872c7de8e" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.0.4.tgz#629896cc364f3c3d00b9908ee60dd18e4c6c6462"
dependencies: dependencies:
source-map "0.5.x" source-map "0.5.x"
@ -1435,7 +1435,7 @@ glob-parent@^2.0.0:
dependencies: dependencies:
is-glob "^2.0.0" is-glob "^2.0.0"
glob@7.0.5, glob@^7.0.5: glob@7.0.5:
version "7.0.5" version "7.0.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95"
dependencies: dependencies:
@ -1456,7 +1456,7 @@ glob@^5.0.15:
once "^1.3.0" once "^1.3.0"
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
glob@^7.1.1: glob@^7.0.5, glob@^7.1.1:
version "7.1.1" version "7.1.1"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
dependencies: dependencies:

10
packages/neutrino/src/get-preset.js

@ -26,11 +26,13 @@ module.exports = (preset) => {
// try requiring it as relative to the project // try requiring it as relative to the project
for (let i = 0; i < modules.length; i++) { for (let i = 0; i < modules.length; i++) {
try { try {
const config = require(modules[i]); const module = require(modules[i]);
const core = 'toConfig' in module ? module.toConfig() : module;
const config = pkg.config && pkg.config.neutrino ?
merge(core, pkg.config.neutrino) :
core;
return pkg.config && pkg.config.neutrino ? return config;
merge(config, pkg.config.neutrino) :
config;
} catch (err) { } catch (err) {
if (!/Cannot find module/.test(err.message)) { if (!/Cannot find module/.test(err.message)) {
throw err; throw err;

18
packages/neutrino/yarn.lock

@ -805,7 +805,7 @@ date-now@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
debug@2.2.0, debug@^2.0.0, debug@^2.1.1, debug@~2.2.0: debug@2.2.0, debug@~2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
dependencies: dependencies:
@ -817,7 +817,7 @@ debug@2.3.3:
dependencies: dependencies:
ms "0.7.2" ms "0.7.2"
debug@2.6.0, debug@^2.2.0: debug@2.6.0, debug@^2.0.0, debug@^2.1.1, debug@^2.2.0:
version "2.6.0" version "2.6.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b"
dependencies: dependencies:
@ -2149,10 +2149,14 @@ oauth-sign@~0.8.1:
version "0.8.2" version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
object-assign@4.1.0, object-assign@^4.0.1, object-assign@^4.1.0: object-assign@4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0"
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
object-component@0.0.3: object-component@0.0.3:
version "0.0.3" version "0.0.3"
resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291"
@ -2947,7 +2951,7 @@ strip-json-comments@~1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"
supports-color@3.1.2, supports-color@^3.1.0, supports-color@^3.1.1: supports-color@3.1.2:
version "3.1.2" version "3.1.2"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
dependencies: dependencies:
@ -2961,6 +2965,12 @@ supports-color@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
supports-color@^3.1.0, supports-color@^3.1.1:
version "3.2.3"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
dependencies:
has-flag "^1.0.0"
swap-case@^1.1.0: swap-case@^1.1.0:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3" resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3"

Loading…
Cancel
Save