UNPKG

hops-postcss

Version:

Configuration of PostCSS and Webpack for Hops

198 lines (183 loc) 4.94 kB
const postcssImportPlugin = require('postcss-import'); const postcssPresetEnv = require('postcss-preset-env'); const postcssNormalizeCharset = require('postcss-normalize-charset'); const ExtractCSSPlugin = require('mini-css-extract-plugin'); const CSSMinimizerPlugin = require('css-minimizer-webpack-plugin'); const { Mixin } = require('hops-mixin'); const { join, trimSlashes } = require('pathifist'); const getAssetPath = (...args) => trimSlashes(join(...args)); const cssLoaderLocalOptions = { modules: { auto: () => true, localIdentName: '[folder]-[name]-[local]-[hash:8]', exportLocalsConvention: 'camelCase', }, esModule: false, sourceMap: process.env.NODE_ENV !== 'production', }; const cssLoaderGlobalOptions = { modules: false, sourceMap: process.env.NODE_ENV !== 'production', }; const getPostCssLoader = (...additionalPlugins) => ({ loader: require.resolve('postcss-loader'), options: { postcssOptions: { ident: 'postcss', config: false, plugins: [ postcssNormalizeCharset({ add: false }), postcssImportPlugin(), ...additionalPlugins, ], }, }, }); const getCSSLoaderConfig = (browsers, additionalLoader) => { const getLoaders = (options) => [ additionalLoader, { loader: require.resolve('css-loader'), options: { ...options, importLoaders: 1, }, }, getPostCssLoader( postcssPresetEnv({ browsers, autoprefixer: { overrideBrowserslist: browsers, }, stage: 2, features: { 'nesting-rules': true, 'custom-media-queries': true, 'custom-properties': { preserve: false, }, }, }) ), ].filter(Boolean); return { test: [/\.css$/], oneOf: [ { resourceQuery: /global/, use: getLoaders(cssLoaderGlobalOptions), }, { use: getLoaders(cssLoaderLocalOptions), }, ], }; }; class PostCSSMixin extends Mixin { configureBuild(webpackConfig, loaderConfigs, target) { switch (target) { case 'build': this.configureTargetBuild(webpackConfig, loaderConfigs); break; case 'develop': this.configureTargetDevelop(loaderConfigs); break; case 'node': this.configureTargetNode(loaderConfigs); break; } } configureTargetBuild(webpackConfig, { allLoaderConfigs, jsLoaderConfig }) { allLoaderConfigs.splice( allLoaderConfigs.indexOf(jsLoaderConfig), 0, getCSSLoaderConfig(this.config.browsers, { loader: ExtractCSSPlugin.loader, options: { esModule: false }, }) ); webpackConfig.plugins.push( new ExtractCSSPlugin({ filename: getAssetPath( this.config.assetPath, '[name]-[chunkhash:12].css' ), chunkFilename: getAssetPath( this.config.assetPath, '[name]-[chunkhash:12].css' ), ignoreOrder: true, }) ); webpackConfig.optimization.minimizer.push( new CSSMinimizerPlugin({ minimizerOptions: { reduceIdents: { disable: true }, zindex: { disable: true }, mergeIdents: { disable: true }, discardUnused: { disable: true }, autoprefixer: { disable: true }, }, }) ); } configureTargetDevelop({ allLoaderConfigs, jsLoaderConfig }) { allLoaderConfigs.splice( allLoaderConfigs.indexOf(jsLoaderConfig), 0, getCSSLoaderConfig(this.config.browsers, { loader: require.resolve('style-loader'), options: { esModule: false, }, }) ); } configureTargetNode({ allLoaderConfigs, jsLoaderConfig }) { const cssLoaderConfig = { test: [/\.css$/], oneOf: [ { resourceQuery: /global/, use: [ { loader: require.resolve('css-loader'), options: { ...cssLoaderGlobalOptions, modules: { auto: false, exportOnlyLocals: true, }, importLoaders: 1, }, }, getPostCssLoader(), ], }, { use: [ { loader: require.resolve('css-loader'), options: { ...cssLoaderLocalOptions, modules: { ...cssLoaderLocalOptions.modules, exportOnlyLocals: true, }, importLoaders: 1, }, }, getPostCssLoader(), ], }, ], }; allLoaderConfigs.splice( allLoaderConfigs.indexOf(jsLoaderConfig), 0, cssLoaderConfig ); } } module.exports = PostCSSMixin;