diff --git a/.gitignore b/.gitignore index f105689..6533715 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ lib build package-lock.json yarn.lock +.vscode diff --git a/examples/web-app-react/simple/package.json b/examples/web-app-react/simple/package.json index 616e4fb..12d4562 100755 --- a/examples/web-app-react/simple/package.json +++ b/examples/web-app-react/simple/package.json @@ -6,7 +6,7 @@ "author": "Schibsted", "license": "MIT", "scripts": { - "dev": "roc dev --runtime-applicationName 'Simple Example'" + "dev": "roc dev" }, "dependencies": { "roc-package-web-app-react": "^2.0.0" diff --git a/examples/web-app-react/simple/roc.config.js b/examples/web-app-react/simple/roc.config.js new file mode 100644 index 0000000..9bbf8c1 --- /dev/null +++ b/examples/web-app-react/simple/roc.config.js @@ -0,0 +1,10 @@ +module.exports = { + settings: { + runtime: { + applicationName: 'Simple Example', + }, + build: { + routes: 'routes.js', + }, + }, +}; diff --git a/package.json b/package.json index cdf4d88..133374b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "eslint-plugin-jsx-a11y": "2.2.1", "eslint-plugin-react": "6.2.0", "roc": "^1.0.0-rc.23", - "roc-plugin-repo": "0.0.25", + "roc-plugin-repo": "0.0.28", "roc-plugin-repo-roc": "0.0.1" } } diff --git a/packages/roc-package-web-app-react-dev/src/webpack/index.js b/packages/roc-package-web-app-react-dev/src/webpack/index.js index 6d0a986..511e8f4 100644 --- a/packages/roc-package-web-app-react-dev/src/webpack/index.js +++ b/packages/roc-package-web-app-react-dev/src/webpack/index.js @@ -138,7 +138,7 @@ export default ({ }) ); - newWebpackConfig.resolveLoader.root.push(join(__dirname, '..', '..', 'node_modules')); + newWebpackConfig.resolveLoader.modules.push(join(__dirname, '..', '..', 'node_modules')); return newWebpackConfig; }; diff --git a/packages/roc-package-webpack-dev/package.json b/packages/roc-package-webpack-dev/package.json index 11d12e3..15049b6 100644 --- a/packages/roc-package-webpack-dev/package.json +++ b/packages/roc-package-webpack-dev/package.json @@ -38,8 +38,8 @@ "roc": "^1.0.0-rc.23", "roc-abstract-package-base-dev": "^1.0.0", "roc-plugin-babel": "^1.0.0", - "webpack": "~1.12.2", - "webpack-merge": "0.14.0" + "webpack": "~3.10.0", + "webpack-merge": "~4.1.1" }, "roc": { "packages": [ diff --git a/packages/roc-package-webpack-dev/src/actions/build.js b/packages/roc-package-webpack-dev/src/actions/build.js index 4f5ece0..c937f43 100644 --- a/packages/roc-package-webpack-dev/src/actions/build.js +++ b/packages/roc-package-webpack-dev/src/actions/build.js @@ -118,7 +118,13 @@ export default ({ context: { verbose, config: { settings } } }) => (targets) => const promises = validTargets.map((target) => { const babelConfig = invokeHook('babel-config', target); - const webpackConfig = invokeHook('build-webpack', target, babelConfig); + /* eslint-disable no-unused-vars */ + const { rocMetaInfo: _, ...webpackConfig } = invokeHook( + 'build-webpack', + target, + babelConfig, + ); + /* eslint-enable no-unused-vars */ return build(webpackConfig, target, settings, verbose); }); diff --git a/packages/roc-package-webpack-dev/src/actions/dev.js b/packages/roc-package-webpack-dev/src/actions/dev.js index 39e7cdc..6d4a3fd 100644 --- a/packages/roc-package-webpack-dev/src/actions/dev.js +++ b/packages/roc-package-webpack-dev/src/actions/dev.js @@ -31,17 +31,17 @@ const writeStatsFile = (buildPath, scriptPath) => }); }); -const createWatcher = (verbose, settings, target, webpackConfig, watcher) => { +const createWatcher = (verbose, settings, target, webpackConfig, rocMetaInfo, watcher) => { // Resolve directly if we did not get a webpackConfig back if (!webpackConfig) { return Promise.resolve(); } - return cleanPromise(webpackConfig.rocMetaInfo.outputPath) + return cleanPromise(rocMetaInfo.outputPath) .then(async function watch() { const compiler = webpack(webpackConfig); await writeStatsFile(webpackConfig.output.path, webpackConfig.output.publicPath + - webpackConfig.output.filename.replace(/\[name\]/, webpackConfig.rocMetaInfo.outputName)); + webpackConfig.output.filename.replace(/\[name\]/, rocMetaInfo.outputName)); if (!watcher[target]) { return Promise.resolve(); @@ -90,7 +90,11 @@ export default ({ context: { verbose, config: { settings } } }) => (targets) => // Build each one in order return Promise.all(targets.map(async function builders(target) { const babelConfig = invokeHook('babel-config', target); - const webpackConfig = invokeHook('build-webpack', target, babelConfig); - return await createWatcher(verbose, newSettings, target, webpackConfig, watchers); + const { rocMetaInfo, ...webpackConfig } = invokeHook( + 'build-webpack', + target, + babelConfig, + ); + return await createWatcher(verbose, newSettings, target, webpackConfig, rocMetaInfo, watchers); })); }; diff --git a/packages/roc-package-webpack-dev/src/roc/index.js b/packages/roc-package-webpack-dev/src/roc/index.js index cec76df..b3440ff 100644 --- a/packages/roc-package-webpack-dev/src/roc/index.js +++ b/packages/roc-package-webpack-dev/src/roc/index.js @@ -28,7 +28,7 @@ export default { const targets = invokeHook('get-webpack-targets'); if (targets.indexOf(target) !== -1) { babelConfig.presets.push( - require.resolve('babel-preset-es2015'), + [require.resolve('babel-preset-es2015'), { modules: false }], require.resolve('babel-preset-stage-1') ); babelConfig.plugins.push( diff --git a/packages/roc-package-webpack-dev/src/webpack/index.js b/packages/roc-package-webpack-dev/src/webpack/index.js index b72c96e..2eab2a3 100644 --- a/packages/roc-package-webpack-dev/src/webpack/index.js +++ b/packages/roc-package-webpack-dev/src/webpack/index.js @@ -83,44 +83,37 @@ export default () => (target, babelConfig) => (webpackConfig = {}) => { // Base newWebpackConfig.module = { - preLoaders: [], - loaders: [], + rules: [], }; // JS LOADER const jsLoader = { - id: 'babel', test: /\.js$/, - loader: require.resolve('babel-loader'), - query: { - ...babelConfig, - cacheDirectory: true, - }, include: runThroughBabel, + use: [{ + loader: require.resolve('babel-loader'), + options: { + ...babelConfig, + cacheDirectory: true, + }, + }], }; - newWebpackConfig.module.loaders.push(jsLoader); - - // JSON LOADER - const jsonLoader = { - test: /\.json$/, - loader: require.resolve('json-loader'), - }; - - newWebpackConfig.module.loaders.push(jsonLoader); + newWebpackConfig.module.rules.push(jsLoader); /** * Resolve */ newWebpackConfig.resolve = { - fallback: [], - extensions: ['', '.js'], + extensions: ['.js'], + modules: ['node_modules'], + alias: {}, }; newWebpackConfig.resolveLoader = { - root: [ - join(__dirname, '..', '..', 'node_modules'), - ], + modules: ['node_modules', join(__dirname, '..', '..', 'node_modules')], + extensions: ['.js', '.json'], + mainFields: ['loader', 'main'], }; /** @@ -147,7 +140,7 @@ export default () => (target, babelConfig) => (webpackConfig = {}) => { newWebpackConfig.plugins.push( new webpack.optimize.DedupePlugin(), - new webpack.optimize.OccurenceOrderPlugin() + new webpack.optimize.OccurrenceOrderPlugin() ); } diff --git a/packages/roc-package-webpack-dev/src/webpack/utils/rocExportWebpackPlugin.js b/packages/roc-package-webpack-dev/src/webpack/utils/rocExportWebpackPlugin.js index e107f71..c488690 100644 --- a/packages/roc-package-webpack-dev/src/webpack/utils/rocExportWebpackPlugin.js +++ b/packages/roc-package-webpack-dev/src/webpack/utils/rocExportWebpackPlugin.js @@ -6,91 +6,148 @@ export default class RocExportPlugin { } apply(compiler) { - const getAlias = createGetAlias(compiler.options.resolve.alias); // eslint-disable-line + const getAlias = createGetAlias(compiler.options.resolve.alias); const resolveRequest = this.resolveRequest; // Create a random identifer that can be used to detect when our resolver is called // recusively so we can prevent an infinite loop - const recursiveIdentifier = `?rocExportWebpackPlugin=${Math.floor(Math.random() * 10 * 10000)}`; - const createResolver = (resolver) => - (request, context, callback) => resolver(context, request + recursiveIdentifier, callback); - - // We assume that loaders will be managed in Webpack-land, meaning that we will not manage - // them using exports in Roc - compiler.resolvers.normal.plugin('module', function rocExportWebpackPlugin(result, next) { - if (result.query === recursiveIdentifier) { - return next(); - } - - let request = result.request; - - // Use resolve.alias to use the alias if one exists and match - const beforeAlias = request; - request = getAlias(request); - const afterAlias = request; - - // Create resolver that works with Roc - const resolver = createResolver(this.resolve); - - // Try to resolve the dependency against the roc dependency context - return resolveRequest(request, result.path, { resolver }, (err, newRequest) => { - // If we failed to resolve we want to propagate the error - if (err) { - return next(err); - } - - // Remove recursiveIdentifier if present - newRequest = newRequest.replace(recursiveIdentifier, ''); // eslint-disable-line - - return this.resolve(result.path, newRequest + recursiveIdentifier, (error) => { - if (error) { - // We got an error and will try again with fallback enabled - return resolveRequest( - request, - result.path, - { fallback: true, resolver }, - (fallbackError, newRequestFallback) => { - if (fallbackError) { - return next(fallbackError); - } - - // Remove recursiveIdentifier if present - newRequestFallback = newRequestFallback.replace(recursiveIdentifier, ''); // eslint-disable-line - - // If we have not changed the request we want to revert the alias change - request = newRequestFallback === afterAlias ? beforeAlias : newRequestFallback; - - // Update the resolving with the new value if the request was modified - if (request !== result.request) { - return this.doResolve('file', { ...result, request }, next); - } - - // Do nothing and just pass through - return next(); - } - ); + const recursiveIdentifier = `?rocExportWebpackPlugin=${Math.floor( + Math.random() * 10 * 10000, + )}`; + const createResolver = (resolver, webpackContext = {}) => ( + request, + context, + callback, + ) => + resolver( + webpackContext, + context, + request + recursiveIdentifier, + callback, + ); + + compiler.plugin('after-resolvers', afterResolversCompiler => { + // We assume that loaders will be managed in Webpack-land, meaning that we will not manage + // them using exports in Roc + afterResolversCompiler.resolvers.normal.plugin( + 'module', + function rocExportWebpackPlugin(result, next) { + if (result.query === recursiveIdentifier) { + return next(); } - // If we have not changed the request we want to revert the alias change - request = newRequest === afterAlias ? beforeAlias : newRequest; - - // Update the resolving with the new value if the request was modified - if (request !== result.request) { - return this.doResolve('file', { ...result, request }, next); - } + let request = result.request; + + // Use resolve.alias to use the alias if one exists and match + const beforeAlias = request; + request = getAlias(request); + const afterAlias = request; + + // Create resolver that works with Roc + const resolver = createResolver( + this.resolve.bind(this), + result.context, + ); + + // Try to resolve the dependency against the roc dependency context + return resolveRequest( + request, + result.path, + { resolver }, + (err, newRequest) => { + // If we failed to resolve we want to propagate the error + if (err) { + return next(err); + } - // Do nothing and just pass through - return next(); - }); - }); + // Remove recursiveIdentifier if present + newRequest = newRequest.replace( + recursiveIdentifier, + '', + ); // eslint-disable-line + + return this.resolve( + result.context || {}, + result.path, + newRequest + recursiveIdentifier, + error => { + if (error) { + // We got an error and will try again with fallback enabled + return resolveRequest( + request, + result.path, + { fallback: true, resolver }, + ( + fallbackError, + newRequestFallback, + ) => { + if (fallbackError) { + return next(fallbackError); + } + + // Remove recursiveIdentifier if present + newRequestFallback = newRequestFallback.replace( + recursiveIdentifier, + '', + ); // eslint-disable-line + + // If we have not changed the request we want to revert the alias change + request = + newRequestFallback === + afterAlias + ? beforeAlias + : newRequestFallback; + + // Update the resolving with the new value if the request was modified + if ( + request !== result.request + ) { + return this.doResolve( + 'resolve', + { ...result, request }, + '', + next, + ); + } + + // Do nothing and just pass through + return next(); + }, + ); + } + + // If we have not changed the request we want to revert the alias change + request = + newRequest === afterAlias + ? beforeAlias + : newRequest; + + // Update the resolving with the new value if the request was modified + if (request !== result.request) { + return this.doResolve( + 'resolve', + { ...result, request }, + '', + next, + ); + } + + // Do nothing and just pass through + return next(); + }, + ); + }, + ); + }, + ); }); } } - // Based on code from enhanced-resolve function createGetAlias(aliases) { if (isPlainObject(aliases) && !Array.isArray(aliases)) { - aliases = Object.keys(aliases).map((key) => { // eslint-disable-line + aliases = Object.keys(aliases).map(key => { + // eslint-disable-line let onlyModule = false; let obj = aliases[key]; if (/\$$/.test(key)) { @@ -110,10 +167,18 @@ function createGetAlias(aliases) { }); } - return (request) => { + return request => { + // eslint-disable-next-line no-restricted-syntax for (const alias of aliases) { - if ((!alias.onlyModule && request.indexOf(`${alias.name}/`) === 0) || request === alias.name) { - if (request.indexOf(`${alias.alias}/`) !== 0 && request !== alias.alias) { + if ( + (!alias.onlyModule && + request.indexOf(`${alias.name}/`) === 0) || + request === alias.name + ) { + if ( + request.indexOf(`${alias.alias}/`) !== 0 && + request !== alias.alias + ) { return alias.alias + request.substr(alias.name.length); } } diff --git a/packages/roc-package-webpack-node-dev/src/webpack/index.js b/packages/roc-package-webpack-node-dev/src/webpack/index.js index 1e3f9ee..591758a 100644 --- a/packages/roc-package-webpack-node-dev/src/webpack/index.js +++ b/packages/roc-package-webpack-node-dev/src/webpack/index.js @@ -74,7 +74,7 @@ export default ({ previousValue: webpackConfig }) => (target) => { if (DEV) { newWebpackConfig.plugins.push( - new webpack.NoErrorsPlugin() + new webpack.NoEmitOnErrorsPlugin() ); } diff --git a/packages/roc-package-webpack-web-dev/package.json b/packages/roc-package-webpack-web-dev/package.json index 4895d79..bbbb493 100644 --- a/packages/roc-package-webpack-web-dev/package.json +++ b/packages/roc-package-webpack-web-dev/package.json @@ -30,7 +30,8 @@ "roc": "^1.0.0-rc.23", "roc-package-webpack-dev": "^1.1.0-alpha.0", "webpack": "~1.12.2", - "webpack-hot-middleware": "~2.10.0" + "webpack-hot-middleware": "~2.10.0", + "uglifyjs-webpack-plugin": "~1.1.6" }, "roc": { "packages": [ diff --git a/packages/roc-package-webpack-web-dev/src/webpack/index.js b/packages/roc-package-webpack-web-dev/src/webpack/index.js index c9fcec0..8921a18 100644 --- a/packages/roc-package-webpack-web-dev/src/webpack/index.js +++ b/packages/roc-package-webpack-web-dev/src/webpack/index.js @@ -4,6 +4,7 @@ import { getDevPath } from 'roc-package-webpack-dev'; import { getSettings, getAbsolutePath } from 'roc'; import qs from 'qs'; import webpack from 'webpack'; +import UglifyJsPlugin from 'uglifyjs-webpack-plugin'; export default ({ previousValue: webpackConfig }) => (target) => { if (target === 'web') { @@ -55,10 +56,10 @@ export default ({ previousValue: webpackConfig }) => (target) => { */ if (DEV) { // To make sure the client can resolve webpack-hot-middleware correctly - newWebpackConfig.resolve.fallback.push(path.join(__dirname, '..', '..', 'node_modules')); + newWebpackConfig.resolve.modules.push(path.join(__dirname, '..', '..', 'node_modules')); } - newWebpackConfig.resolveLoader.root.push( + newWebpackConfig.resolveLoader.modules.push( path.join(__dirname, '..', '..', 'node_modules') ); @@ -74,29 +75,21 @@ export default ({ previousValue: webpackConfig }) => (target) => { if (DEV) { newWebpackConfig.plugins.push( - new webpack.optimize.OccurenceOrderPlugin(), + new webpack.optimize.OccurrenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), - new webpack.NoErrorsPlugin() + new webpack.NoEmitOnErrorsPlugin() ); } if (DIST) { newWebpackConfig.plugins.push( - new webpack.optimize.UglifyJsPlugin({ - /* eslint-disable */ - compress: { - warnings: false, - screw_ie8: true, - drop_debugger: true + new UglifyJsPlugin({ + uglifyOptions: { + ie8: false, + ecma: 8, + mangle: true, + compress: true, }, - managle: { - screw_ie8: true, - }, - output: { - comments: false, - screw_ie8: true, - } - /* eslint-enable */ }) ); } diff --git a/plugins/roc-plugin-assets-images/package.json b/plugins/roc-plugin-assets-images/package.json index 7f159b2..41a5cac 100644 --- a/plugins/roc-plugin-assets-images/package.json +++ b/plugins/roc-plugin-assets-images/package.json @@ -26,7 +26,6 @@ "license": "MIT", "dependencies": { "file-loader": "~0.8.5", - "qs": "~6.2.0", "roc": "^1.0.0-rc.23", "url-loader": "~0.5.7" }, diff --git a/plugins/roc-plugin-assets-images/src/images/index.js b/plugins/roc-plugin-assets-images/src/images/index.js index dc634bf..edc3bd8 100644 --- a/plugins/roc-plugin-assets-images/src/images/index.js +++ b/plugins/roc-plugin-assets-images/src/images/index.js @@ -3,23 +3,29 @@ import { join } from 'path'; import qs from 'qs'; export default ({ context: { config: { settings } }, previousValue: webpackConfig }) => () => () => { - webpackConfig.module.loaders.push({ + webpackConfig.module.rules.push({ test: new RegExp(`\.(${settings.build.assets.images.urlLoader.filetypes.join('|')})$`), - loader: `${require.resolve('url-loader')}?${qs.stringify({ - // The url-loader will pass all additional query parameters to the file-loader if it exceeds the limit. - ...settings.build.assets.images.fileLoader.options, - ...settings.build.assets.images.urlLoader.options, - })}`, + use: [{ + loader: require.resolve('url-loader'), + options: { + // The url-loader will pass all additional query parameters to the file-loader if it exceeds the limit. + ...settings.build.assets.images.fileLoader.options, + ...settings.build.assets.images.urlLoader.options, + }, + }], }); - webpackConfig.module.loaders.push({ + webpackConfig.module.rules.push({ test: new RegExp(`\.(${settings.build.assets.images.fileLoader.filetypes.join('|')})$`), - loader: `${require.resolve('file-loader')}?${qs.stringify(settings.build.assets.images.fileLoader.options)}`, + use: [{ + loader: require.resolve('file-loader'), + options: settings.build.assets.images.fileLoader.options, + }], }); // We want to be able to use the url-loader and the file-loader in projects without the user needing // to install them directly. - webpackConfig.resolveLoader.root.push(join(__dirname, '../../node_modules')); + webpackConfig.resolveLoader.modules.push(join(__dirname, '../../node_modules')); return webpackConfig; }; diff --git a/plugins/roc-plugin-style-css/package.json b/plugins/roc-plugin-style-css/package.json index 61f87a0..cf384d9 100644 --- a/plugins/roc-plugin-style-css/package.json +++ b/plugins/roc-plugin-style-css/package.json @@ -22,13 +22,13 @@ ], "license": "MIT", "dependencies": { - "autoprefixer": "~6.6.1", - "css-loader": "~0.23.0", - "extract-text-webpack-plugin": "~0.8.2", + "autoprefixer": "~7.2.4", + "css-loader": "~0.28.7", + "extract-text-webpack-plugin": "~3.0.2", "node-noop": "1.0.0", - "postcss-loader": "~0.8.0", + "postcss-loader": "~2.0.9", "roc": "^1.0.0-rc.23", - "style-loader": "~0.13.0" + "style-loader": "~0.19.1" }, "roc": { "packages": [ diff --git a/plugins/roc-plugin-style-css/src/css/index.js b/plugins/roc-plugin-style-css/src/css/index.js index 3137e27..65a6472 100644 --- a/plugins/roc-plugin-style-css/src/css/index.js +++ b/plugins/roc-plugin-style-css/src/css/index.js @@ -44,6 +44,9 @@ export default ({ context: { config: { settings } }, previousValue: webpackConfi preLoaders = preLoaders.concat(loaders); }); + // setup postcss plugins + const postcssPlugins = [autoprefixer(settings.build.style.autoprefixer)]; + // Create a seperate pipeline for each `add-style` invocation styles.forEach(({ extensions, loaders }) => { // We allow stylesheet files to end with a query string @@ -54,18 +57,19 @@ export default ({ context: { config: { settings } }, previousValue: webpackConfi const loader = NODE ? 'css-loader/locals' : 'css-loader'; - const styleLoader = (cssModules) => cssPipeline( + const styleLoader = cssModules => cssPipeline( loader, loaders, DIST, sourceMap, cssModules, preLoaders, - minimize + minimize, + postcssPlugins, ); // Add CSS Modules loader - newWebpackConfig.module.loaders.push({ + newWebpackConfig.module.rules.push({ test: (absPath) => { if ( globalStylePaths.indexOf(absPath) === -1 && toMatch.test(absPath) && @@ -81,14 +85,14 @@ export default ({ context: { config: { settings } }, previousValue: webpackConfi return false; }, - loader: WEB ? - ExtractTextPlugin.extract(require.resolve('style-loader'), styleLoader(true)) : + use: WEB ? + ExtractTextPlugin.extract({ fallback: require.resolve('style-loader'), use: styleLoader(true) }) : styleLoader(true), }); // Create global style loader if (WEB) { - newWebpackConfig.module.loaders.push({ + newWebpackConfig.module.rules.push({ test: (absPath) => { if ( globalStylePaths.indexOf(absPath) === -1 && toMatch.test(absPath) && @@ -108,7 +112,7 @@ export default ({ context: { config: { settings } }, previousValue: webpackConfi return false; }, - loader: ExtractTextPlugin.extract(require.resolve('style-loader'), styleLoader(false)), + use: ExtractTextPlugin.extract({ fallback: require.resolve('style-loader'), use: styleLoader(false) }), }); } else { newWebpackConfig.externals.unshift((context, request, callback) => { @@ -147,20 +151,16 @@ export default ({ context: { config: { settings } }, previousValue: webpackConfi }; }); - // Configure autoprefixer - newWebpackConfig.postcss = [ - autoprefixer(settings.build.style.autoprefixer), - ]; - // Configure ExtractTextPlugin newWebpackConfig.plugins.push( - new ExtractTextPlugin(settings.build.style.name, { + new ExtractTextPlugin({ + filename: settings.build.style.name, disable: WEB && DEV, }) ); // We want to be able to use the css-loader in projects without the user needing to install them directly. - newWebpackConfig.resolveLoader.root.push(join(__dirname, '../../node_modules')); + newWebpackConfig.resolveLoader.modules.push(join(__dirname, '../../node_modules')); return newWebpackConfig; }; diff --git a/plugins/roc-plugin-style-css/src/css/pipeline.js b/plugins/roc-plugin-style-css/src/css/pipeline.js index 740616f..a63ba16 100644 --- a/plugins/roc-plugin-style-css/src/css/pipeline.js +++ b/plugins/roc-plugin-style-css/src/css/pipeline.js @@ -1,49 +1,34 @@ export default function cssPipeline( - base, + cssLoader, loaders, isDist, sourceMap = false, cssModulesEnabled = true, preLoaders, - minimize = true + minimize = true, + postcssPlugins, ) { - let moduleSettings = ''; - const sourceMapSettings = sourceMap ? - 'sourceMap&' : - ''; - const minimizeSettings = minimize ? - '' : - '-minimize&'; + const cssLoaderConf = { + loader: require.resolve(cssLoader), + options: { + sourceMap, + minimize, + importLoaders: loaders.length + preLoaders.length + 1, + }, + }; if (cssModulesEnabled) { - moduleSettings = '&modules&localIdentName='; + cssLoaderConf.options.modules = true; - // Define how the class names should be defined - if (isDist) { - moduleSettings += '[hash:base64:5]'; - } else { - moduleSettings += '[path]_[name]__[local]___[hash:base64:5]'; - } + cssLoaderConf.options.localIdentName = isDist + ? '[hash:base64:5]' + : '[path]_[name]__[local]___[hash:base64:5]'; } - const extraLoaders = loaders.length > 0 ? - `!${loaders.join('!')}` : - ''; - - const ploaders = (preLoaders && preLoaders.length > 0) ? - `!${preLoaders.join('!')}` : - ''; - - const nLoaders = loaders.length + preLoaders.length + 1; - - // We set importLoaders to nr. loaders + 1 to get css-loader to process everything through the pipeline - return `${require.resolve(base)}?` + - `${minimizeSettings}` + - `${sourceMapSettings}` + - '-autoprefixer&' + - `importLoaders=${nLoaders}` + - `${moduleSettings}` + - `${ploaders}` + - `!${require.resolve('postcss-loader')}` + - `${extraLoaders}`; + return [ + ...preLoaders, + cssLoaderConf, + { loader: 'postcss-loader', options: { plugins: postcssPlugins } }, + ...loaders, + ]; } diff --git a/plugins/roc-plugin-style-css/src/roc/index.js b/plugins/roc-plugin-style-css/src/roc/index.js index 168ada0..76e6474 100644 --- a/plugins/roc-plugin-style-css/src/roc/index.js +++ b/plugins/roc-plugin-style-css/src/roc/index.js @@ -1,4 +1,4 @@ -import { isArray, isObject, isString, oneOf } from 'roc/validators'; +import { isArray, isObject } from 'roc/validators'; import { lazyFunctionRequire, generateDependencies } from 'roc'; import config from '../config/roc.config.js'; @@ -26,9 +26,9 @@ export default { Important that the _actions_ return an object matching the following: - \`{ extensions: String/[String], loaders: String/[String] }\``, + \`{ extensions: String/[String], loaders: String/Object/[String]/[Object] }\``, hasCallback: true, - returns: isObject(oneOf(isString, isArray(isString))), + returns: isObject(), }, 'add-style-preloaders': { description: ` @@ -36,7 +36,7 @@ export default { These loaders will be applied to all styles added from the \`add-style\` hook.`, hasCallback: true, - returns: isArray(isString), + returns: isArray(isObject()), }, }, }; diff --git a/plugins/roc-plugin-style-less/package.json b/plugins/roc-plugin-style-less/package.json index ae3ae1a..75bc54f 100644 --- a/plugins/roc-plugin-style-less/package.json +++ b/plugins/roc-plugin-style-less/package.json @@ -26,7 +26,7 @@ ], "dependencies": { "less": "^2.5.1", - "less-loader": "^2.2.1" + "less-loader": "^4.0.5" }, "roc": { "packages": [ diff --git a/plugins/roc-plugin-style-less/src/index.js b/plugins/roc-plugin-style-less/src/index.js index 7077e57..6af8575 100644 --- a/plugins/roc-plugin-style-less/src/index.js +++ b/plugins/roc-plugin-style-less/src/index.js @@ -9,8 +9,12 @@ export const roc = { description: 'Adds Less support to Webpack.', action: ({ context: { config: { settings } } }) => () => () => ({ extensions: ['less'], - loaders: require.resolve('less-loader') + - (settings.build.style.sourceMap ? '?sourceMap' : ''), + loaders: [{ + loader: require.resolve('less-loader'), + options: { + sourceMap: !!settings.build.style.sourceMap, + }, + }], }), }], }; diff --git a/plugins/roc-plugin-style-sass/package.json b/plugins/roc-plugin-style-sass/package.json index 9674d97..a56df11 100644 --- a/plugins/roc-plugin-style-sass/package.json +++ b/plugins/roc-plugin-style-sass/package.json @@ -25,7 +25,7 @@ "bourbon": "~4.2.6", "node-sass": "^4.5.0", "roc": "^1.0.0-rc.23", - "sass-loader": "^4.1.1" + "sass-loader": "^6.0.6" }, "roc": { "packages": [ diff --git a/plugins/roc-plugin-style-sass/src/index.js b/plugins/roc-plugin-style-sass/src/index.js index ce56127..c64f0b9 100644 --- a/plugins/roc-plugin-style-sass/src/index.js +++ b/plugins/roc-plugin-style-sass/src/index.js @@ -32,16 +32,15 @@ export const roc = { extension: 'roc-plugin-style-css', hook: 'add-style', description: 'Adds Sass support to Webpack.', - action: ({ context: { config: { settings } } }) => () => () => { - const params = [ - settings.build.sass.useBourbon ? `includePaths[]=${BOURBON_PATH}` : '', - settings.build.style.sourceMap ? 'sourceMap' : '', - ].filter(v => v).join('&'); - - return { - extensions: ['sass', 'scss'], - loaders: `${require.resolve('sass-loader')}?${params}`, - }; - }, + action: ({ context: { config: { settings } } }) => () => () => ({ + extensions: ['sass', 'scss'], + loaders: [{ + loader: require.resolve('sass-loader'), + options: { + includePaths: settings.build.sass.useBourbon ? [...BOURBON_PATH] : [], + sourceMap: !!settings.build.style.sourceMap, + }, + }], + }), }], }; diff --git a/plugins/roc-plugin-test-jest/src/actions/test.js b/plugins/roc-plugin-test-jest/src/actions/test.js index 101c650..5ecdb5f 100644 --- a/plugins/roc-plugin-test-jest/src/actions/test.js +++ b/plugins/roc-plugin-test-jest/src/actions/test.js @@ -10,7 +10,13 @@ export default ({ context }) => (targets, managedOptions, extraArgs = []) => { let argv = [...extraArgs]; // TODO - Make it not depend on Webpack but work in any project - const webpackConfig = invokeHook('build-webpack', 'node', {}); + /* eslint-disable no-unused-vars */ + const { rocMetaInfo: _, ...webpackConfig } = invokeHook( + 'build-webpack', + 'node', + {}, + ); + /* eslint-enable no-unused-vars */ const globals = webpackConfig.plugins.reduce((definitions, plugin) => { if (plugin.definitions) { return { diff --git a/plugins/roc-plugin-test-mocha-webpack/src/actions/test.js b/plugins/roc-plugin-test-mocha-webpack/src/actions/test.js index 7e5e0a3..e670da4 100644 --- a/plugins/roc-plugin-test-mocha-webpack/src/actions/test.js +++ b/plugins/roc-plugin-test-mocha-webpack/src/actions/test.js @@ -13,7 +13,13 @@ export default () => (targets, { grep, watch, coverage, runtime }) => { // Create Webpack configuration that is to be used in a node. const babelConfig = invokeHook('babel-config', 'node', cover); - const webpackConfig = invokeHook('build-webpack', 'node', babelConfig); + /* eslint-disable no-unused-vars */ + const { rocMetaInfo: _, ...webpackConfig } = invokeHook( + 'build-webpack', + 'node', + babelConfig, + ); + /* eslint-enable no-unused-vars */ nycRunner({ grep, watch, coverage: cover, runtime, webpackConfig }); };