mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-26 23:52:06 +00:00
feat(webpack): support passing function as postcssOptions
(#19495)
This commit is contained in:
parent
f842c75ff2
commit
3e4284e8f6
@ -154,7 +154,7 @@ export default class PostcssConfig {
|
|||||||
* @param postcssOptions
|
* @param postcssOptions
|
||||||
* @returns {{ postcssOptions: { plugins?: unknown, order?: string, preset?: any} }}
|
* @returns {{ postcssOptions: { plugins?: unknown, order?: string, preset?: any} }}
|
||||||
*/
|
*/
|
||||||
normalize (postcssOptions) {
|
normalize (postcssOptions, warnAboutTopLevelDeprecation = true) {
|
||||||
// TODO: Remove in Nuxt 3
|
// TODO: Remove in Nuxt 3
|
||||||
if (Array.isArray(postcssOptions)) {
|
if (Array.isArray(postcssOptions)) {
|
||||||
consola.warn('Using an Array as `build.postcss` will be deprecated in Nuxt 3. Please switch to the object' +
|
consola.warn('Using an Array as `build.postcss` will be deprecated in Nuxt 3. Please switch to the object' +
|
||||||
@ -168,12 +168,19 @@ export default class PostcssConfig {
|
|||||||
return { postcssOptions: {} }
|
return { postcssOptions: {} }
|
||||||
}
|
}
|
||||||
if (postcssOptions.postcssOptions && typeof postcssOptions.postcssOptions === 'function') {
|
if (postcssOptions.postcssOptions && typeof postcssOptions.postcssOptions === 'function') {
|
||||||
consola.warn('Using a Function as `build.postcss.postcssOptions` is not yet supported in Nuxt 2.16.2')
|
const postcssOptionsFn = postcssOptions.postcssOptions
|
||||||
return { postcssOptions: {} }
|
return {
|
||||||
|
postcssOptions: (loaderContext) => {
|
||||||
|
const result = this.normalize(postcssOptionsFn(loaderContext), false)
|
||||||
|
if (result) {
|
||||||
|
return result.postcssOptions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!('postcssOptions' in postcssOptions)) {
|
if (!('postcssOptions' in postcssOptions)) {
|
||||||
if (Object.keys(postcssOptions).length > 0) {
|
if (Object.keys(postcssOptions).length > 0 && warnAboutTopLevelDeprecation) {
|
||||||
consola.warn('Using the top-level properties in `build.postcss` will be deprecated in Nuxt 3. Please move' +
|
consola.warn('Using the top-level properties in `build.postcss` will be deprecated in Nuxt 3. Please move ' +
|
||||||
'the settings to `postcss.postcssOptions`')
|
'the settings to `postcss.postcssOptions`')
|
||||||
}
|
}
|
||||||
postcssOptions = { postcssOptions }
|
postcssOptions = { postcssOptions }
|
||||||
@ -211,7 +218,7 @@ export default class PostcssConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Load plugins from postcssOptions
|
* Load plugins from postcssOptions
|
||||||
* @param {{ postcssOptions: {plugins?: unknown, order?: string | function}}} postcssOptions
|
* @param {{ postcssOptions: {plugins?: unknown, order?: string | function }}} postcssOptions
|
||||||
*/
|
*/
|
||||||
loadPlugins (postcssOptions) {
|
loadPlugins (postcssOptions) {
|
||||||
const { plugins, order } = postcssOptions.postcssOptions
|
const { plugins, order } = postcssOptions.postcssOptions
|
||||||
@ -252,7 +259,7 @@ export default class PostcssConfig {
|
|||||||
|
|
||||||
if (Array.isArray(postcssOptions.postcssOptions.plugins)) {
|
if (Array.isArray(postcssOptions.postcssOptions.plugins)) {
|
||||||
defaults(postcssOptions.postcssOptions.plugins, this.defaultPostcssOptions.plugins)
|
defaults(postcssOptions.postcssOptions.plugins, this.defaultPostcssOptions.plugins)
|
||||||
} else {
|
} else if (typeof postcssOptions.postcssOptions !== 'function') {
|
||||||
// Merge all plugins and use preset for setting up postcss-preset-env
|
// Merge all plugins and use preset for setting up postcss-preset-env
|
||||||
if (postcssOptions.postcssOptions.preset) {
|
if (postcssOptions.postcssOptions.preset) {
|
||||||
if (!postcssOptions.postcssOptions.plugins) {
|
if (!postcssOptions.postcssOptions.plugins) {
|
||||||
|
55
packages/webpack/test/postcss.test.js
Normal file
55
packages/webpack/test/postcss.test.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { join } from 'node:path'
|
||||||
|
import PostcssConfig from '../src/utils/postcss'
|
||||||
|
|
||||||
|
describe('webpack: postcss', () => {
|
||||||
|
const getConfigWithPostcssConfig = config =>
|
||||||
|
new PostcssConfig({
|
||||||
|
options: {
|
||||||
|
dev: false,
|
||||||
|
srcDir: join(__dirname),
|
||||||
|
rootDir: join(__dirname),
|
||||||
|
modulesDir: []
|
||||||
|
},
|
||||||
|
nuxt: {
|
||||||
|
resolver: {
|
||||||
|
requireModule: plugin => opts => [plugin, opts]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buildOptions: {
|
||||||
|
postcss: config
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should have the right default configuration', () => {
|
||||||
|
// Use the default postcss config: stage 2
|
||||||
|
// https://cssdb.org/#staging-process
|
||||||
|
const pluginConfig = Object.fromEntries(
|
||||||
|
getConfigWithPostcssConfig({ postcssOptions: {} }).config().postcssOptions.plugins
|
||||||
|
)
|
||||||
|
expect(pluginConfig).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"cssnano": {
|
||||||
|
"preset": [
|
||||||
|
"default",
|
||||||
|
{
|
||||||
|
"minifyFontValues": {
|
||||||
|
"removeQuotes": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"postcss-import": {
|
||||||
|
"resolve": [Function],
|
||||||
|
},
|
||||||
|
"postcss-preset-env": {},
|
||||||
|
"postcss-url": {},
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
test('can pass a function through', () => {
|
||||||
|
// Use the default postcss config: stage 2
|
||||||
|
// https://cssdb.org/#staging-process
|
||||||
|
const options = getConfigWithPostcssConfig({ postcssOptions: () => ({ preset: { stage: 2 } }) }).config().postcssOptions
|
||||||
|
expect(typeof options).toBe('function')
|
||||||
|
})
|
||||||
|
})
|
32
test/dev/postcss-function.test.js
Normal file
32
test/dev/postcss-function.test.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { getPort, loadFixture, Nuxt } from '../utils'
|
||||||
|
|
||||||
|
let port
|
||||||
|
const url = route => 'http://localhost:' + port + route
|
||||||
|
|
||||||
|
let nuxt = null
|
||||||
|
|
||||||
|
describe('postcss configuration as function', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
const options = await loadFixture('postcss-function')
|
||||||
|
nuxt = new Nuxt(options)
|
||||||
|
await nuxt.ready()
|
||||||
|
|
||||||
|
port = await getPort()
|
||||||
|
await nuxt.server.listen(port, '0.0.0.0')
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const path of ['/css', '/postcss']) {
|
||||||
|
test(path, async () => {
|
||||||
|
const window = await nuxt.server.renderAndGetWindow(url(path))
|
||||||
|
|
||||||
|
const headHtml = window.document.head.innerHTML
|
||||||
|
expect(headHtml.replace(/\s+/g, '').replace(/;}/g, '}')).toContain('div.red{background-color:blue}.red{color:red}')
|
||||||
|
|
||||||
|
const element = window.document.querySelector('.red')
|
||||||
|
expect(element).not.toBe(null)
|
||||||
|
expect(element.textContent).toContain('This is red')
|
||||||
|
expect(element.className).toBe('red')
|
||||||
|
// t.is(window.getComputedStyle(element).color, 'red')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
16
test/fixtures/postcss-function/nuxt.config.js
vendored
Normal file
16
test/fixtures/postcss-function/nuxt.config.js
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const createData = async () => {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
return {
|
||||||
|
build: {
|
||||||
|
postcss: {
|
||||||
|
postcssOptions: () => ({
|
||||||
|
plugins: [
|
||||||
|
['postcss-preset-env', { features: { 'custom-selectors': true } }]
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createData
|
15
test/fixtures/postcss-function/pages/css.vue
vendored
Normal file
15
test/fixtures/postcss-function/pages/css.vue
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div class="red">
|
||||||
|
This is red
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@custom-selector :--red div.red;
|
||||||
|
:--red {
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
.red {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
15
test/fixtures/postcss-function/pages/postcss.vue
vendored
Normal file
15
test/fixtures/postcss-function/pages/postcss.vue
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div class="red">
|
||||||
|
This is red
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
@custom-selector :--red div.red;
|
||||||
|
:--red {
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
.red {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
3
test/fixtures/postcss-function/postcss-function.test.js
vendored
Normal file
3
test/fixtures/postcss-function/postcss-function.test.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { buildFixture } from '../../utils/build'
|
||||||
|
|
||||||
|
buildFixture('postcss-function')
|
Loading…
Reference in New Issue
Block a user