import curry from 'lodash.curry' import path from 'path' import webpack, { Configuration } from 'webpack' import MiniCssExtractPlugin from '../../../plugins/mini-css-extract-plugin' import { loader, plugin } from '../../helpers' import { ConfigurationContext, ConfigurationFn, pipe } from '../../utils' import { getCssModuleLoader, getGlobalCssLoader } from './loaders' import { getCustomDocumentError, getGlobalImportError, getGlobalModuleImportError, getLocalModuleImportError, } from './messages' import { getPostCssPlugins } from './plugins' // RegExps for all Style Sheet variants const regexLikeCss = /\.(css|scss|sass)$/ // RegExps for Style Sheets const regexCssGlobal = /(? file fns.push( loader({ oneOf: [ { test: [ regexCssGlobal, (scssEnabled && regexSassGlobal) as RegExp, ].filter(Boolean), use: { loader: 'error-loader', options: { reason: getGlobalImportError( ctx.customAppFile && path.relative(ctx.rootDirectory, ctx.customAppFile) ), }, }, }, ], }) ) if (ctx.isClient) { // Automatically transform references to files (i.e. url()) into URLs // e.g. url(./logo.svg) fns.push( loader({ oneOf: [ { // This should only be applied to CSS files issuer: { test: regexLikeCss }, // Exclude extensions that webpack handles by default exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/], use: { // `file-loader` always emits a URL reference, where `url-loader` // might inline the asset as a data URI loader: require.resolve('file-loader'), options: { // Hash the file for immutable cacheability name: 'static/media/[name].[hash].[ext]', }, }, }, ], }) ) } if (ctx.isClient && ctx.isProduction) { // Extract CSS as CSS file(s) in the client-side production bundle. fns.push( plugin( new MiniCssExtractPlugin({ filename: 'static/css/[contenthash].css', chunkFilename: 'static/css/[contenthash].css', // Next.js guarantees that CSS order "doesn't matter", due to imposed // restrictions: // 1. Global CSS can only be defined in a single entrypoint (_app) // 2. CSS Modules generate scoped class names by default and cannot // include Global CSS (:global() selector). // // While not a perfect guarantee (e.g. liberal use of `:global()` // selector), this assumption is required to code-split CSS. // // If this warning were to trigger, it'd be unactionable by the user, // but also not valid -- so we disable it. ignoreOrder: true, }) ) ) } const fn = pipe(...fns) return fn(config) })