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
|
||||
* @returns {{ postcssOptions: { plugins?: unknown, order?: string, preset?: any} }}
|
||||
*/
|
||||
normalize (postcssOptions) {
|
||||
normalize (postcssOptions, warnAboutTopLevelDeprecation = true) {
|
||||
// TODO: Remove in Nuxt 3
|
||||
if (Array.isArray(postcssOptions)) {
|
||||
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: {} }
|
||||
}
|
||||
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')
|
||||
return { postcssOptions: {} }
|
||||
const postcssOptionsFn = postcssOptions.postcssOptions
|
||||
return {
|
||||
postcssOptions: (loaderContext) => {
|
||||
const result = this.normalize(postcssOptionsFn(loaderContext), false)
|
||||
if (result) {
|
||||
return result.postcssOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!('postcssOptions' in postcssOptions)) {
|
||||
if (Object.keys(postcssOptions).length > 0) {
|
||||
consola.warn('Using the top-level properties in `build.postcss` will be deprecated in Nuxt 3. Please move' +
|
||||
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 ' +
|
||||
'the settings to `postcss.postcssOptions`')
|
||||
}
|
||||
postcssOptions = { postcssOptions }
|
||||
@ -211,7 +218,7 @@ export default class PostcssConfig {
|
||||
|
||||
/**
|
||||
* Load plugins from postcssOptions
|
||||
* @param {{ postcssOptions: {plugins?: unknown, order?: string | function}}} postcssOptions
|
||||
* @param {{ postcssOptions: {plugins?: unknown, order?: string | function }}} postcssOptions
|
||||
*/
|
||||
loadPlugins (postcssOptions) {
|
||||
const { plugins, order } = postcssOptions.postcssOptions
|
||||
@ -252,7 +259,7 @@ export default class PostcssConfig {
|
||||
|
||||
if (Array.isArray(postcssOptions.postcssOptions.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
|
||||
if (postcssOptions.postcssOptions.preset) {
|
||||
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