const { deepmerge } = require('@umijs/utils'); const safePostCssParser = require('postcss-safe-parser'); const BundlerConfigType = { csr:'csr', ssr:'ssr', } function createCSSRule({ webpackConfig, type, config, lang, test, isDev, loader, options, browserslist, miniCSSExtractPluginLoaderPath, }) { const rule = webpackConfig.module.rule(lang).test(test); applyLoaders(rule.oneOf('css-modules').resourceQuery(/modules/), true); applyLoaders(rule.oneOf('css'), false); applyLoaders(rule.oneOf('less'), true); function applyLoaders(rule, isCSSModules) { if(config.styleLoader) { rule .use('style-loader') .loader(require.resolve('style-loader')) .options( deepmerge( { base: 0, }, config.styleLoader, ), ); } else { if (!config.styleLoader) { rule .use('extract-css-loader') .loader( require('mini-css-extract-plugin').loader, ) .options({ publicPath: './', hmr: isDev, }); } } if(isDev && isCSSModules && config.cssModulesTypescriptLoader) { rule .use('css-modules-typescript-loader') .loader(require.resolve('css-modules-typescript-loader')) .options(config.cssModulesTypescriptLoader) } rule .use('css-loader') .loader(require.resolve('css-loader')) .options( deepmerge( { importLoaders: 1, ...(isCSSModules ? { modules: config.cssLoader.modules, } : {}), }, config.cssLoader || {}, ), ); rule .use('postcss-loader') .loader(require.resolve('postcss-loader')) .options( deepmerge( { ident: 'postcss', plugins: () => [ require('postcss-flexbugs-fixes'), require('postcss-preset-env')({ // TODO: set browsers autoprefixer: { ...config.autoprefixer, overrideBrowserslist: browserslist, }, // https://cssdb.org/ stage: 3, }), ...(config.extraPostCSSPlugins ? config.extraPostCSSPlugins : []), ], }, config.postcssLoader || {}, ), ); if (loader) { rule .use(loader) .loader(require.resolve(loader)) .options(options || {}); } } }; function css({ type, config, webpackConfig, isDev, disableCompress, browserslist, miniCSSExtractPluginPath, miniCSSExtractPluginLoaderPath, }) { createCSSRule({ type, webpackConfig, config, isDev, lang: 'css', test: /\.(css)(\?.*)?$/, browserslist, miniCSSExtractPluginLoaderPath, }); const theme = config.theme; createCSSRule({ type, webpackConfig, config, isDev, lang: 'less', test: /\.(less)(\?.*)?$/, loader: 'less-loader', options: deepmerge( { modifyVars: theme, javascriptEnabled: true, }, config.lessLoader || {}, ), browserslist, miniCSSExtractPluginLoaderPath, }); if(!config.styleLoader) { const hash = !isDev && config.hash ? '.[contenthash:8]' : ''; webpackConfig .plugin('extract-css') .use( require('mini-css-extract-plugin'), [ { filename: `[name]${hash}.css`, chunkFilename: `[name]${hash}.chunk.css`, ignoreOrder: true, }, ] ) } if (!isDev && !disableCompress) { webpackConfig .plugin('optimize-css') .use(require.resolve('optimize-css-assets-webpack-plugin'), [ { cssProcessorOptions: { parser: safePostCssParser, }, cssProcessorPluginOptions: { preset: ['default', config.cssnano], }, }, ]); } if(config.sass) { createCSSRule({ lang: 'sass', test: /\.(sass|scss)(\?.*)?$/, loader: require.resolve('sass-loader'), options: utils.deepmerge( { implementation: require('sass'), }, config.sass || {}, ), }) } } module.exports = { createCSSRule, css }