mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-23 14:15:13 +00:00
refactor: styleLoader and postcss (#4318)
This commit is contained in:
parent
5f8d26175a
commit
853ca4e7d4
@ -7,6 +7,16 @@ import createResolver from 'postcss-import-resolver'
|
|||||||
|
|
||||||
import { isPureObject } from '@nuxt/common'
|
import { isPureObject } from '@nuxt/common'
|
||||||
|
|
||||||
|
export const orderPresets = {
|
||||||
|
cssnanoLast: (names) => {
|
||||||
|
const nanoIndex = names.indexOf('cssnano')
|
||||||
|
if (nanoIndex !== names.length - 1) {
|
||||||
|
names.push(names.splice(nanoIndex, 1)[0])
|
||||||
|
}
|
||||||
|
return names
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default class PostcssConfig {
|
export default class PostcssConfig {
|
||||||
constructor(options, nuxt) {
|
constructor(options, nuxt) {
|
||||||
this.nuxt = nuxt
|
this.nuxt = nuxt
|
||||||
@ -45,7 +55,9 @@ export default class PostcssConfig {
|
|||||||
// https://github.com/csstools/postcss-preset-env
|
// https://github.com/csstools/postcss-preset-env
|
||||||
'postcss-preset-env': this.preset || {},
|
'postcss-preset-env': this.preset || {},
|
||||||
'cssnano': this.dev ? false : { preset: 'default' }
|
'cssnano': this.dev ? false : { preset: 'default' }
|
||||||
}
|
},
|
||||||
|
// Array, String or Function
|
||||||
|
order: 'cssnanoLast'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +99,19 @@ export default class PostcssConfig {
|
|||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sortPlugins({ plugins, order }) {
|
||||||
|
const names = Object.keys(plugins)
|
||||||
|
if (typeof order === 'string') {
|
||||||
|
order = orderPresets[order]
|
||||||
|
}
|
||||||
|
return typeof order === 'function' ? order(names, orderPresets) : (order || names)
|
||||||
|
}
|
||||||
|
|
||||||
loadPlugins(config) {
|
loadPlugins(config) {
|
||||||
const plugins = config.plugins
|
const plugins = config.plugins
|
||||||
if (isPureObject(plugins)) {
|
if (isPureObject(plugins)) {
|
||||||
// Map postcss plugins into instances on object mode once
|
// Map postcss plugins into instances on object mode once
|
||||||
config.plugins = Object.keys(plugins)
|
config.plugins = this.sortPlugins(config)
|
||||||
.map((p) => {
|
.map((p) => {
|
||||||
const plugin = require(p)
|
const plugin = require(p)
|
||||||
const opts = plugins[p]
|
const opts = plugins[p]
|
||||||
|
@ -14,7 +14,10 @@ export default class StyleLoader {
|
|||||||
this.assetsDir = options.dir.assets
|
this.assetsDir = options.dir.assets
|
||||||
this.staticDir = options.dir.static
|
this.staticDir = options.dir.static
|
||||||
this.rootDir = options.rootDir
|
this.rootDir = options.rootDir
|
||||||
this.loaders = options.build.loaders
|
this.loaders = {
|
||||||
|
css: options.build.loaders.css,
|
||||||
|
cssModules: options.build.loaders.cssModules
|
||||||
|
}
|
||||||
this.extractCSS = options.build.extractCSS
|
this.extractCSS = options.build.extractCSS
|
||||||
this.resources = options.build.styleResources
|
this.resources = options.build.styleResources
|
||||||
this.sourceMap = Boolean(options.build.cssSourceMap)
|
this.sourceMap = Boolean(options.build.cssSourceMap)
|
||||||
@ -91,13 +94,12 @@ export default class StyleLoader {
|
|||||||
|
|
||||||
apply(ext, loaders = []) {
|
apply(ext, loaders = []) {
|
||||||
const customLoaders = [].concat(
|
const customLoaders = [].concat(
|
||||||
this.postcss(loaders),
|
this.postcss(),
|
||||||
this.normalize(loaders),
|
this.normalize(loaders),
|
||||||
this.styleResource(ext)
|
this.styleResource(ext)
|
||||||
).filter(Boolean)
|
).filter(Boolean)
|
||||||
|
|
||||||
const { css: cssOptions, cssModules: cssModulesOptions } = this.loaders
|
this.loaders.css.importLoaders = this.loaders.cssModules.importLoaders = customLoaders.length
|
||||||
cssOptions.importLoaders = cssModulesOptions.importLoaders = customLoaders.length
|
|
||||||
|
|
||||||
const styleLoader = this.extract() || this.vueStyle()
|
const styleLoader = this.extract() || this.vueStyle()
|
||||||
|
|
||||||
@ -107,7 +109,7 @@ export default class StyleLoader {
|
|||||||
resourceQuery: /module/,
|
resourceQuery: /module/,
|
||||||
use: this.perfLoader.css().concat(
|
use: this.perfLoader.css().concat(
|
||||||
styleLoader,
|
styleLoader,
|
||||||
this.cssModules(cssModulesOptions),
|
this.cssModules(this.loaders.cssModules),
|
||||||
customLoaders
|
customLoaders
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -115,7 +117,7 @@ export default class StyleLoader {
|
|||||||
{
|
{
|
||||||
use: this.perfLoader.css().concat(
|
use: this.perfLoader.css().concat(
|
||||||
styleLoader,
|
styleLoader,
|
||||||
this.css(cssOptions),
|
this.css(this.loaders.css),
|
||||||
customLoaders
|
customLoaders
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
3
test/fixtures/basic/nuxt.config.js
vendored
3
test/fixtures/basic/nuxt.config.js
vendored
@ -77,7 +77,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
cssnano: {}
|
cssnano: {},
|
||||||
|
[path.resolve(__dirname, 'plugins', 'tailwind.js')]: {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
test/fixtures/basic/plugins/tailwind.js
vendored
Normal file
6
test/fixtures/basic/plugins/tailwind.js
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
const postcss = require('postcss')
|
||||||
|
|
||||||
|
module.exports = postcss.plugin('nuxt-test', () => {
|
||||||
|
return function () {}
|
||||||
|
})
|
@ -10,6 +10,7 @@ let transpile = null
|
|||||||
let output = null
|
let output = null
|
||||||
let loadersOptions
|
let loadersOptions
|
||||||
let vueLoader
|
let vueLoader
|
||||||
|
let postcssLoader
|
||||||
|
|
||||||
describe('basic dev', () => {
|
describe('basic dev', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
@ -40,6 +41,8 @@ describe('basic dev', () => {
|
|||||||
output = wpOutput
|
output = wpOutput
|
||||||
loadersOptions = loaders
|
loadersOptions = loaders
|
||||||
vueLoader = rules.find(loader => loader.test.test('.vue'))
|
vueLoader = rules.find(loader => loader.test.test('.vue'))
|
||||||
|
const cssLoaders = rules.find(loader => loader.test.test('.css')).oneOf[0].use
|
||||||
|
postcssLoader = cssLoaders[cssLoaders.length - 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,6 +85,19 @@ describe('basic dev', () => {
|
|||||||
expect(vueLoader.options).toBe(vue)
|
expect(vueLoader.options).toBe(vue)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Config: cssnano is at then end of postcss plugins', () => {
|
||||||
|
const plugins = postcssLoader.options.plugins.map((plugin) => {
|
||||||
|
return plugin.postcssPlugin
|
||||||
|
})
|
||||||
|
expect(plugins).toEqual([
|
||||||
|
'postcss-import',
|
||||||
|
'postcss-url',
|
||||||
|
'postcss-preset-env',
|
||||||
|
'nuxt-test',
|
||||||
|
'cssnano'
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
test('/stateless', async () => {
|
test('/stateless', async () => {
|
||||||
const window = await nuxt.server.renderAndGetWindow(url('/stateless'))
|
const window = await nuxt.server.renderAndGetWindow(url('/stateless'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
|
Loading…
Reference in New Issue
Block a user