前言
通过本文你将理解rspack,并快速实现Vue2、Vue3项目配置,提升5倍多的项目构建性能,快速提高工作效率。
Webpack 构建问题
- 原有大型后台系统项目 DEV 构建需要 3分钟以上;
- 自动化部署构建阶段需要10分钟以上;
- 生产打包构建需要2分钟;
Rspack 优化后
使用 Rspack 替代 Webpack 后:
- DEV构建 3min -> 20s
- 自动化部署 6min -> 3min
- 打包速度 2min -> 20s
比 Webpack 更快 的 Rspack
Rspack 是基于 Rust 重写 Webpack,允许依赖 Webpack 的打包构建工具。
核心优势在于: DEV 启动性能、快速构建、配置灵活、生产优化
起步
安装依赖:
js
pnpm add @rspack/cli@0.3.4
配置npm脚本:
json
// package.json
{
scripts: {
dev: "rspack serve",
build: "rspack build"
}
}
Vue2 + Rspack 示例
安装好依赖和脚本后,我们接着创建配置文件 rspack.config.js
js
// rspack.config.js
const { VueLoaderPlugin } = require('vue-loader')
const rspack = require('@rspack/core')
const path = require('path')
const chalk = require('chalk')
const port = {
production: 9001,
// ...
}[process.env.VUE_APP_ENV || 'development']
const folderName = {
development: 'dev_dir',
// ...
}[process.env.VUE_APP_ENV || 'development']
const isProd = /production/i.test(process.env.NODE_ENV)
const config = {
context: __dirname,
entry: {
main: './src/main.js'
},
output: Object.assign({
path: path.resolve(__dirname, folderName)
}, isProd
? {
filename: 'static/javascript/[name].[contenthash:8].js',
cssFilename: 'static/css/[name].[contenthash:8].js',
assetModuleFilename: 'static/assets/[hash][ext][query]',
publicPath: './',
clean: true
}
: {}),
builtins: {
html: [
{
template: 'public/index.html',
minify: isProd
}
],
define: {
'process.env.NODE_ENV': `"${process.env.NODE_ENV}"`,
'process.env.VUE_APP_ENV': `"${process.env.VUE_APP_ENV}"`
}
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
},
extensions: ['.js', '.vue'],
fallback: {
url: require.resolve('url/'),
stream: require.resolve('stream-browserify'),
buffer: require.resolve('buffer'),
process: require.resolve('process'),
module: require.resolve('module')
}
},
devServer: {
historyApiFallback: true,
open: true,
port
},
devtool: false,
plugins: [
new rspack.ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer']
}),
new VueLoaderPlugin()
].concat(isProd
? [new rspack.ProgressPlugin({
prefix: chalk.green(`端口${port},文件夹${folderName}, 接口环境${process.env.VUE_APP_ENV}, ${isProd ? '生产' : '开发'}环境${process.env.NODE_ENV} \n`)
}),
new rspack.CopyRspackPlugin({
patterns: [
{
from: 'public/static',
to: 'static'
}
]
}),
new rspack.SwcJsMinimizerRspackPlugin({
dropConsole: isProd
})]
: []),
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
},
{
test: /\.scss$/,
use: ['vue-style-loader', 'css-loader', 'sass-loader'],
type: 'javascript/auto'
},
{
test: /\.(styl|stylus)$/,
use: ['vue-style-loader', 'css-loader', 'stylus-loader'],
type: 'javascript/auto'
},
{
test: /\.css$/,
use: ['vue-style-loader', 'css-loader'],
type: 'javascript/auto'
},
{
test: /\.(svg|png|gif|jpe?g)$/,
type: 'asset/resource'
},
{
test: /^BUILD_ID$/,
type: 'asset/source'
}
]
}
}
module.exports = config
Dev 执行结果:
Vue3 + TS + Rspack 示例
js
const { VueLoaderPlugin } = require('vue-loader')
const rspack = require('@rspack/core')
const path = require('path')
const chalk = require('chalk')
const packageName = require('./package.json').name
const isProd = /production/i.test(process.env.NODE_ENV || '')
const folderName = process.env.OUT_DIR
const port = 666666
/** @type {import('@rspack/cli').Configuration} */
const config = {
context: __dirname,
entry: {
main: './src/main.ts'
},
output: Object.assign({
library: `${packageName}-[name]`,
libraryTarget: 'umd',
chunkLoadingGlobal: `webpackJsonp_${packageName}`
}, isProd
? {
path: path.resolve(__dirname, folderName),
filename: 'static/javascript/[name].[contenthash:8].js',
cssFilename: 'static/css/[name].[contenthash:8].css',
assetModuleFilename: 'static/assets/[hash][ext][query]',
publicPath: './',
clean: true
}
: {}),
builtins: {
html: [
{
template: 'public/index.html',
minify: isProd,
title: 'finder-dms'
}
],
define: {
'process.env.NODE_ENV': `"${process.env.NODE_ENV}"`
}
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
},
extensions: ['.vue', '.js', '.ts']
},
devServer: {
historyApiFallback: true,
open: false,
port,
headers: {
'Access-Control-Allow-Origin': '*'
}
},
devtool: false,
plugins: [
new VueLoaderPlugin()
].concat(isProd
? [new rspack.ProgressPlugin({
prefix: chalk.green(`端口${port},输出目录${folderName}, 接口环境由主应用决定, ${isProd ? '生产' : '开发'}环境${process.env.NODE_ENV} \n`)
}),
new rspack.SwcJsMinimizerRspackPlugin({
dropConsole: isProd
})]
: []),
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
experimentalInlineMatchResource: true
}
},
{
test: /\.ts$/,
loader: 'builtin:swc-loader',
options: {
sourceMap: true,
jsc: {
parser: {
syntax: 'typescript'
}
}
},
type: 'javascript/auto'
},
{
test: /.(styl|stylus)$/,
loader: 'stylus-loader',
type: 'css'
},
{
test: /.scss$/,
loader: 'sass-loader',
type: 'css'
},
{
test: /\.(svg|png|gif|jpe?g)$/,
type: 'asset/resource'
},
{
test: /^BUILD_ID$/,
type: 'asset/source'
}
]
}
}
module.exports = config
总结
本文介绍了rspack以及如何在Vue2和Vue3项目中使用rspack进行配置,以提高项目构建性能和工作效率。使用rspack替代webpack后,构建时间大幅缩短的优势。
如果你对巨型应用构建问题很头疼的话,不妨试试接入Rspack。