refactor(builder): remove buildContext (#25)

This commit is contained in:
Xin Du (Clark) 2020-08-18 21:33:58 +01:00 committed by GitHub
parent d1718230ed
commit f6355ca65d
8 changed files with 108 additions and 94 deletions

View File

@ -81,13 +81,5 @@ export async function generate (builder: Builder) {
} }
async function bundle ({ nuxt }: Builder) { async function bundle ({ nuxt }: Builder) {
// TODO: get rid of this context and directly pass nuxt to BundleBuilder await new BundleBuilder(nuxt).build()
const bundleBuilder = new BundleBuilder({
nuxt,
options: nuxt.options,
buildOptions: nuxt.options.build,
target: nuxt.options.target,
plugins: []
})
await bundleBuilder.build()
} }

View File

@ -6,6 +6,7 @@ import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware' import webpackHotMiddleware from 'webpack-hot-middleware'
import consola from 'consola' import consola from 'consola'
import { Nuxt } from 'src/core'
import { TARGETS, parallel, sequence, wrapArray, isModernRequest } from 'src/utils' import { TARGETS, parallel, sequence, wrapArray, isModernRequest } from 'src/utils'
import { createMFS } from './utils/mfs' import { createMFS } from './utils/mfs'
@ -15,8 +16,13 @@ import PerfLoader from './utils/perf-loader'
const glob = pify(Glob) const glob = pify(Glob)
export class WebpackBundler { export class WebpackBundler {
constructor (buildContext) { nuxt: Nuxt
this.buildContext = buildContext plugins: Array<string>
constructor (nuxt) {
this.nuxt = nuxt
// TODO: plugins
this.plugins = []
// Class fields // Class fields
this.compilers = [] this.compilers = []
@ -28,7 +34,7 @@ export class WebpackBundler {
this.middleware = this.middleware.bind(this) this.middleware = this.middleware.bind(this)
// Initialize shared MFS for dev // Initialize shared MFS for dev
if (this.buildContext.options.dev) { if (this.nuxt.options.dev) {
this.mfs = createMFS() this.mfs = createMFS()
} }
} }
@ -43,7 +49,7 @@ export class WebpackBundler {
} }
async build () { async build () {
const { options } = this.buildContext const { options } = this.nuxt
const webpackConfigs = [ const webpackConfigs = [
this.getWebpackConfig('Client') this.getWebpackConfig('Client')
@ -57,10 +63,10 @@ export class WebpackBundler {
webpackConfigs.push(this.getWebpackConfig('Server')) webpackConfigs.push(this.getWebpackConfig('Server'))
} }
await this.buildContext.nuxt.callHook('webpack:config', webpackConfigs) await this.nuxt.callHook('webpack:config', webpackConfigs)
// Check styleResource existence // Check styleResource existence
const { styleResources } = this.buildContext.options.build const { styleResources } = this.nuxt.options.build
if (styleResources && Object.keys(styleResources).length) { if (styleResources && Object.keys(styleResources).length) {
consola.warn( consola.warn(
'Using styleResources without the @nuxtjs/style-resources is not suggested and can lead to severe performance issues.', 'Using styleResources without the @nuxtjs/style-resources is not suggested and can lead to severe performance issues.',
@ -68,7 +74,7 @@ export class WebpackBundler {
) )
for (const ext of Object.keys(styleResources)) { for (const ext of Object.keys(styleResources)) {
await Promise.all(wrapArray(styleResources[ext]).map(async (p) => { await Promise.all(wrapArray(styleResources[ext]).map(async (p) => {
const styleResourceFiles = await glob(path.resolve(this.buildContext.options.rootDir, p)) const styleResourceFiles = await glob(path.resolve(this.nuxt.options.rootDir, p))
if (!styleResourceFiles || styleResourceFiles.length === 0) { if (!styleResourceFiles || styleResourceFiles.length === 0) {
throw new Error(`Style Resource not found: ${p}`) throw new Error(`Style Resource not found: ${p}`)
@ -104,20 +110,20 @@ export class WebpackBundler {
async webpackCompile (compiler) { async webpackCompile (compiler) {
const { name } = compiler.options const { name } = compiler.options
const { nuxt, options } = this.buildContext const { options } = this.nuxt
await nuxt.callHook('build:compile', { name, compiler }) await this.nuxt.callHook('build:compile', { name, compiler })
// Load renderer resources after build // Load renderer resources after build
compiler.hooks.done.tap('load-resources', async (stats) => { compiler.hooks.done.tap('load-resources', async (stats) => {
await nuxt.callHook('build:compiled', { await this.nuxt.callHook('build:compiled', {
name, name,
compiler, compiler,
stats stats
}) })
// Reload renderer // Reload renderer
await nuxt.callHook('build:resources', this.mfs) await this.nuxt.callHook('build:resources', this.mfs)
}) })
// --- Dev Build --- // --- Dev Build ---
@ -160,14 +166,14 @@ export class WebpackBundler {
} }
// Await for renderer to load resources (programmatic, tests and generate) // Await for renderer to load resources (programmatic, tests and generate)
await nuxt.callHook('build:resources') await this.nuxt.callHook('build:resources')
} }
async webpackDev (compiler) { async webpackDev (compiler) {
consola.debug('Creating webpack middleware...') consola.debug('Creating webpack middleware...')
const { name } = compiler.options const { name } = compiler.options
const buildOptions = this.buildContext.options.build const buildOptions = this.nuxt.options.build
const { client, ...hotMiddlewareOptions } = buildOptions.hotMiddleware || {} const { client, ...hotMiddlewareOptions } = buildOptions.hotMiddleware || {}
// Create webpack dev middleware // Create webpack dev middleware
@ -177,7 +183,7 @@ export class WebpackBundler {
publicPath: buildOptions.publicPath, publicPath: buildOptions.publicPath,
stats: false, stats: false,
logLevel: 'silent', logLevel: 'silent',
watchOptions: this.buildContext.options.watchers.webpack, watchOptions: this.nuxt.options.watchers.webpack,
fs: this.mfs, fs: this.mfs,
...buildOptions.devMiddleware ...buildOptions.devMiddleware
}) })
@ -198,11 +204,11 @@ export class WebpackBundler {
) )
// Register devMiddleware on server // Register devMiddleware on server
await this.buildContext.nuxt.callHook('server:devMiddleware', this.middleware) await this.nuxt.callHook('server:devMiddleware', this.middleware)
} }
async middleware (req, res, next) { async middleware (req, res, next) {
const name = isModernRequest(req, this.buildContext.options.modern) ? 'modern' : 'client' const name = isModernRequest(req, this.nuxt.options.modern) ? 'modern' : 'client'
if (this.devMiddleware && this.devMiddleware[name]) { if (this.devMiddleware && this.devMiddleware[name]) {
await this.devMiddleware[name](req, res) await this.devMiddleware[name](req, res)
@ -251,6 +257,6 @@ export class WebpackBundler {
} }
forGenerate () { forGenerate () {
this.buildContext.target = TARGETS.static this.nuxt.options.target = TARGETS.static
} }
} }

View File

@ -10,6 +10,7 @@ import TerserWebpackPlugin from 'terser-webpack-plugin'
import WebpackBar from 'webpackbar' import WebpackBar from 'webpackbar'
import env from 'std-env' import env from 'std-env'
import semver from 'semver' import semver from 'semver'
import type { NormalizedConfiguration } from 'src/config'
import { TARGETS, isUrl, urlJoin, getPKG } from 'src/utils' import { TARGETS, isUrl, urlJoin, getPKG } from 'src/utils'
import PerfLoader from '../utils/perf-loader' import PerfLoader from '../utils/perf-loader'
import StyleLoader from '../utils/style-loader' import StyleLoader from '../utils/style-loader'
@ -17,9 +18,11 @@ import WarningIgnorePlugin from '../plugins/warning-ignore'
import { reservedVueTags } from '../utils/reserved-tags' import { reservedVueTags } from '../utils/reserved-tags'
export default class WebpackBaseConfig { export default class WebpackBaseConfig {
options: NormalizedConfiguration
constructor (builder) { constructor (builder) {
this.builder = builder this.builder = builder
this.buildContext = builder.buildContext this.options = builder.nuxt.options
} }
get colors () { get colors () {
@ -49,16 +52,16 @@ export default class WebpackBaseConfig {
} }
get target () { get target () {
return this.buildContext.target return this.options.target
} }
get dev () { get dev () {
return this.buildContext.options.dev return this.options.dev
} }
get loaders () { get loaders () {
if (!this._loaders) { if (!this._loaders) {
this._loaders = cloneDeep(this.buildContext.buildOptions.loaders) this._loaders = cloneDeep(this.options.build.loaders)
// sass-loader<8 support (#6460) // sass-loader<8 support (#6460)
const sassLoaderPKG = getPKG('sass-loader') const sassLoaderPKG = getPKG('sass-loader')
if (sassLoaderPKG && semver.lt(sassLoaderPKG.version, '8.0.0')) { if (sassLoaderPKG && semver.lt(sassLoaderPKG.version, '8.0.0')) {
@ -80,7 +83,7 @@ export default class WebpackBaseConfig {
normalizeTranspile ({ pathNormalize = false } = {}) { normalizeTranspile ({ pathNormalize = false } = {}) {
const transpile = [] const transpile = []
for (let pattern of this.buildContext.buildOptions.transpile) { for (let pattern of this.options.build.transpile) {
if (typeof pattern === 'function') { if (typeof pattern === 'function') {
pattern = pattern(this.nuxtEnv) pattern = pattern(this.nuxtEnv)
} }
@ -99,7 +102,7 @@ export default class WebpackBaseConfig {
getBabelOptions () { getBabelOptions () {
const envName = this.name const envName = this.name
const options = { const options = {
...this.buildContext.buildOptions.babel, ...this.options.build.babel,
envName envName
} }
@ -136,7 +139,7 @@ export default class WebpackBaseConfig {
} }
getFileName (key) { getFileName (key) {
let fileName = this.buildContext.buildOptions.filenames[key] let fileName = this.options.build.filenames[key]
if (typeof fileName === 'function') { if (typeof fileName === 'function') {
fileName = fileName(this.nuxtEnv) fileName = fileName(this.nuxtEnv)
} }
@ -158,13 +161,13 @@ export default class WebpackBaseConfig {
'process.static': this.target === TARGETS.static, 'process.static': this.target === TARGETS.static,
'process.target': JSON.stringify(this.target) 'process.target': JSON.stringify(this.target)
} }
if (this.buildContext.buildOptions.aggressiveCodeRemoval) { if (this.options.build.aggressiveCodeRemoval) {
env['typeof process'] = JSON.stringify(this.isServer ? 'object' : 'undefined') env['typeof process'] = JSON.stringify(this.isServer ? 'object' : 'undefined')
env['typeof window'] = JSON.stringify(!this.isServer ? 'object' : 'undefined') env['typeof window'] = JSON.stringify(!this.isServer ? 'object' : 'undefined')
env['typeof document'] = JSON.stringify(!this.isServer ? 'object' : 'undefined') env['typeof document'] = JSON.stringify(!this.isServer ? 'object' : 'undefined')
} }
Object.entries(this.buildContext.options.env).forEach(([key, value]) => { Object.entries(this.options.env).forEach(([key, value]) => {
env['process.env.' + key] = env['process.env.' + key] =
['boolean', 'number'].includes(typeof value) ['boolean', 'number'].includes(typeof value)
? value ? value
@ -175,9 +178,10 @@ export default class WebpackBaseConfig {
output () { output () {
const { const {
options: { buildDir, router }, build: { publicPath },
buildOptions: { publicPath } buildDir,
} = this.buildContext router
} = this.options
return { return {
path: path.resolve(buildDir, 'dist', this.isServer ? 'server' : 'client'), path: path.resolve(buildDir, 'dist', this.isServer ? 'server' : 'client'),
filename: this.getFileName('app'), filename: this.getFileName('app'),
@ -187,7 +191,7 @@ export default class WebpackBaseConfig {
} }
cache () { cache () {
if (!this.buildContext.buildOptions.cache) { if (!this.options.build.cache) {
return false return false
} }
@ -195,15 +199,15 @@ export default class WebpackBaseConfig {
type: 'filesystem', type: 'filesystem',
cacheDirectory: path.resolve('node_modules/.cache/@nuxt/webpack/'), cacheDirectory: path.resolve('node_modules/.cache/@nuxt/webpack/'),
buildDependencies: { buildDependencies: {
config: [...this.buildContext.options._nuxtConfigFiles] config: [...this.options._nuxtConfigFiles]
}, },
...this.buildContext.buildOptions.cache, ...this.options.build.cache,
name: this.name name: this.name
} }
} }
optimization () { optimization () {
const optimization = cloneDeep(this.buildContext.buildOptions.optimization) const optimization = cloneDeep(this.options.build.optimization)
if (optimization.minimize && optimization.minimizer === undefined) { if (optimization.minimize && optimization.minimizer === undefined) {
optimization.minimizer = this.minimizer() optimization.minimizer = this.minimizer()
@ -214,7 +218,7 @@ export default class WebpackBaseConfig {
resolve () { resolve () {
// Prioritize nested node_modules in webpack search path (#2558) // Prioritize nested node_modules in webpack search path (#2558)
const webpackModulesDir = ['node_modules'].concat(this.buildContext.options.modulesDir) const webpackModulesDir = ['node_modules'].concat(this.options.modulesDir)
return { return {
resolve: { resolve: {
@ -230,7 +234,7 @@ export default class WebpackBaseConfig {
minimizer () { minimizer () {
const minimizer = [] const minimizer = []
const { terser, cache } = this.buildContext.buildOptions const { terser, cache } = this.options.build
// https://github.com/webpack-contrib/terser-webpack-plugin // https://github.com/webpack-contrib/terser-webpack-plugin
if (terser) { if (terser) {
@ -258,17 +262,17 @@ export default class WebpackBaseConfig {
alias () { alias () {
return { return {
...this.buildContext.options.alias, ...this.options.alias,
app: this.buildContext.options.appDir, app: this.options.appDir,
'nuxt-build': this.buildContext.options.buildDir, 'nuxt-build': this.options.buildDir,
'vue-meta': require.resolve(`vue-meta${this.isServer ? '' : '/dist/vue-meta.esm.browser.js'}`) 'vue-meta': require.resolve(`vue-meta${this.isServer ? '' : '/dist/vue-meta.esm.browser.js'}`)
} }
} }
rules () { rules () {
const perfLoader = new PerfLoader(this.name, this.buildContext) const perfLoader = new PerfLoader(this.name, this.options)
const styleLoader = new StyleLoader( const styleLoader = new StyleLoader(
this.buildContext, this.builder.nuxt,
{ isServer: this.isServer, perfLoader } { isServer: this.isServer, perfLoader }
) )
@ -390,7 +394,8 @@ export default class WebpackBaseConfig {
plugins () { plugins () {
const plugins = [] const plugins = []
const { nuxt, buildOptions } = this.buildContext const { nuxt } = this.builder
const { build: buildOptions } = this.options
// Add timefix-plugin before others plugins // Add timefix-plugin before others plugins
if (this.dev) { if (this.dev) {
@ -431,8 +436,8 @@ export default class WebpackBaseConfig {
nuxt.callHook('bundler:change', shortPath) nuxt.callHook('bundler:change', shortPath)
} }
}, },
done: (buildContext) => { done: (stats) => {
if (buildContext.hasErrors) { if (stats.hasErrors) {
nuxt.callHook('bundler:error') nuxt.callHook('bundler:error')
} }
}, },
@ -446,13 +451,13 @@ export default class WebpackBaseConfig {
})) }))
// CSS extraction // CSS extraction
if (this.buildContext.buildOptions.extractCSS) { if (this.options.build.extractCSS) {
plugins.push(new MiniCssExtractPlugin(Object.assign({ plugins.push(new MiniCssExtractPlugin(Object.assign({
filename: this.getFileName('css'), filename: this.getFileName('css'),
chunkFilename: this.getFileName('css'), chunkFilename: this.getFileName('css'),
// TODO: https://github.com/faceyspacey/extract-css-chunks-webpack-plugin/issues/132 // TODO: https://github.com/faceyspacey/extract-css-chunks-webpack-plugin/issues/132
reloadAll: true reloadAll: true
}, this.buildContext.buildOptions.extractCSS))) }, this.options.build.extractCSS)))
} }
return plugins return plugins
@ -464,14 +469,14 @@ export default class WebpackBaseConfig {
warn => warn.name === 'ModuleDependencyWarning' && warn => warn.name === 'ModuleDependencyWarning' &&
warn.message.includes('export \'default\'') && warn.message.includes('export \'default\'') &&
warn.message.includes('nuxt_plugin_'), warn.message.includes('nuxt_plugin_'),
...(this.buildContext.buildOptions.warningIgnoreFilters || []) ...(this.options.build.warningIgnoreFilters || [])
] ]
return warn => !filters.some(ignoreFilter => ignoreFilter(warn)) return warn => !filters.some(ignoreFilter => ignoreFilter(warn))
} }
extendConfig (config) { extendConfig (config) {
const { extend } = this.buildContext.buildOptions const { extend } = this.options.build
if (typeof extend === 'function') { if (typeof extend === 'function') {
const extendedConfig = extend.call( const extendedConfig = extend.call(
this.builder, config, { loaders: this.loaders, ...this.nuxtEnv } this.builder, config, { loaders: this.loaders, ...this.nuxtEnv }

View File

@ -31,8 +31,8 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
} }
getCspScriptPolicy () { getCspScriptPolicy () {
const { csp } = this.buildContext.options.render const { csp } = this.options.render
if (csp) { if (typeof csp === 'object') {
const { policies = {} } = csp const { policies = {} } = csp
return policies['script-src'] || policies['default-src'] || [] return policies['script-src'] || policies['default-src'] || []
} }
@ -59,7 +59,7 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
// Small, known and common modules which are usually used project-wise // Small, known and common modules which are usually used project-wise
// Sum of them may not be more than 244 KiB // Sum of them may not be more than 244 KiB
if ( if (
this.buildContext.buildOptions.splitChunks.commons === true && this.options.build.splitChunks.commons === true &&
cacheGroups.commons === undefined cacheGroups.commons === undefined
) { ) {
cacheGroups.commons = { cacheGroups.commons = {
@ -89,7 +89,7 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
minimizer () { minimizer () {
const minimizer = super.minimizer() const minimizer = super.minimizer()
const { optimizeCSS } = this.buildContext.buildOptions const { optimizeCSS } = this.options.build
// https://github.com/NMFR/optimize-css-assets-webpack-plugin // https://github.com/NMFR/optimize-css-assets-webpack-plugin
// https://github.com/webpack-contrib/mini-css-extract-plugin#minimizing-for-production // https://github.com/webpack-contrib/mini-css-extract-plugin#minimizing-for-production
@ -104,7 +104,7 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
alias () { alias () {
const aliases = super.alias() const aliases = super.alias()
for (const p of this.buildContext.plugins) { for (const p of this.builder.plugins) {
if (!aliases[p.name]) { if (!aliases[p.name]) {
// Do not load server-side plugins on client-side // Do not load server-side plugins on client-side
aliases[p.name] = p.mode === 'server' ? './empty.js' : p.src aliases[p.name] = p.mode === 'server' ? './empty.js' : p.src
@ -116,7 +116,7 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
plugins () { plugins () {
const plugins = super.plugins() const plugins = super.plugins()
const { buildOptions, options: { appTemplatePath, buildDir, modern, render } } = this.buildContext const { build: buildOptions, appTemplatePath, buildDir, modern, render } = this.options
// Generate output HTML for SSR // Generate output HTML for SSR
if (buildOptions.ssr) { if (buildOptions.ssr) {
@ -185,9 +185,10 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
config () { config () {
const config = super.config() const config = super.config()
const { const {
options: { router, buildDir }, router,
buildOptions: { hotMiddleware, quiet, friendlyErrors } buildDir,
} = this.buildContext build: { hotMiddleware, quiet, friendlyErrors }
} = this.options
const { client = {} } = hotMiddleware || {} const { client = {} } = hotMiddleware || {}
const { ansiColors, overlayStyles, ...options } = client const { ansiColors, overlayStyles, ...options } = client

View File

@ -59,7 +59,7 @@ export default class WebpackServerConfig extends WebpackBaseConfig {
} }
optimization () { optimization () {
const { _minifyServer } = this.buildContext.buildOptions const { _minifyServer } = this.options.build
return { return {
splitChunks: false, splitChunks: false,
@ -78,7 +78,7 @@ export default class WebpackServerConfig extends WebpackBaseConfig {
alias () { alias () {
const aliases = super.alias() const aliases = super.alias()
for (const p of this.buildContext.plugins) { for (const p of this.builder.plugins) {
if (!aliases[p.name]) { if (!aliases[p.name]) {
// Do not load client-side plugins on server-side // Do not load client-side plugins on server-side
aliases[p.name] = p.mode === 'client' ? './empty.js' : p.src aliases[p.name] = p.mode === 'client' ? './empty.js' : p.src
@ -95,7 +95,7 @@ export default class WebpackServerConfig extends WebpackBaseConfig {
new DefinePlugin(this.env()) new DefinePlugin(this.env())
) )
const { serverURLPolyfill } = this.buildContext.options.build const { serverURLPolyfill } = this.options.build
if (serverURLPolyfill) { if (serverURLPolyfill) {
plugins.push(new ProvidePlugin({ plugins.push(new ProvidePlugin({
@ -114,7 +114,7 @@ export default class WebpackServerConfig extends WebpackBaseConfig {
target: 'node', target: 'node',
node: false, node: false,
entry: Object.assign({}, config.entry, { entry: Object.assign({}, config.entry, {
app: [path.resolve(this.buildContext.options.buildDir, 'entry.server.ts')] app: [path.resolve(this.options.buildDir, 'entry.server.ts')]
}), }),
output: Object.assign({}, config.output, { output: Object.assign({}, config.output, {
filename: 'server.js', filename: 'server.js',
@ -132,8 +132,8 @@ export default class WebpackServerConfig extends WebpackBaseConfig {
// https://webpack.js.org/configuration/externals/#externals // https://webpack.js.org/configuration/externals/#externals
// https://github.com/liady/webpack-node-externals // https://github.com/liady/webpack-node-externals
// https://vue-loader.vuejs.org/migrating.html#ssr-externals // https://vue-loader.vuejs.org/migrating.html#ssr-externals
if (!this.buildContext.buildOptions.standalone) { if (!this.options.build.standalone) {
this.buildContext.options.modulesDir.forEach((dir) => { this.options.modulesDir.forEach((dir) => {
if (fs.existsSync(dir)) { if (fs.existsSync(dir)) {
config.externals.push( config.externals.push(
nodeExternals({ nodeExternals({

View File

@ -3,10 +3,10 @@ import { warmup } from 'thread-loader'
// https://github.com/webpack-contrib/thread-loader // https://github.com/webpack-contrib/thread-loader
export default class PerfLoader { export default class PerfLoader {
constructor (name, buildContext) { constructor (name, options) {
this.name = name this.name = name
this.buildContext = buildContext this.options = options
this.workerPools = PerfLoader.defaultPools({ dev: buildContext.options.dev }) this.workerPools = PerfLoader.defaultPools({ dev: options.dev })
return new Proxy(this, { return new Proxy(this, {
get (target, name) { get (target, name) {
return target[name] ? target[name] : target.use.bind(target, name) return target[name] ? target[name] : target.use.bind(target, name)
@ -38,7 +38,7 @@ export default class PerfLoader {
use (poolName) { use (poolName) {
const loaders = [] const loaders = []
if (this.buildContext.buildOptions) { if (this.options.build.buildOptions) {
const pool = this.workerPools[poolName] const pool = this.workerPools[poolName]
if (pool) { if (pool) {
loaders.push({ loaders.push({

View File

@ -6,6 +6,8 @@ import merge from 'lodash/merge'
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
import createResolver from 'postcss-import-resolver' import createResolver from 'postcss-import-resolver'
import type { Nuxt } from 'src/core'
import type { NormalizedConfiguration } from 'src/config'
import { isPureObject } from 'src/utils' import { isPureObject } from 'src/utils'
export const orderPresets = { export const orderPresets = {
@ -37,16 +39,20 @@ function postcssConfigFileWarning () {
} }
export default class PostcssConfig { export default class PostcssConfig {
constructor (buildContext) { nuxt: Nuxt
this.buildContext = buildContext options: NormalizedConfiguration
constructor (nuxt) {
this.nuxt = nuxt
this.options = nuxt.options
} }
get postcssOptions () { get postcssOptions () {
return this.buildContext.buildOptions.postcss return this.options.build.postcss
} }
get postcssImportAlias () { get postcssImportAlias () {
const alias = { ...this.buildContext.options.alias } const alias = { ...this.options.alias }
for (const key in alias) { for (const key in alias) {
if (key.startsWith('~')) { if (key.startsWith('~')) {
@ -62,9 +68,9 @@ export default class PostcssConfig {
} }
get defaultConfig () { get defaultConfig () {
const { dev, srcDir, rootDir, modulesDir } = this.buildContext.options const { dev, srcDir, rootDir, modulesDir } = this.options
return { return {
sourceMap: this.buildContext.buildOptions.cssSourceMap, sourceMap: this.options.build.cssSourceMap,
plugins: { plugins: {
// https://github.com/postcss/postcss-import // https://github.com/postcss/postcss-import
'postcss-import': { 'postcss-import': {
@ -90,7 +96,7 @@ export default class PostcssConfig {
// Search for postCSS config file and use it if exists // Search for postCSS config file and use it if exists
// https://github.com/michael-ciniawsky/postcss-load-config // https://github.com/michael-ciniawsky/postcss-load-config
// TODO: Remove in Nuxt 3 // TODO: Remove in Nuxt 3
const { srcDir, rootDir } = this.buildContext.options const { srcDir, rootDir } = this.options
for (const dir of [srcDir, rootDir]) { for (const dir of [srcDir, rootDir]) {
for (const file of [ for (const file of [
'postcss.config.js', 'postcss.config.js',
@ -114,7 +120,7 @@ export default class PostcssConfig {
if (loaderConfig.path) { if (loaderConfig.path) {
return { return {
sourceMap: this.buildContext.buildOptions.cssSourceMap, sourceMap: this.options.build.cssSourceMap,
config: loaderConfig config: loaderConfig
} }
} }
@ -144,7 +150,7 @@ export default class PostcssConfig {
// Map postcss plugins into instances on object mode once // Map postcss plugins into instances on object mode once
config.plugins = this.sortPlugins(config) config.plugins = this.sortPlugins(config)
.map((p) => { .map((p) => {
const plugin = this.buildContext.nuxt.resolver.requireModule(p) const plugin = this.nuxt.resolver.requireModule(p)
const opts = plugins[p] const opts = plugins[p]
if (opts === false) { if (opts === false) {
return // Disabled return // Disabled

View File

@ -2,23 +2,27 @@ import path from 'path'
// import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin' // import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin'
import MiniCssExtractPlugin from 'mini-css-extract-plugin' import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import type { Nuxt } from 'src/core'
import type { NormalizedConfiguration } from 'src/config'
import { wrapArray } from 'src/utils' import { wrapArray } from 'src/utils'
import PostcssConfig from './postcss' import PostcssConfig from './postcss'
export default class StyleLoader { export default class StyleLoader {
constructor (buildContext, { isServer, perfLoader }) { options: NormalizedConfiguration
this.buildContext = buildContext
constructor (nuxt: Nuxt, { isServer, perfLoader }) {
this.options = nuxt.options
this.isServer = isServer this.isServer = isServer
this.perfLoader = perfLoader this.perfLoader = perfLoader
if (buildContext.options.build.postcss) { if (this.options.build.postcss) {
this.postcssConfig = new PostcssConfig(buildContext) this.postcssConfig = new PostcssConfig(nuxt)
} }
} }
get extractCSS () { get extractCSS () {
return this.buildContext.buildOptions.extractCSS return this.options.build.extractCSS
} }
get onlyLocals () { get onlyLocals () {
@ -32,7 +36,7 @@ export default class StyleLoader {
} }
styleResource (ext) { styleResource (ext) {
const { buildOptions: { styleResources }, options: { rootDir } } = this.buildContext const { build: { styleResources }, rootDir } = this.options
const extResource = styleResources[ext] const extResource = styleResources[ext]
// style-resources-loader // style-resources-loader
// https://github.com/yenshih/style-resources-loader // https://github.com/yenshih/style-resources-loader
@ -65,7 +69,7 @@ export default class StyleLoader {
return { return {
loader: 'postcss-loader', loader: 'postcss-loader',
options: Object.assign({ sourceMap: this.buildContext.buildOptions.cssSourceMap }, config) options: Object.assign({ sourceMap: this.options.build.cssSourceMap }, config)
} }
} }
@ -86,7 +90,7 @@ export default class StyleLoader {
extract () { extract () {
if (this.extractCSS) { if (this.extractCSS) {
const isDev = this.buildContext.options.dev const isDev = this.options.dev
return { return {
loader: MiniCssExtractPlugin.loader, loader: MiniCssExtractPlugin.loader,
options: { options: {
@ -102,12 +106,12 @@ export default class StyleLoader {
styleLoader () { styleLoader () {
return this.extract() || { return this.extract() || {
loader: 'vue-style-loader', loader: 'vue-style-loader',
options: this.buildContext.buildOptions.loaders.vueStyle options: this.options.build.loaders.vueStyle
} }
} }
apply (ext, loaders = []) { apply (ext, loaders = []) {
const { css, cssModules } = this.buildContext.buildOptions.loaders const { css, cssModules } = this.options.build.loaders
const customLoaders = [].concat( const customLoaders = [].concat(
this.postcss(), this.postcss(),