mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-23 14:15:13 +00:00
refactor: perf loader (#4299)
This commit is contained in:
parent
57f66726d0
commit
2c4bd57101
@ -26,7 +26,6 @@ export class WebpackBundler {
|
|||||||
this.compilersWatching = []
|
this.compilersWatching = []
|
||||||
this.devMiddleware = {}
|
this.devMiddleware = {}
|
||||||
this.hotMiddleware = {}
|
this.hotMiddleware = {}
|
||||||
this.perfLoader = null
|
|
||||||
|
|
||||||
// Initialize shared FS and Cache
|
// Initialize shared FS and Cache
|
||||||
if (this.context.options.dev) {
|
if (this.context.options.dev) {
|
||||||
@ -37,8 +36,6 @@ export class WebpackBundler {
|
|||||||
async build() {
|
async build() {
|
||||||
const options = this.context.options
|
const options = this.context.options
|
||||||
|
|
||||||
this.perfLoader = new PerfLoader(options)
|
|
||||||
|
|
||||||
const compilersOptions = []
|
const compilersOptions = []
|
||||||
|
|
||||||
// Client
|
// Client
|
||||||
@ -104,7 +101,7 @@ export class WebpackBundler {
|
|||||||
// Warmup perfLoader before build
|
// Warmup perfLoader before build
|
||||||
if (options.build.parallel) {
|
if (options.build.parallel) {
|
||||||
consola.info('Warming up worker pools')
|
consola.info('Warming up worker pools')
|
||||||
this.perfLoader.warmupAll()
|
PerfLoader.warmupAll({ dev: options.dev })
|
||||||
consola.success('Worker pools ready')
|
consola.success('Worker pools ready')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import env from 'std-env'
|
|||||||
|
|
||||||
import { isUrl, urlJoin } from '@nuxt/common'
|
import { isUrl, urlJoin } from '@nuxt/common'
|
||||||
|
|
||||||
|
import PerfLoader from './utils/perf-loader'
|
||||||
import StyleLoader from './utils/style-loader'
|
import StyleLoader from './utils/style-loader'
|
||||||
import WarnFixPlugin from './plugins/warnfix'
|
import WarnFixPlugin from './plugins/warnfix'
|
||||||
|
|
||||||
@ -125,14 +126,13 @@ export default class WebpackBaseConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rules() {
|
rules() {
|
||||||
|
const perfLoader = new PerfLoader(this)
|
||||||
const styleLoader = new StyleLoader(
|
const styleLoader = new StyleLoader(
|
||||||
this.options,
|
this.options,
|
||||||
this.nuxt,
|
this.nuxt,
|
||||||
{ isServer: this.isServer }
|
{ isServer: this.isServer, perfLoader }
|
||||||
)
|
)
|
||||||
|
|
||||||
const perfLoader = this.builder.perfLoader
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
test: /\.vue$/,
|
test: /\.vue$/,
|
||||||
@ -173,46 +173,46 @@ export default class WebpackBaseConfig {
|
|||||||
|
|
||||||
return !modulesToTranspile.some(module => module.test(file))
|
return !modulesToTranspile.some(module => module.test(file))
|
||||||
},
|
},
|
||||||
use: perfLoader.pool('js', {
|
use: perfLoader.js().concat({
|
||||||
loader: require.resolve('babel-loader'),
|
loader: require.resolve('babel-loader'),
|
||||||
options: this.getBabelOptions()
|
options: this.getBabelOptions()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
oneOf: perfLoader.poolOneOf('css', styleLoader.apply('css'))
|
oneOf: styleLoader.apply('css')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.less$/,
|
test: /\.less$/,
|
||||||
oneOf: perfLoader.poolOneOf('css', styleLoader.apply('less', {
|
oneOf: styleLoader.apply('less', {
|
||||||
loader: 'less-loader',
|
loader: 'less-loader',
|
||||||
options: this.loaders.less
|
options: this.loaders.less
|
||||||
}))
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.sass$/,
|
test: /\.sass$/,
|
||||||
oneOf: perfLoader.poolOneOf('css', styleLoader.apply('sass', {
|
oneOf: styleLoader.apply('sass', {
|
||||||
loader: 'sass-loader',
|
loader: 'sass-loader',
|
||||||
options: this.loaders.sass
|
options: this.loaders.sass
|
||||||
}))
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.scss$/,
|
test: /\.scss$/,
|
||||||
oneOf: perfLoader.poolOneOf('css', styleLoader.apply('scss', {
|
oneOf: styleLoader.apply('scss', {
|
||||||
loader: 'sass-loader',
|
loader: 'sass-loader',
|
||||||
options: this.loaders.scss
|
options: this.loaders.scss
|
||||||
}))
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.styl(us)?$/,
|
test: /\.styl(us)?$/,
|
||||||
oneOf: perfLoader.poolOneOf('css', styleLoader.apply('stylus', {
|
oneOf: styleLoader.apply('stylus', {
|
||||||
loader: 'stylus-loader',
|
loader: 'stylus-loader',
|
||||||
options: this.loaders.stylus
|
options: this.loaders.stylus
|
||||||
}))
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(png|jpe?g|gif|svg|webp)$/,
|
test: /\.(png|jpe?g|gif|svg|webp)$/,
|
||||||
use: perfLoader.pool('assets', {
|
use: perfLoader.asset().concat({
|
||||||
loader: 'url-loader',
|
loader: 'url-loader',
|
||||||
options: Object.assign(
|
options: Object.assign(
|
||||||
this.loaders.imgUrl,
|
this.loaders.imgUrl,
|
||||||
@ -222,7 +222,7 @@ export default class WebpackBaseConfig {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||||
use: perfLoader.pool('assets', {
|
use: perfLoader.asset().concat({
|
||||||
loader: 'url-loader',
|
loader: 'url-loader',
|
||||||
options: Object.assign(
|
options: Object.assign(
|
||||||
this.loaders.fontUrl,
|
this.loaders.fontUrl,
|
||||||
@ -232,7 +232,7 @@ export default class WebpackBaseConfig {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(webm|mp4|ogv)$/,
|
test: /\.(webm|mp4|ogv)$/,
|
||||||
use: perfLoader.pool('assets', {
|
use: perfLoader.asset().concat({
|
||||||
loader: 'file-loader',
|
loader: 'file-loader',
|
||||||
options: Object.assign(
|
options: Object.assign(
|
||||||
this.loaders.file,
|
this.loaders.file,
|
||||||
|
@ -6,58 +6,58 @@ import { warmup } from 'thread-loader'
|
|||||||
// https://github.com/webpack-contrib/cache-loader
|
// https://github.com/webpack-contrib/cache-loader
|
||||||
|
|
||||||
export default class PerfLoader {
|
export default class PerfLoader {
|
||||||
constructor(options) {
|
constructor(config) {
|
||||||
this.options = options
|
this.name = config.name
|
||||||
this.warmup = warmup
|
this.options = config.options
|
||||||
this.workerPools = {
|
this.workerPools = PerfLoader.defaultPools(this.options)
|
||||||
js: {
|
return new Proxy(this, {
|
||||||
name: 'js',
|
get(target, name) {
|
||||||
poolTimeout: this.options.dev ? Infinity : 2000
|
return target[name] ? target[name] : target.use.bind(target, name)
|
||||||
},
|
|
||||||
css: {
|
|
||||||
name: 'css',
|
|
||||||
poolTimeout: this.options.dev ? Infinity : 2000
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultPools({ dev }) {
|
||||||
|
const poolTimeout = dev ? Infinity : 2000
|
||||||
|
return {
|
||||||
|
js: { name: 'js', poolTimeout },
|
||||||
|
css: { name: 'css', poolTimeout }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
warmupAll() {
|
static warmupAll(options) {
|
||||||
this.warmup(this.workerPools.js, [
|
options = PerfLoader.defaultPools(options)
|
||||||
|
PerfLoader.warmup(options.js, [
|
||||||
require.resolve('babel-loader'),
|
require.resolve('babel-loader'),
|
||||||
require.resolve('@babel/preset-env')
|
require.resolve('@babel/preset-env')
|
||||||
])
|
])
|
||||||
this.warmup(this.workerPools.css, ['css-loader'])
|
PerfLoader.warmup(options.css, ['css-loader'])
|
||||||
}
|
}
|
||||||
|
|
||||||
pool(poolName, _loaders) {
|
use(poolName) {
|
||||||
const loaders = [].concat(_loaders)
|
const loaders = []
|
||||||
|
|
||||||
|
if (this.options.build.cache) {
|
||||||
|
loaders.push({
|
||||||
|
loader: 'cache-loader',
|
||||||
|
options: {
|
||||||
|
cacheDirectory: path.resolve(`node_modules/.cache/cache-loader/${this.name}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (this.options.build.parallel) {
|
if (this.options.build.parallel) {
|
||||||
const pool = this.workerPools[poolName]
|
const pool = this.workerPools[poolName]
|
||||||
|
|
||||||
if (pool) {
|
if (pool) {
|
||||||
loaders.unshift({
|
loaders.push({
|
||||||
loader: 'thread-loader',
|
loader: 'thread-loader',
|
||||||
options: pool
|
options: pool
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.build.cache) {
|
|
||||||
loaders.unshift({
|
|
||||||
loader: 'cache-loader',
|
|
||||||
options: {
|
|
||||||
cacheDirectory: path.resolve('node_modules/.cache/cache-loader')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return loaders
|
return loaders
|
||||||
}
|
}
|
||||||
|
|
||||||
poolOneOf(poolName, oneOfRules) {
|
|
||||||
return oneOfRules.map(rule => Object.assign({}, rule, {
|
|
||||||
use: this.pool(poolName, rule.use)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PerfLoader.warmup = warmup
|
||||||
|
@ -6,8 +6,9 @@ import { wrapArray } from '@nuxt/common'
|
|||||||
import PostcssConfig from './postcss'
|
import PostcssConfig from './postcss'
|
||||||
|
|
||||||
export default class StyleLoader {
|
export default class StyleLoader {
|
||||||
constructor(options, nuxt, { isServer }) {
|
constructor(options, nuxt, { isServer, perfLoader }) {
|
||||||
this.isServer = isServer
|
this.isServer = isServer
|
||||||
|
this.perfLoader = perfLoader
|
||||||
this.dev = options.dev
|
this.dev = options.dev
|
||||||
this.srcDir = options.srcDir
|
this.srcDir = options.srcDir
|
||||||
this.assetsDir = options.dir.assets
|
this.assetsDir = options.dir.assets
|
||||||
@ -104,7 +105,7 @@ export default class StyleLoader {
|
|||||||
// This matches <style module>
|
// This matches <style module>
|
||||||
{
|
{
|
||||||
resourceQuery: /module/,
|
resourceQuery: /module/,
|
||||||
use: [].concat(
|
use: this.perfLoader.css().concat(
|
||||||
styleLoader,
|
styleLoader,
|
||||||
this.cssModules(cssModulesOptions),
|
this.cssModules(cssModulesOptions),
|
||||||
customLoaders
|
customLoaders
|
||||||
@ -112,7 +113,7 @@ export default class StyleLoader {
|
|||||||
},
|
},
|
||||||
// This matches plain <style> or <style scoped>
|
// This matches plain <style> or <style scoped>
|
||||||
{
|
{
|
||||||
use: [].concat(
|
use: this.perfLoader.css().concat(
|
||||||
styleLoader,
|
styleLoader,
|
||||||
this.css(cssOptions),
|
this.css(cssOptions),
|
||||||
customLoaders
|
customLoaders
|
||||||
|
@ -4,32 +4,33 @@ import PerfLoader from '../../packages/webpack/src/config/utils/perf-loader'
|
|||||||
|
|
||||||
describe('webpack configuration', () => {
|
describe('webpack configuration', () => {
|
||||||
test('performance loader', () => {
|
test('performance loader', () => {
|
||||||
const perfLoader = new PerfLoader({
|
|
||||||
dev: true,
|
|
||||||
build: {
|
|
||||||
parallel: true,
|
|
||||||
cache: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const js = { name: 'js', poolTimeout: Infinity }
|
const js = { name: 'js', poolTimeout: Infinity }
|
||||||
const css = { name: 'css', poolTimeout: Infinity }
|
const css = { name: 'css', poolTimeout: Infinity }
|
||||||
expect(perfLoader.workerPools).toMatchObject({ js, css })
|
PerfLoader.warmup = jest.fn()
|
||||||
|
PerfLoader.warmupAll({ dev: true })
|
||||||
perfLoader.warmup = jest.fn()
|
expect(PerfLoader.warmup).toHaveBeenCalledTimes(2)
|
||||||
perfLoader.warmupAll()
|
expect(PerfLoader.warmup).toHaveBeenCalledWith(js, [
|
||||||
expect(perfLoader.warmup).toHaveBeenCalledTimes(2)
|
|
||||||
expect(perfLoader.warmup).toHaveBeenCalledWith(js, [
|
|
||||||
require.resolve('babel-loader'),
|
require.resolve('babel-loader'),
|
||||||
require.resolve('@babel/preset-env')
|
require.resolve('@babel/preset-env')
|
||||||
])
|
])
|
||||||
expect(perfLoader.warmup).toHaveBeenCalledWith(css, ['css-loader'])
|
expect(PerfLoader.warmup).toHaveBeenCalledWith(css, ['css-loader'])
|
||||||
|
|
||||||
const loaders = perfLoader.pool('js', { loader: 'test-perf-loader' })
|
const perfLoader = new PerfLoader({
|
||||||
const cacheDirectory = path.resolve('node_modules/.cache/cache-loader')
|
name: 'test-perf',
|
||||||
|
options: {
|
||||||
|
dev: true,
|
||||||
|
build: {
|
||||||
|
parallel: true,
|
||||||
|
cache: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(perfLoader.workerPools).toMatchObject({ js, css })
|
||||||
|
const loaders = perfLoader.use('js')
|
||||||
|
const cacheDirectory = path.resolve('node_modules/.cache/cache-loader/test-perf')
|
||||||
expect(loaders).toMatchObject([
|
expect(loaders).toMatchObject([
|
||||||
{ loader: 'cache-loader', options: { cacheDirectory } },
|
{ loader: 'cache-loader', options: { cacheDirectory } },
|
||||||
{ loader: 'thread-loader', options: js },
|
{ loader: 'thread-loader', options: js }
|
||||||
{ loader: 'test-perf-loader' }
|
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user