Lazy-load postcss (#31762)

Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
This commit is contained in:
Tim Neutkens 2021-11-25 18:41:20 +01:00 committed by GitHub
parent a4159321b2
commit 92b397f2b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 307 additions and 303 deletions

3
.gitignore vendored
View file

@ -13,6 +13,7 @@ test/node_modules
# logs & pids # logs & pids
*.log *.log
pids pids
*.cpuprofile
# coverage # coverage
.nyc_output .nyc_output
@ -41,4 +42,4 @@ test-timings.json
.now .now
# Cache # Cache
*.tsbuildinfo *.tsbuildinfo

View file

@ -33,7 +33,6 @@ import { NextConfigComplete } from '../server/config-shared'
import { finalizeEntrypoint } from './entries' import { finalizeEntrypoint } from './entries'
import * as Log from './output/log' import * as Log from './output/log'
import { build as buildConfiguration } from './webpack/config' import { build as buildConfiguration } from './webpack/config'
import { __overrideCssConfiguration } from './webpack/config/blocks/css/overrideCssConfiguration'
import MiddlewarePlugin from './webpack/plugins/middleware-plugin' import MiddlewarePlugin from './webpack/plugins/middleware-plugin'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin' import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
import { JsConfigPathsPlugin } from './webpack/plugins/jsconfig-paths-plugin' import { JsConfigPathsPlugin } from './webpack/plugins/jsconfig-paths-plugin'
@ -1890,8 +1889,6 @@ export default async function getBaseWebpackConfig(
(e) => (e as any).__next_css_remove !== true (e) => (e as any).__next_css_remove !== true
) )
} }
} else if (!config.future.strictPostcssConfiguration) {
await __overrideCssConfiguration(dir, supportedBrowsers, webpackConfig)
} }
// Inject missing React Refresh loaders so that development mode is fast: // Inject missing React Refresh loaders so that development mode is fast:

View file

@ -11,69 +11,6 @@ import {
getLocalModuleImportError, getLocalModuleImportError,
} from './messages' } from './messages'
import { getPostCssPlugins } from './plugins' import { getPostCssPlugins } from './plugins'
import postcss from 'postcss'
// @ts-ignore backwards compat
postcss.plugin = function postcssPlugin(name, initializer) {
function creator(...args: any) {
let transformer = initializer(...args)
transformer.postcssPlugin = name
// transformer.postcssVersion = new Processor().version
return transformer
}
let cache: any
Object.defineProperty(creator, 'postcss', {
get() {
if (!cache) cache = creator()
return cache
},
})
creator.process = function (css: any, processOpts: any, pluginOpts: any) {
return postcss([creator(pluginOpts)]).process(css, processOpts)
}
return creator
}
// @ts-ignore backwards compat
postcss.vendor = {
/**
* Returns the vendor prefix extracted from an input string.
*
* @param {string} prop String with or without vendor prefix.
*
* @return {string} vendor prefix or empty string
*
* @example
* postcss.vendor.prefix('-moz-tab-size') //=> '-moz-'
* postcss.vendor.prefix('tab-size') //=> ''
*/
prefix: function prefix(prop: any) {
const match = prop.match(/^(-\w+-)/)
if (match) {
return match[0]
}
return ''
},
/**
* Returns the input string stripped of its vendor prefix.
*
* @param {string} prop String with or without vendor prefix.
*
* @return {string} String name without vendor prefixes.
*
* @example
* postcss.vendor.unprefixed('-moz-tab-size') //=> 'tab-size'
*/
unprefixed: function unprefixed(prop: any) {
return prop.replace(/^-\w+-/, '')
},
}
// RegExps for all Style Sheet variants // RegExps for all Style Sheet variants
export const regexLikeCss = /\.(css|scss|sass)$/ export const regexLikeCss = /\.(css|scss|sass)$/
@ -86,6 +23,99 @@ const regexCssModules = /\.module\.css$/
const regexSassGlobal = /(?<!\.module)\.(scss|sass)$/ const regexSassGlobal = /(?<!\.module)\.(scss|sass)$/
const regexSassModules = /\.module\.(scss|sass)$/ const regexSassModules = /\.module\.(scss|sass)$/
let postcssInstancePromise: Promise<any>
export async function lazyPostCSS(
rootDirectory: string,
supportedBrowsers: string[] | undefined,
strictPostcssConfiguration: boolean | undefined,
disablePostcssPresetEnv: boolean | undefined
) {
if (!postcssInstancePromise) {
postcssInstancePromise = (async () => {
const postcss = require('postcss')
// @ts-ignore backwards compat
postcss.plugin = function postcssPlugin(name, initializer) {
function creator(...args: any) {
let transformer = initializer(...args)
transformer.postcssPlugin = name
// transformer.postcssVersion = new Processor().version
return transformer
}
let cache: any
Object.defineProperty(creator, 'postcss', {
get() {
if (!cache) cache = creator()
return cache
},
})
creator.process = function (
css: any,
processOpts: any,
pluginOpts: any
) {
return postcss([creator(pluginOpts)]).process(css, processOpts)
}
return creator
}
// @ts-ignore backwards compat
postcss.vendor = {
/**
* Returns the vendor prefix extracted from an input string.
*
* @param {string} prop String with or without vendor prefix.
*
* @return {string} vendor prefix or empty string
*
* @example
* postcss.vendor.prefix('-moz-tab-size') //=> '-moz-'
* postcss.vendor.prefix('tab-size') //=> ''
*/
prefix: function prefix(prop: any) {
const match = prop.match(/^(-\w+-)/)
if (match) {
return match[0]
}
return ''
},
/**
* Returns the input string stripped of its vendor prefix.
*
* @param {string} prop String with or without vendor prefix.
*
* @return {string} String name without vendor prefixes.
*
* @example
* postcss.vendor.unprefixed('-moz-tab-size') //=> 'tab-size'
*/
unprefixed: function unprefixed(prop: any) {
return prop.replace(/^-\w+-/, '')
},
}
const postCssPlugins = await getPostCssPlugins(
rootDirectory,
supportedBrowsers,
strictPostcssConfiguration,
disablePostcssPresetEnv
)
return {
postcss,
postcssWithPlugins: postcss(postCssPlugins),
}
})()
}
return postcssInstancePromise
}
export const css = curry(async function css( export const css = curry(async function css(
ctx: ConfigurationContext, ctx: ConfigurationContext,
config: webpack.Configuration config: webpack.Configuration
@ -96,6 +126,14 @@ export const css = curry(async function css(
...sassOptions ...sassOptions
} = ctx.sassOptions } = ctx.sassOptions
const lazyPostCSSInitalizer = () =>
lazyPostCSS(
ctx.rootDirectory,
ctx.supportedBrowsers,
ctx.future.strictPostcssConfiguration,
ctx.experimental.disablePostcssPresetEnv
)
const sassPreprocessors: webpack.RuleSetUseItem[] = [ const sassPreprocessors: webpack.RuleSetUseItem[] = [
// First, process files with `sass-loader`: this inlines content, and // First, process files with `sass-loader`: this inlines content, and
// compiles away the proprietary syntax. // compiles away the proprietary syntax.
@ -137,12 +175,6 @@ export const css = curry(async function css(
}), }),
] ]
const postCssPlugins = await getPostCssPlugins(
ctx.rootDirectory,
ctx.supportedBrowsers,
!ctx.future.strictPostcssConfiguration
)
// CSS cannot be imported in _document. This comes before everything because // CSS cannot be imported in _document. This comes before everything because
// global CSS nor CSS modules work in said file. // global CSS nor CSS modules work in said file.
fns.push( fns.push(
@ -183,7 +215,7 @@ export const css = curry(async function css(
and: [ctx.rootDirectory], and: [ctx.rootDirectory],
not: [/node_modules/], not: [/node_modules/],
}, },
use: getCssModuleLoader(ctx, postCssPlugins), use: getCssModuleLoader(ctx, lazyPostCSSInitalizer),
}, },
], ],
}) })
@ -206,7 +238,11 @@ export const css = curry(async function css(
and: [ctx.rootDirectory], and: [ctx.rootDirectory],
not: [/node_modules/], not: [/node_modules/],
}, },
use: getCssModuleLoader(ctx, postCssPlugins, sassPreprocessors), use: getCssModuleLoader(
ctx,
lazyPostCSSInitalizer,
sassPreprocessors
),
}, },
], ],
}) })
@ -266,7 +302,7 @@ export const css = curry(async function css(
and: [ctx.rootDirectory], and: [ctx.rootDirectory],
not: [/node_modules/], not: [/node_modules/],
}, },
use: getGlobalCssLoader(ctx, postCssPlugins), use: getGlobalCssLoader(ctx, lazyPostCSSInitalizer),
}, },
], ],
}) })
@ -284,7 +320,7 @@ export const css = curry(async function css(
sideEffects: true, sideEffects: true,
test: regexCssGlobal, test: regexCssGlobal,
issuer: { and: [ctx.customAppFile] }, issuer: { and: [ctx.customAppFile] },
use: getGlobalCssLoader(ctx, postCssPlugins), use: getGlobalCssLoader(ctx, lazyPostCSSInitalizer),
}, },
], ],
}) })
@ -300,7 +336,11 @@ export const css = curry(async function css(
sideEffects: true, sideEffects: true,
test: regexSassGlobal, test: regexSassGlobal,
issuer: { and: [ctx.customAppFile] }, issuer: { and: [ctx.customAppFile] },
use: getGlobalCssLoader(ctx, postCssPlugins, sassPreprocessors), use: getGlobalCssLoader(
ctx,
lazyPostCSSInitalizer,
sassPreprocessors
),
}, },
], ],
}) })

View file

@ -1,13 +1,11 @@
import { AcceptedPlugin } from 'postcss'
import { webpack } from 'next/dist/compiled/webpack/webpack' import { webpack } from 'next/dist/compiled/webpack/webpack'
import { ConfigurationContext } from '../../../utils' import { ConfigurationContext } from '../../../utils'
import { getClientStyleLoader } from './client' import { getClientStyleLoader } from './client'
import { cssFileResolve } from './file-resolve' import { cssFileResolve } from './file-resolve'
import postcss from 'postcss'
export function getGlobalCssLoader( export function getGlobalCssLoader(
ctx: ConfigurationContext, ctx: ConfigurationContext,
postCssPlugins: AcceptedPlugin[], postcss: any,
preProcessors: readonly webpack.RuleSetUseItem[] = [] preProcessors: readonly webpack.RuleSetUseItem[] = []
): webpack.RuleSetUseItem[] { ): webpack.RuleSetUseItem[] {
const loaders: webpack.RuleSetUseItem[] = [] const loaders: webpack.RuleSetUseItem[] = []
@ -27,6 +25,7 @@ export function getGlobalCssLoader(
loaders.push({ loaders.push({
loader: require.resolve('../../../../loaders/css-loader/src'), loader: require.resolve('../../../../loaders/css-loader/src'),
options: { options: {
postcss,
importLoaders: 1 + preProcessors.length, importLoaders: 1 + preProcessors.length,
// Next.js controls CSS Modules eligibility: // Next.js controls CSS Modules eligibility:
modules: false, modules: false,
@ -41,7 +40,7 @@ export function getGlobalCssLoader(
loaders.push({ loaders.push({
loader: require.resolve('../../../../loaders/postcss-loader/src'), loader: require.resolve('../../../../loaders/postcss-loader/src'),
options: { options: {
postcss: postcss(postCssPlugins), postcss,
}, },
}) })

View file

@ -1,14 +1,12 @@
import { AcceptedPlugin } from 'postcss'
import { webpack } from 'next/dist/compiled/webpack/webpack' import { webpack } from 'next/dist/compiled/webpack/webpack'
import { ConfigurationContext } from '../../../utils' import { ConfigurationContext } from '../../../utils'
import { getClientStyleLoader } from './client' import { getClientStyleLoader } from './client'
import { cssFileResolve } from './file-resolve' import { cssFileResolve } from './file-resolve'
import { getCssModuleLocalIdent } from './getCssModuleLocalIdent' import { getCssModuleLocalIdent } from './getCssModuleLocalIdent'
import postcss from 'postcss'
export function getCssModuleLoader( export function getCssModuleLoader(
ctx: ConfigurationContext, ctx: ConfigurationContext,
postCssPlugins: AcceptedPlugin[], postcss: any,
preProcessors: readonly webpack.RuleSetUseItem[] = [] preProcessors: readonly webpack.RuleSetUseItem[] = []
): webpack.RuleSetUseItem[] { ): webpack.RuleSetUseItem[] {
const loaders: webpack.RuleSetUseItem[] = [] const loaders: webpack.RuleSetUseItem[] = []
@ -28,6 +26,7 @@ export function getCssModuleLoader(
loaders.push({ loaders.push({
loader: require.resolve('../../../../loaders/css-loader/src'), loader: require.resolve('../../../../loaders/css-loader/src'),
options: { options: {
postcss,
importLoaders: 1 + preProcessors.length, importLoaders: 1 + preProcessors.length,
// Use CJS mode for backwards compatibility: // Use CJS mode for backwards compatibility:
esModule: false, esModule: false,
@ -57,7 +56,7 @@ export function getCssModuleLoader(
loaders.push({ loaders.push({
loader: require.resolve('../../../../loaders/postcss-loader/src'), loader: require.resolve('../../../../loaders/postcss-loader/src'),
options: { options: {
postcss: postcss(postCssPlugins), postcss,
}, },
}) })

View file

@ -1,42 +0,0 @@
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { getPostCssPlugins } from './plugins'
import postcss from 'postcss'
export async function __overrideCssConfiguration(
rootDirectory: string,
supportedBrowsers: string[] | undefined,
config: webpack.Configuration
) {
const postCssPlugins = await getPostCssPlugins(
rootDirectory,
supportedBrowsers
)
function patch(rule: webpack.RuleSetRule) {
if (
rule.options &&
typeof rule.options === 'object' &&
typeof rule.options.postcssOptions === 'object'
) {
rule.options.postcssOptions.plugins = postCssPlugins
} else if (
rule.options &&
typeof rule.options === 'object' &&
typeof rule.options.postcss !== 'undefined'
) {
rule.options.postcss = postcss(postCssPlugins)
} else if (Array.isArray(rule.oneOf)) {
rule.oneOf.forEach(patch)
} else if (Array.isArray(rule.use)) {
rule.use.forEach((u) => {
if (typeof u === 'object') {
patch(u)
}
})
}
}
config.module?.rules?.forEach((entry) => {
patch(entry)
})
}

View file

@ -88,40 +88,46 @@ async function loadPlugin(
} }
function getDefaultPlugins( function getDefaultPlugins(
supportedBrowsers: string[] | undefined supportedBrowsers: string[] | undefined,
): CssPluginCollection { disablePostcssPresetEnv: boolean
): any[] {
return [ return [
require.resolve('next/dist/compiled/postcss-flexbugs-fixes'), require.resolve('next/dist/compiled/postcss-flexbugs-fixes'),
[ disablePostcssPresetEnv
require.resolve('next/dist/compiled/postcss-preset-env'), ? false
{ : [
browsers: supportedBrowsers ?? ['defaults'], require.resolve('next/dist/compiled/postcss-preset-env'),
autoprefixer: { {
// Disable legacy flexbox support browsers: supportedBrowsers ?? ['defaults'],
flexbox: 'no-2009', autoprefixer: {
}, // Disable legacy flexbox support
// Enable CSS features that have shipped to the flexbox: 'no-2009',
// web platform, i.e. in 2+ browsers unflagged. },
stage: 3, // Enable CSS features that have shipped to the
features: { // web platform, i.e. in 2+ browsers unflagged.
'custom-properties': false, stage: 3,
}, features: {
}, 'custom-properties': false,
], },
] },
],
].filter(Boolean)
} }
export async function getPostCssPlugins( export async function getPostCssPlugins(
dir: string, dir: string,
supportedBrowsers: string[] | undefined, supportedBrowsers: string[] | undefined,
defaults: boolean = false defaults: boolean = false,
disablePostcssPresetEnv: boolean = false
): Promise<import('postcss').AcceptedPlugin[]> { ): Promise<import('postcss').AcceptedPlugin[]> {
let config = defaults let config = defaults
? null ? null
: await findConfig<{ plugins: CssPluginCollection }>(dir, 'postcss') : await findConfig<{ plugins: CssPluginCollection }>(dir, 'postcss')
if (config == null) { if (config == null) {
config = { plugins: getDefaultPlugins(supportedBrowsers) } config = {
plugins: getDefaultPlugins(supportedBrowsers, disablePostcssPresetEnv),
}
} }
if (typeof config === 'function') { if (typeof config === 'function') {

View file

@ -2,28 +2,135 @@
MIT License http://www.opensource.org/licenses/mit-license.php MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra Author Tobias Koppers @sokra
*/ */
import postcss from 'postcss'
import CssSyntaxError from './CssSyntaxError' import CssSyntaxError from './CssSyntaxError'
import Warning from '../../postcss-loader/src/Warning' import Warning from '../../postcss-loader/src/Warning'
import { icssParser, importParser, urlParser } from './plugins' // import { icssParser, importParser, urlParser } from './plugins'
import {
normalizeOptions,
shouldUseModulesPlugins,
shouldUseImportPlugin,
shouldUseURLPlugin,
shouldUseIcssPlugin,
getPreRequester,
getExportCode,
getFilter,
getImportCode,
getModuleCode,
getModulesPlugins,
normalizeSourceMap,
sort,
} from './utils'
import { stringifyRequest } from '../../../stringify-request' import { stringifyRequest } from '../../../stringify-request'
const moduleRegExp = /\.module\.\w+$/i
function getModulesOptions(rawOptions, loaderContext) {
const { resourcePath } = loaderContext
if (typeof rawOptions.modules === 'undefined') {
const isModules = moduleRegExp.test(resourcePath)
if (!isModules) {
return false
}
} else if (
typeof rawOptions.modules === 'boolean' &&
rawOptions.modules === false
) {
return false
}
let modulesOptions = {
compileType: rawOptions.icss ? 'icss' : 'module',
auto: true,
mode: 'local',
exportGlobals: false,
localIdentName: '[hash:base64]',
localIdentContext: loaderContext.rootContext,
localIdentHashPrefix: '',
// eslint-disable-next-line no-undefined
localIdentRegExp: undefined,
namedExport: false,
exportLocalsConvention: 'asIs',
exportOnlyLocals: false,
}
if (
typeof rawOptions.modules === 'boolean' ||
typeof rawOptions.modules === 'string'
) {
modulesOptions.mode =
typeof rawOptions.modules === 'string' ? rawOptions.modules : 'local'
} else {
if (rawOptions.modules) {
if (typeof rawOptions.modules.auto === 'boolean') {
const isModules =
rawOptions.modules.auto && moduleRegExp.test(resourcePath)
if (!isModules) {
return false
}
} else if (rawOptions.modules.auto instanceof RegExp) {
const isModules = rawOptions.modules.auto.test(resourcePath)
if (!isModules) {
return false
}
} else if (typeof rawOptions.modules.auto === 'function') {
const isModule = rawOptions.modules.auto(resourcePath)
if (!isModule) {
return false
}
}
if (
rawOptions.modules.namedExport === true &&
typeof rawOptions.modules.exportLocalsConvention === 'undefined'
) {
modulesOptions.exportLocalsConvention = 'camelCaseOnly'
}
}
modulesOptions = { ...modulesOptions, ...(rawOptions.modules || {}) }
}
if (typeof modulesOptions.mode === 'function') {
modulesOptions.mode = modulesOptions.mode(loaderContext.resourcePath)
}
if (modulesOptions.namedExport === true) {
if (rawOptions.esModule === false) {
throw new Error(
'The "modules.namedExport" option requires the "esModules" option to be enabled'
)
}
if (modulesOptions.exportLocalsConvention !== 'camelCaseOnly') {
throw new Error(
'The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly"'
)
}
}
return modulesOptions
}
function normalizeOptions(rawOptions, loaderContext) {
if (rawOptions.icss) {
loaderContext.emitWarning(
new Error(
'The "icss" option is deprecated, use "modules.compileType: "icss"" instead'
)
)
}
const modulesOptions = getModulesOptions(rawOptions, loaderContext)
return {
url: typeof rawOptions.url === 'undefined' ? true : rawOptions.url,
import: typeof rawOptions.import === 'undefined' ? true : rawOptions.import,
modules: modulesOptions,
// TODO remove in the next major release
icss: typeof rawOptions.icss === 'undefined' ? false : rawOptions.icss,
sourceMap:
typeof rawOptions.sourceMap === 'boolean'
? rawOptions.sourceMap
: loaderContext.sourceMap,
importLoaders:
typeof rawOptions.importLoaders === 'string'
? parseInt(rawOptions.importLoaders, 10)
: rawOptions.importLoaders,
esModule:
typeof rawOptions.esModule === 'undefined' ? true : rawOptions.esModule,
}
}
export default async function loader(content, map, meta) { export default async function loader(content, map, meta) {
const rawOptions = this.getOptions() const rawOptions = this.getOptions()
@ -42,6 +149,25 @@ export default async function loader(content, map, meta) {
throw error throw error
} }
const { postcss } = await rawOptions.postcss()
const {
shouldUseModulesPlugins,
shouldUseImportPlugin,
shouldUseURLPlugin,
shouldUseIcssPlugin,
getPreRequester,
getExportCode,
getFilter,
getImportCode,
getModuleCode,
getModulesPlugins,
normalizeSourceMap,
sort,
} = require('./utils')
const { icssParser, importParser, urlParser } = require('./plugins')
const replacements = [] const replacements = []
const exports = [] const exports = []

View file

@ -81,130 +81,6 @@ function getFilter(filter, resourcePath) {
} }
} }
const moduleRegExp = /\.module\.\w+$/i
function getModulesOptions(rawOptions, loaderContext) {
const { resourcePath } = loaderContext
if (typeof rawOptions.modules === 'undefined') {
const isModules = moduleRegExp.test(resourcePath)
if (!isModules) {
return false
}
} else if (
typeof rawOptions.modules === 'boolean' &&
rawOptions.modules === false
) {
return false
}
let modulesOptions = {
compileType: rawOptions.icss ? 'icss' : 'module',
auto: true,
mode: 'local',
exportGlobals: false,
localIdentName: '[hash:base64]',
localIdentContext: loaderContext.rootContext,
localIdentHashPrefix: '',
// eslint-disable-next-line no-undefined
localIdentRegExp: undefined,
namedExport: false,
exportLocalsConvention: 'asIs',
exportOnlyLocals: false,
}
if (
typeof rawOptions.modules === 'boolean' ||
typeof rawOptions.modules === 'string'
) {
modulesOptions.mode =
typeof rawOptions.modules === 'string' ? rawOptions.modules : 'local'
} else {
if (rawOptions.modules) {
if (typeof rawOptions.modules.auto === 'boolean') {
const isModules =
rawOptions.modules.auto && moduleRegExp.test(resourcePath)
if (!isModules) {
return false
}
} else if (rawOptions.modules.auto instanceof RegExp) {
const isModules = rawOptions.modules.auto.test(resourcePath)
if (!isModules) {
return false
}
} else if (typeof rawOptions.modules.auto === 'function') {
const isModule = rawOptions.modules.auto(resourcePath)
if (!isModule) {
return false
}
}
if (
rawOptions.modules.namedExport === true &&
typeof rawOptions.modules.exportLocalsConvention === 'undefined'
) {
modulesOptions.exportLocalsConvention = 'camelCaseOnly'
}
}
modulesOptions = { ...modulesOptions, ...(rawOptions.modules || {}) }
}
if (typeof modulesOptions.mode === 'function') {
modulesOptions.mode = modulesOptions.mode(loaderContext.resourcePath)
}
if (modulesOptions.namedExport === true) {
if (rawOptions.esModule === false) {
throw new Error(
'The "modules.namedExport" option requires the "esModules" option to be enabled'
)
}
if (modulesOptions.exportLocalsConvention !== 'camelCaseOnly') {
throw new Error(
'The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly"'
)
}
}
return modulesOptions
}
function normalizeOptions(rawOptions, loaderContext) {
if (rawOptions.icss) {
loaderContext.emitWarning(
new Error(
'The "icss" option is deprecated, use "modules.compileType: "icss"" instead'
)
)
}
const modulesOptions = getModulesOptions(rawOptions, loaderContext)
return {
url: typeof rawOptions.url === 'undefined' ? true : rawOptions.url,
import: typeof rawOptions.import === 'undefined' ? true : rawOptions.import,
modules: modulesOptions,
// TODO remove in the next major release
icss: typeof rawOptions.icss === 'undefined' ? false : rawOptions.icss,
sourceMap:
typeof rawOptions.sourceMap === 'boolean'
? rawOptions.sourceMap
: loaderContext.sourceMap,
importLoaders:
typeof rawOptions.importLoaders === 'string'
? parseInt(rawOptions.importLoaders, 10)
: rawOptions.importLoaders,
esModule:
typeof rawOptions.esModule === 'undefined' ? true : rawOptions.esModule,
}
}
function shouldUseImportPlugin(options) { function shouldUseImportPlugin(options) {
if (options.modules.exportOnlyLocals) { if (options.modules.exportOnlyLocals) {
return false return false
@ -632,7 +508,6 @@ function isDataUrl(url) {
export { export {
isDataUrl, isDataUrl,
normalizeOptions,
shouldUseModulesPlugins, shouldUseModulesPlugins,
shouldUseImportPlugin, shouldUseImportPlugin,
shouldUseURLPlugin, shouldUseURLPlugin,
@ -640,7 +515,6 @@ export {
normalizeUrl, normalizeUrl,
requestify, requestify,
getFilter, getFilter,
getModulesOptions,
getModulesPlugins, getModulesPlugins,
normalizeSourceMap, normalizeSourceMap,
getPreRequester, getPreRequester,

View file

@ -56,13 +56,16 @@ export default async function loader(content, sourceMap, meta) {
loaderSpan.setAttribute('astUsed', 'true') loaderSpan.setAttribute('astUsed', 'true')
} }
// Initializes postcss with plugins
const { postcssWithPlugins } = await options.postcss()
let result let result
try { try {
result = await loaderSpan result = await loaderSpan
.traceChild('postcss-process') .traceChild('postcss-process')
.traceAsyncFn(() => .traceAsyncFn(() =>
options.postcss.process(root || content, processOptions) postcssWithPlugins.process(root || content, processOptions)
) )
} catch (error) { } catch (error) {
if (error.file) { if (error.file) {

View file

@ -126,6 +126,7 @@ export type NextConfig = { [key: string]: any } & {
crossOrigin?: false | 'anonymous' | 'use-credentials' crossOrigin?: false | 'anonymous' | 'use-credentials'
swcMinify?: boolean swcMinify?: boolean
experimental?: { experimental?: {
disablePostcssPresetEnv?: boolean
removeConsole?: removeConsole?:
| boolean | boolean
| { | {

View file

@ -208,7 +208,7 @@ describe('Bad CSS Customization Array (1)', () => {
expect(stderr).toMatch( expect(stderr).toMatch(
/A PostCSS Plugin was passed as an array but did not provide its configuration \('postcss-trolling'\)/ /A PostCSS Plugin was passed as an array but did not provide its configuration \('postcss-trolling'\)/
) )
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })
@ -228,7 +228,7 @@ describe('Bad CSS Customization Array (2)', () => {
expect(stderr).toMatch( expect(stderr).toMatch(
/To disable 'postcss-trolling', pass false, otherwise, pass true or a configuration object./ /To disable 'postcss-trolling', pass false, otherwise, pass true or a configuration object./
) )
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })
@ -245,7 +245,7 @@ describe('Bad CSS Customization Array (3)', () => {
expect(stderr).toMatch( expect(stderr).toMatch(
/A PostCSS Plugin must be provided as a string. Instead, we got: '5'/ /A PostCSS Plugin must be provided as a string. Instead, we got: '5'/
) )
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })
@ -260,7 +260,7 @@ describe('Bad CSS Customization Array (4)', () => {
const { stderr } = await nextBuild(appDir, [], { stderr: true }) const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).toMatch(/An unknown PostCSS plugin was provided \(5\)/) expect(stderr).toMatch(/An unknown PostCSS plugin was provided \(5\)/)
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })
@ -277,7 +277,7 @@ describe('Bad CSS Customization Array (5)', () => {
expect(stderr).toMatch( expect(stderr).toMatch(
/Your custom PostCSS configuration must export a `plugins` key./ /Your custom PostCSS configuration must export a `plugins` key./
) )
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })
@ -294,7 +294,7 @@ describe('Bad CSS Customization Array (6)', () => {
expect(stderr).toMatch( expect(stderr).toMatch(
/Your custom PostCSS configuration must export a `plugins` key./ /Your custom PostCSS configuration must export a `plugins` key./
) )
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })
@ -311,7 +311,7 @@ describe('Bad CSS Customization Array (7)', () => {
expect(stderr).toMatch( expect(stderr).toMatch(
/A PostCSS Plugin was passed as an array but did not provide its configuration \('postcss-trolling'\)/ /A PostCSS Plugin was passed as an array but did not provide its configuration \('postcss-trolling'\)/
) )
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })
@ -328,7 +328,7 @@ describe('Bad CSS Customization Array (8)', () => {
expect(stderr).toMatch( expect(stderr).toMatch(
/A PostCSS Plugin was passed as a function using require\(\), but it must be provided as a string/ /A PostCSS Plugin was passed as a function using require\(\), but it must be provided as a string/
) )
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })
@ -345,6 +345,6 @@ describe('Bad CSS Customization Function', () => {
expect(stderr).toMatch( expect(stderr).toMatch(
/Your custom PostCSS configuration may not export a function/ /Your custom PostCSS configuration may not export a function/
) )
expect(stderr).toMatch(/Build error occurred/) expect(stderr).toMatch(/Build failed because of webpack errors/)
}) })
}) })