2018-03-21 10:16:03 +00:00
|
|
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
2018-03-23 04:09:03 +00:00
|
|
|
import PostcssConfig from './postcss'
|
2017-08-14 14:03:07 +00:00
|
|
|
|
2018-03-23 04:09:03 +00:00
|
|
|
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
|
2018-09-10 08:27:01 +00:00
|
|
|
this.loaders = options.build.loaders
|
2018-03-23 04:09:03 +00:00
|
|
|
this.extractCSS = options.build.extractCSS
|
|
|
|
this.resources = options.build.styleResources
|
|
|
|
this.sourceMap = Boolean(options.build.cssSourceMap)
|
2017-12-28 15:30:31 +00:00
|
|
|
|
2018-03-23 04:09:03 +00:00
|
|
|
if (options.build.postcss) {
|
|
|
|
this.postcssConfig = new PostcssConfig(options, nuxt)
|
|
|
|
}
|
|
|
|
}
|
2017-12-28 15:30:31 +00:00
|
|
|
|
2018-03-23 04:09:03 +00:00
|
|
|
normalize(loaders) {
|
|
|
|
loaders = Array.isArray(loaders) ? loaders : [loaders]
|
2018-09-10 08:27:01 +00:00
|
|
|
return loaders.map(loader => (typeof loader === 'string' ? { loader } : loader))
|
2018-03-23 04:09:03 +00:00
|
|
|
}
|
2017-12-28 15:30:31 +00:00
|
|
|
|
2018-03-23 15:26:24 +00:00
|
|
|
styleResource(ext) {
|
2018-03-23 04:09:03 +00:00
|
|
|
const extResource = this.resources[ext]
|
2018-03-21 11:34:16 +00:00
|
|
|
// style-resources-loader
|
|
|
|
// https://github.com/yenshih/style-resources-loader
|
2018-03-23 04:09:03 +00:00
|
|
|
if (extResource) {
|
|
|
|
const patterns = Array.isArray(extResource)
|
|
|
|
? extResource
|
|
|
|
: [extResource]
|
2017-08-14 14:03:07 +00:00
|
|
|
|
2018-03-23 15:26:24 +00:00
|
|
|
return {
|
2018-03-21 11:34:16 +00:00
|
|
|
loader: 'style-resources-loader',
|
2018-03-23 04:09:03 +00:00
|
|
|
options: Object.assign(
|
|
|
|
{ patterns },
|
|
|
|
this.resources.options || {}
|
|
|
|
)
|
2018-03-23 15:26:24 +00:00
|
|
|
}
|
2017-12-28 16:05:34 +00:00
|
|
|
}
|
2018-03-23 04:09:03 +00:00
|
|
|
}
|
2017-08-14 14:03:07 +00:00
|
|
|
|
2018-03-23 15:26:24 +00:00
|
|
|
postcss() {
|
2018-03-21 11:34:16 +00:00
|
|
|
// postcss-loader
|
|
|
|
// https://github.com/postcss/postcss-loader
|
2018-03-23 04:09:03 +00:00
|
|
|
if (this.postcssConfig) {
|
|
|
|
const config = this.postcssConfig.config()
|
|
|
|
if (config) {
|
2018-03-23 15:26:24 +00:00
|
|
|
return {
|
2018-03-23 04:09:03 +00:00
|
|
|
loader: 'postcss-loader',
|
|
|
|
options: Object.assign({ sourceMap: this.sourceMap }, config)
|
2018-03-23 15:26:24 +00:00
|
|
|
}
|
2018-03-23 04:09:03 +00:00
|
|
|
}
|
2017-08-14 14:03:07 +00:00
|
|
|
}
|
2018-03-23 04:09:03 +00:00
|
|
|
}
|
2017-08-14 14:03:07 +00:00
|
|
|
|
2018-09-10 08:27:01 +00:00
|
|
|
css(options) {
|
2018-03-23 15:26:24 +00:00
|
|
|
return {
|
2018-03-23 20:37:59 +00:00
|
|
|
loader: (this.isServer && this.extractCSS) ? 'css-loader/locals' : 'css-loader',
|
2018-09-19 08:46:21 +00:00
|
|
|
options
|
2018-03-23 15:26:24 +00:00
|
|
|
}
|
2018-03-23 04:09:03 +00:00
|
|
|
}
|
2018-03-21 11:34:16 +00:00
|
|
|
|
2018-09-10 08:27:01 +00:00
|
|
|
cssModules(options) {
|
|
|
|
options.modules = true
|
2018-10-11 21:53:02 +00:00
|
|
|
return {
|
|
|
|
loader: 'css-loader',
|
|
|
|
options
|
|
|
|
}
|
2018-09-10 08:27:01 +00:00
|
|
|
}
|
|
|
|
|
2018-03-23 15:26:24 +00:00
|
|
|
extract() {
|
2018-03-23 20:37:59 +00:00
|
|
|
if (this.extractCSS && !this.isServer) {
|
2018-03-23 15:26:24 +00:00
|
|
|
return MiniCssExtractPlugin.loader
|
2018-03-23 04:09:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-23 15:26:24 +00:00
|
|
|
vueStyle() {
|
2018-03-23 04:09:03 +00:00
|
|
|
// https://github.com/vuejs/vue-style-loader
|
2018-03-23 15:26:24 +00:00
|
|
|
return {
|
2018-03-23 04:09:03 +00:00
|
|
|
loader: 'vue-style-loader',
|
2018-09-10 08:27:01 +00:00
|
|
|
options: this.loaders.vueStyle
|
2018-03-23 15:26:24 +00:00
|
|
|
}
|
2018-03-23 04:09:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
apply(ext, loaders = []) {
|
2018-03-29 19:26:42 +00:00
|
|
|
const customLoaders = [].concat(
|
2018-03-23 15:26:24 +00:00
|
|
|
this.postcss(loaders),
|
2018-04-11 08:21:30 +00:00
|
|
|
this.normalize(loaders),
|
|
|
|
this.styleResource(ext)
|
2018-03-23 15:26:24 +00:00
|
|
|
).filter(Boolean)
|
2018-03-23 04:09:03 +00:00
|
|
|
|
2018-09-10 08:27:01 +00:00
|
|
|
const { css: cssOptions, cssModules: cssModulesOptions } = this.loaders
|
|
|
|
cssOptions.importLoaders = cssModulesOptions.importLoaders = customLoaders.length
|
|
|
|
|
2018-03-29 19:26:42 +00:00
|
|
|
const styleLoader = this.extract() || this.vueStyle()
|
|
|
|
|
|
|
|
return [
|
|
|
|
// This matches <style module>
|
|
|
|
{
|
|
|
|
resourceQuery: /module/,
|
|
|
|
use: [].concat(
|
|
|
|
styleLoader,
|
2018-09-10 08:27:01 +00:00
|
|
|
this.cssModules(cssModulesOptions),
|
2018-03-29 19:26:42 +00:00
|
|
|
customLoaders
|
|
|
|
)
|
|
|
|
},
|
|
|
|
// This matches plain <style> or <style scoped>
|
|
|
|
{
|
|
|
|
use: [].concat(
|
|
|
|
styleLoader,
|
2018-09-10 08:27:01 +00:00
|
|
|
this.css(cssOptions),
|
2018-03-29 19:26:42 +00:00
|
|
|
customLoaders
|
|
|
|
)
|
|
|
|
}
|
|
|
|
]
|
2017-11-20 23:56:14 +00:00
|
|
|
}
|
2017-08-14 14:03:07 +00:00
|
|
|
}
|