快来用 Rspack/Rsbuild + pnpm 构建你的 monorepo 全栈项目

背景说明

我现在做新项目,喜欢前后端都用 JavaScript,代码都放在一个目录下(monorepo 代码管理模式),并使用 pnpm 管理😄。构建工具也从 webpackvite 切换到 Rspack / Rsbuild

关于构建工具

我是从 webpack 的时代过来的,并对它情有独钟,哪怕后面 vite 异军突起,用的最多的还是 webpack,一个很重要的原因就是它全面,前端 WEB、后端 SERVER、库 Library、WASM 均能胜任。虽然 vite 速度快,但在打包后端、库时差强人意(至少在我的实践中如此)。直至遇见 Rspack,兼容 webpack,速度还飞快,在这个急躁的年代谁能不爱😀。 再来张官方的性能对比图

测试机器:MacBook Pro / Apple M1 Pro / 32GB

补充

项目结构

话不多说,看看我的项目组成:

  • web:前端项目,vue3 + naive-ui
  • server:后端服务,fastify + sqlite3, ESM 项目

使用 Rspack

js 复制代码
import { readFileSync } from 'node:fs'
import { defineConfig } from "@rspack/cli"

const pkg = JSON.parse(readFileSync("./package.json"))

export default defineConfig({
    entry: './src/index.js',
    output:{
        filename: `${pkg.name}.js`
    },
    target: 'node',
    devtool: false
})
js 复制代码
const { join } = require('node:path')

const { defineConfig } = require("@rspack/cli")
const { HtmlRspackPlugin, DefinePlugin, EnvironmentPlugin, experiments } = require('@rspack/core')

const { VueLoaderPlugin } = require('vue-loader')
const { NaiveUiResolver } = require('unplugin-vue-components/resolvers')

const pkg = require("./package.json")

const resolve = dir=> join(__dirname, dir)

module.exports = defineConfig({
    context: __dirname,
    entry: './src/main.js',
    devtool: false,
    devServer:{
        port: 10000,
        host: "localhost"
    },
    resolve:{
        extensions:[".js",".vue",".json",".css"],
        alias:{
            "@"                     : resolve("src")
        }
    },
    performance:{
        hints: 'error',
        maxAssetSize: 5*1024*1024,
        maxEntrypointSize: 5*1024*1024,
    },
    plugins:[
        new VueLoaderPlugin(),
        new HtmlRspackPlugin({
            template: "./index.html"
        }),
        new DefinePlugin({
        	//关闭 vue3 的警告信息
            "__VUE_OPTIONS_API__": true,
            "__VUE_PROD_DEVTOOLS__": false,
            "__VUE_PROD_HYDRATION_MISMATCH_DETAILS__": false,
        }),
        new EnvironmentPlugin({
            "VERSION"           : pkg.version,
            "AUTHOR"            : pkg.author
        }),
        require('unplugin-auto-import/rspack').default({ imports:['vue', 'vue-router'], dts: false }),
        //按需导入 naive-ui
        require('unplugin-vue-components/rspack').default({
            resolvers: [NaiveUiResolver()]
        })
    ],
    experiments:{
        css: true
    },
    module:{
        rules:[
            { test: /\.vue$/, loader: "vue-loader", options: { experimentalInlineMatchResource: true }},
            { test: /\.(txt|svg)/, type: "asset/resource" },
            { test: /\.md/, type: 'asset/source' }
        ]
    }
})

使用 Rsbuild

js 复制代码
import { readFileSync } from 'node:fs'
import { defineConfig } from '@rsbuild/core'

const pkg = JSON.parse(readFileSync("./package.json"))

export default defineConfig({
    source:{
        entry:{ index: './src/index.js' },
    },
    output:{
        target:"node",
        filename:{
            js: `${pkg.name}.js`
        }
    }
})
js 复制代码
import { defineConfig } from "@rsbuild/core"
import { pluginVue } from "@rsbuild/plugin-vue"

import AutoImport from 'unplugin-auto-import/rspack'
import Components from 'unplugin-vue-components/rspack'
import { NaiveUiResolver } from "unplugin-vue-components/resolvers"

import pkg from './package.json'

export default defineConfig({
    source:{
        entry: {index:"./src/main.js"},
        alias:{
            "@"         : "./src"
        },
        define:{
            "APP_TITLE"         : JSON.stringify(pkg.cnName)
        }
    },
    html:{
        template: "./index.html",
        templateParameters:{
            "APP_TITLE"     : pkg.cnName
        }
    },
    server:{
        port: 10000,
        host: "localhost"
    },
    output:{
        distPath:{
            js:"js",
            css:"css"
        },
        legalComments: 'none'
    },
    plugins:[
        pluginVue()
    ],
    tools:{
        rspack:{
            plugins: [
                AutoImport({
                    include: [/\.[tj]sx?$/,/\.vue$/,/\.vue\?vue/],
                    imports:['vue', 'vue-router'],
                    dts: false
                }),
                //按需导入 naive-ui
                Components({ resolvers: [NaiveUiResolver()] })
            ]
        }
    }
})

问题记录

  1. rsbuild 1.0.3(2024-09-11发布),使用 unplugin-auto-import 插件时,会导致 SFC 文件内样式失效,已反馈给官方团队,后者正在修复 👍
相关推荐
会飞的战斗鸡7 分钟前
JS中的链表(含leetcode例题)
javascript·leetcode·链表
方也_arkling40 分钟前
别名路径联想提示。@/统一文件路径的配置
前端·javascript
qq_177767371 小时前
React Native鸿蒙跨平台剧集管理应用实现,包含主应用组件、剧集列表、分类筛选、搜索排序等功能模块
javascript·react native·react.js·交互·harmonyos
qq_177767371 小时前
React Native鸿蒙跨平台自定义复选框组件,通过样式数组实现选中/未选中状态的样式切换,使用链式调用替代样式数组,实现状态驱动的样式变化
javascript·react native·react.js·架构·ecmascript·harmonyos·媒体
web打印社区1 小时前
web-print-pdf:突破浏览器限制,实现专业级Web静默打印
前端·javascript·vue.js·electron·html
烬头88212 小时前
React Native鸿蒙跨平台采用了函数式组件的形式,通过 props 接收分类数据,使用 TouchableOpacity实现了点击交互效果
javascript·react native·react.js·ecmascript·交互·harmonyos
Amumu121382 小时前
Vuex介绍
前端·javascript·vue.js
2601_949809592 小时前
flutter_for_openharmony家庭相册app实战+相册详情实现
javascript·flutter·ajax
qq_177767372 小时前
React Native鸿蒙跨平台通过Animated.Value.interpolate实现滚动距离到动画属性的映射
javascript·react native·react.js·harmonyos
2601_949833392 小时前
flutter_for_openharmony口腔护理app实战+饮食记录实现
android·javascript·flutter