refactor: styleLoader and postcss (#4318)

This commit is contained in:
Clark Du 2018-11-12 21:18:50 +00:00 committed by GitHub
parent 5f8d26175a
commit 853ca4e7d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 9 deletions

View File

@ -7,6 +7,16 @@ import createResolver from 'postcss-import-resolver'
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 {
constructor(options, nuxt) {
this.nuxt = nuxt
@ -45,7 +55,9 @@ export default class PostcssConfig {
// https://github.com/csstools/postcss-preset-env
'postcss-preset-env': this.preset || {},
'cssnano': this.dev ? false : { preset: 'default' }
}
},
// Array, String or Function
order: 'cssnanoLast'
}
}
@ -87,11 +99,19 @@ export default class PostcssConfig {
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) {
const plugins = config.plugins
if (isPureObject(plugins)) {
// Map postcss plugins into instances on object mode once
config.plugins = Object.keys(plugins)
config.plugins = this.sortPlugins(config)
.map((p) => {
const plugin = require(p)
const opts = plugins[p]

View File

@ -14,7 +14,10 @@ export default class StyleLoader {
this.assetsDir = options.dir.assets
this.staticDir = options.dir.static
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.resources = options.build.styleResources
this.sourceMap = Boolean(options.build.cssSourceMap)
@ -91,13 +94,12 @@ export default class StyleLoader {
apply(ext, loaders = []) {
const customLoaders = [].concat(
this.postcss(loaders),
this.postcss(),
this.normalize(loaders),
this.styleResource(ext)
).filter(Boolean)
const { css: cssOptions, cssModules: cssModulesOptions } = this.loaders
cssOptions.importLoaders = cssModulesOptions.importLoaders = customLoaders.length
this.loaders.css.importLoaders = this.loaders.cssModules.importLoaders = customLoaders.length
const styleLoader = this.extract() || this.vueStyle()
@ -107,7 +109,7 @@ export default class StyleLoader {
resourceQuery: /module/,
use: this.perfLoader.css().concat(
styleLoader,
this.cssModules(cssModulesOptions),
this.cssModules(this.loaders.cssModules),
customLoaders
)
},
@ -115,7 +117,7 @@ export default class StyleLoader {
{
use: this.perfLoader.css().concat(
styleLoader,
this.css(cssOptions),
this.css(this.loaders.css),
customLoaders
)
}

View File

@ -77,7 +77,8 @@ export default {
}
},
plugins: {
cssnano: {}
cssnano: {},
[path.resolve(__dirname, 'plugins', 'tailwind.js')]: {}
}
}
}

View File

@ -0,0 +1,6 @@
const postcss = require('postcss')
module.exports = postcss.plugin('nuxt-test', () => {
return function () {}
})

View File

@ -10,6 +10,7 @@ let transpile = null
let output = null
let loadersOptions
let vueLoader
let postcssLoader
describe('basic dev', () => {
beforeAll(async () => {
@ -40,6 +41,8 @@ describe('basic dev', () => {
output = wpOutput
loadersOptions = loaders
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)
})
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 () => {
const window = await nuxt.server.renderAndGetWindow(url('/stateless'))
const html = window.document.body.innerHTML