Nuxt/lib/builder/webpack/utils/style-loader.js

111 lines
2.7 KiB
JavaScript

import path from 'path'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import PostcssConfig from './postcss'
export default class StyleLoader {
constructor(options, nuxt, { isServer }) {
this.isServer = isServer
this.dev = options.dev
this.srcDir = options.srcDir
this.assetsDir = options.dir.assets
this.staticDir = options.dir.static
this.extractCSS = options.build.extractCSS
this.resources = options.build.styleResources
this.sourceMap = Boolean(options.build.cssSourceMap)
if (options.build.postcss) {
this.postcssConfig = new PostcssConfig(options, nuxt)
}
}
normalize(loaders) {
loaders = Array.isArray(loaders) ? loaders : [loaders]
return loaders.map(loader => Object.assign(
{ options: { sourceMap: this.sourceMap } },
typeof loader === 'string' ? { loader } : loader
))
}
styleResource(ext) {
const extResource = this.resources[ext]
// style-resources-loader
// https://github.com/yenshih/style-resources-loader
if (extResource) {
const patterns = Array.isArray(extResource)
? extResource
: [extResource]
return {
loader: 'style-resources-loader',
options: Object.assign(
{ patterns },
this.resources.options || {}
)
}
}
}
postcss() {
// postcss-loader
// https://github.com/postcss/postcss-loader
if (this.postcssConfig) {
const config = this.postcssConfig.config()
if (config) {
return {
loader: 'postcss-loader',
options: Object.assign({ sourceMap: this.sourceMap }, config)
}
}
}
}
css(importLoaders) {
// css-loader
// https://github.com/webpack-contrib/css-loader
const cssLoaderAlias = {
[`/${this.assetsDir}`]: path.join(this.srcDir, this.assetsDir),
[`/${this.staticDir}`]: path.join(this.srcDir, this.staticDir)
}
return {
loader: 'css-loader',
options: {
sourceMap: this.sourceMap,
minimize: !this.dev,
importLoaders: importLoaders,
alias: cssLoaderAlias
}
}
}
extract() {
if (this.extractCSS) {
return MiniCssExtractPlugin.loader
}
}
vueStyle() {
// https://github.com/vuejs/vue-style-loader
return {
loader: 'vue-style-loader',
options: { sourceMap: this.sourceMap }
}
}
apply(ext, loaders = []) {
const _customLoaders = [].concat(
this.postcss(loaders),
this.styleResource(ext),
this.normalize(loaders)
).filter(Boolean)
return [].concat(
this.extract() || this.vueStyle(),
this.css(_customLoaders.length),
_customLoaders
).filter(Boolean)
}
}