diff --git a/packages/neutrino-middleware-font-loader/index.js b/packages/neutrino-middleware-font-loader/index.js index ef5770a..e5800bd 100644 --- a/packages/neutrino-middleware-font-loader/index.js +++ b/packages/neutrino-middleware-font-loader/index.js @@ -10,18 +10,19 @@ module.exports = ({ config }, options) => { .test(/\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/) .use('url') .loader(urlLoader) - .options({ limit, mimetype: 'application/font-woff' }); + .options(merge({ limit, mimetype: 'application/font-woff' }, options.woff || {})); config.module .rule('ttf') .test(/\.ttf(\?v=\d+\.\d+\.\d+)?$/) .use('url') .loader(urlLoader) - .options({ limit, mimetype: 'application/octet-stream' }); + .options(merge({ limit, mimetype: 'application/octet-stream' }, options.ttf || {})); config.module .rule('eot') .test(/\.eot(\?v=\d+\.\d+\.\d+)?$/) .use('file') - .loader(fileLoader); + .loader(fileLoader) + .when(options.eot, use => use.options(options.eot)); }; diff --git a/packages/neutrino-middleware-html-loader/index.js b/packages/neutrino-middleware-html-loader/index.js index 6897899..61216a1 100644 --- a/packages/neutrino-middleware-html-loader/index.js +++ b/packages/neutrino-middleware-html-loader/index.js @@ -1,6 +1,8 @@ -module.exports = ({ config }) => config.module +const merge = require('deepmerge'); + +module.exports = ({ config }, options) => config.module .rule('html') .test(/\.html$/) .use('file') .loader(require.resolve('file-loader')) - .options({ name: '[name].[ext]' }); + .options(merge({ name: '[name].[ext]' }, options)); diff --git a/packages/neutrino-middleware-html-loader/package.json b/packages/neutrino-middleware-html-loader/package.json index 76e8bc3..3f5dc81 100644 --- a/packages/neutrino-middleware-html-loader/package.json +++ b/packages/neutrino-middleware-html-loader/package.json @@ -14,6 +14,7 @@ "homepage": "https://neutrino.js.org", "bugs": "https://github.com/mozilla-neutrino/neutrino-dev/issues", "dependencies": { + "deepmerge": "^1.3.2", "file-loader": "^0.10.1" }, "peerDependencies": { diff --git a/packages/neutrino-middleware-html-loader/yarn.lock b/packages/neutrino-middleware-html-loader/yarn.lock index 1397131..8c44240 100644 --- a/packages/neutrino-middleware-html-loader/yarn.lock +++ b/packages/neutrino-middleware-html-loader/yarn.lock @@ -6,6 +6,10 @@ big.js@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" +deepmerge@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.3.2.tgz#1663691629d4dbfe364fa12a2a4f0aa86aa3a050" + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" diff --git a/packages/neutrino-middleware-image-loader/index.js b/packages/neutrino-middleware-image-loader/index.js index c210c81..635960c 100644 --- a/packages/neutrino-middleware-image-loader/index.js +++ b/packages/neutrino-middleware-image-loader/index.js @@ -10,18 +10,19 @@ module.exports = ({ config }, options) => { .test(/\.svg(\?v=\d+\.\d+\.\d+)?$/) .use('url') .loader(svgUrlLoader) - .options({ limit }); + .options(merge({ limit }, options.svg || {})); config.module .rule('img') .test(/\.(png|jpg|jpeg|gif)$/) .use('url') .loader(urlLoader) - .options({ limit }); + .options(merge({ limit }, options.img || {})); config.module .rule('ico') .test(/\.ico(\?v=\d+\.\d+\.\d+)?$/) .use('url') - .loader(urlLoader); + .loader(urlLoader) + .when(options.ico, use => use.options(options.ico)); }; diff --git a/packages/neutrino-middleware-minify/index.js b/packages/neutrino-middleware-minify/index.js index e1aaef3..0ac633f 100644 --- a/packages/neutrino-middleware-minify/index.js +++ b/packages/neutrino-middleware-minify/index.js @@ -1,3 +1,6 @@ const BabiliPlugin = require('babili-webpack-plugin'); -module.exports = ({ config }) => config.plugin('minify').use(BabiliPlugin); +module.exports = ({ config }, options) => config + .plugin('minify') + .use(BabiliPlugin) + .when(options, plugin => plugin.tap(() => [options])); diff --git a/packages/neutrino-middleware-style-loader/index.js b/packages/neutrino-middleware-style-loader/index.js index ba95fa1..1aee0f9 100644 --- a/packages/neutrino-middleware-style-loader/index.js +++ b/packages/neutrino-middleware-style-loader/index.js @@ -1,8 +1,10 @@ -module.exports = ({ config }) => config.module +module.exports = ({ config }, options) => config.module .rule('style') - .test(/\.css$/) - .use('style') - .loader(require.resolve('style-loader')) - .end() - .use('css') - .loader(require.resolve('css-loader')); + .test(/\.css$/) + .use('style') + .loader(require.resolve('style-loader')) + .when(options.style, use => use.options(options.style)) + .end() + .use('css') + .loader(require.resolve('css-loader')) + .when(options.css, use => use.options(options.css)); diff --git a/packages/neutrino/src/api.js b/packages/neutrino/src/api.js index 670215d..8cfb816 100644 --- a/packages/neutrino/src/api.js +++ b/packages/neutrino/src/api.js @@ -11,15 +11,65 @@ const start = require('./start'); const test = require('./test'); const getOptions = (options = {}) => { - const root = normalizePath(process.cwd(), defaultTo('', options.root)); - const base = normalizePath(root); - const source = base(defaultTo('src', options.source)); - const output = base(defaultTo('build', options.output)); - const tests = base(defaultTo('test', options.tests)); - const node_modules = base(defaultTo('node_modules', options.node_modules)); // eslint-disable-line camelcase - const entry = normalizePath(source, defaultTo('index.js', options.entry)); + let root = defaultTo('', options.root); + let source = defaultTo('src', options.source); + let output = defaultTo('build', options.output); + let tests = defaultTo('test', options.tests); + let node_modules = defaultTo('node_modules', options.node_modules); // eslint-disable-line camelcase + let entry = defaultTo('index.js', options.entry); - return merge(options, { root, source, output, tests, node_modules, entry }); + Object.defineProperties(options, { + root: { + get() { + return normalizePath(process.cwd(), root); + }, + set(value) { + root = defaultTo('', value); + } + }, + source: { + get() { + return normalizePath(this.root, source); + }, + set(value) { + source = defaultTo('src', value); + } + }, + output: { + get() { + return normalizePath(this.root, output); + }, + set(value) { + output = defaultTo('build', value); + } + }, + tests: { + get() { + return normalizePath(this.root, tests); + }, + set(value) { + tests = defaultTo('test', value); + } + }, + node_modules: { + get() { + return normalizePath(this.root, node_modules); + }, + set(value) { + node_modules = defaultTo('node_modules', value); // eslint-disable-line camelcase + } + }, + entry: { + get() { + return normalizePath(this.source, entry); + }, + set(value) { + entry = defaultTo('index.js', value); + } + } + }); + + return options; }; // Api :: () -> Object diff --git a/packages/neutrino/test/api_test.js b/packages/neutrino/test/api_test.js index 8eba51f..dfde6e0 100644 --- a/packages/neutrino/test/api_test.js +++ b/packages/neutrino/test/api_test.js @@ -1,5 +1,6 @@ import test from 'ava'; import { Neutrino } from '../src'; +import { join } from 'path'; test('initializes with no arguments', t => { t.notThrows(() => Neutrino()); @@ -18,6 +19,78 @@ test('initialization stores options', t => { t.is(api.options.gamma, options.gamma); }); +test('options.root', t => { + const api = Neutrino(); + + t.is(api.options.root, process.cwd()); + api.options.root = './alpha'; + t.is(api.options.root, join(process.cwd(), 'alpha')); + api.options.root = '/alpha'; + t.is(api.options.root, '/alpha'); +}); + +test('options.source', t => { + const api = Neutrino(); + + t.is(api.options.source, join(process.cwd(), 'src')); + api.options.source = './alpha'; + t.is(api.options.source, join(process.cwd(), 'alpha')); + api.options.root = '/beta'; + t.is(api.options.source, join('/beta', 'alpha')); + api.options.source = '/alpha'; + t.is(api.options.source, '/alpha'); +}); + +test('options.output', t => { + const api = Neutrino(); + + t.is(api.options.output, join(process.cwd(), 'build')); + api.options.output = './alpha'; + t.is(api.options.output, join(process.cwd(), 'alpha')); + api.options.root = '/beta'; + t.is(api.options.output, join('/beta', 'alpha')); + api.options.output = '/alpha'; + t.is(api.options.output, '/alpha'); +}); + +test('options.tests', t => { + const api = Neutrino(); + + t.is(api.options.tests, join(process.cwd(), 'test')); + api.options.tests = './alpha'; + t.is(api.options.tests, join(process.cwd(), 'alpha')); + api.options.root = '/beta'; + t.is(api.options.tests, join('/beta', 'alpha')); + api.options.tests = '/alpha'; + t.is(api.options.tests, '/alpha'); +}); + +test('options.node_modules', t => { + const api = Neutrino(); + + t.is(api.options.node_modules, join(process.cwd(), 'node_modules')); + api.options.node_modules = './alpha'; + t.is(api.options.node_modules, join(process.cwd(), 'alpha')); + api.options.root = '/beta'; + t.is(api.options.node_modules, join('/beta', 'alpha')); + api.options.node_modules = '/alpha'; + t.is(api.options.node_modules, '/alpha'); +}); + +test('options.entry', t => { + const api = Neutrino(); + + t.is(api.options.entry, join(process.cwd(), 'src/index.js')); + api.options.entry = './alpha.js'; + t.is(api.options.entry, join(process.cwd(), 'src/alpha.js')); + api.options.source = 'beta'; + t.is(api.options.entry, join(process.cwd(), 'beta/alpha.js')); + api.options.root = '/gamma'; + t.is(api.options.entry, join('/gamma', 'beta/alpha.js')); + api.options.entry = '/alpha.js'; + t.is(api.options.entry, '/alpha.js'); +}); + test('creates an instance of webpack-chain', t => { const api = Neutrino();