Rspack的一个简单的demo

592 阅读6分钟

Rspack学习记录

rspack一个打包工具,(小编比较懒不喜欢讲废话,介绍直接去官网)

Rspack

小编比较菜,文章仅用来记录下自己的学习过程。
官网说它的性能是xx的多少倍,咱也不懂底层逻辑,不过确实要比前一阵搭的webpack的架子要快很多,并且对于webpack的插件相对友好,应该可以直接实现webpack到rspack的迁移。
好吧该进入正题了

一个简单的实验Demo

初始化一个本地的page.json

这里我用的是bun包管理工具(别问我为什么用这个,问就是因为官网上这个在最后面嘿嘿)用npm、yarn、pnpm也是一个样子

// 初始化一下本地目录拿到个 package.json文件 用来装包依赖
// bun 工具
bun init
// npm 工具
npm init

安装rspack相关依赖

这个官网有直接copy

bun add @rspack/core @rspack/cli -D

创建一个配置文件

创建一个rspack.config.js的配置文件

1. 配置入口,出口
const path = require('path');

module.exports = {
  entry: {
        main: path.join(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist/assets'),
        filename: "./js/[name].js",
        clean: true,  // 打包的时候清楚原来的文件重新打包
    },
}
2. 配置package.json指令
{
  "scripts": {
    "start": "rspack serve",
    "build": "rspack build",
    "test": "echo "Error: no test specified" && exit 1"
  },
}

完成这个配置你就可以打包一个js文件了,但要想打包一个完成的网页包括css、html需要安装相关的loader和plugins

3. 安装css、html等相关得配置

希望你已经仔细地看过文档了,rspack内部集成了css,html的相关loader和plugins所以直接使用即可,当然如果你没有,使用webpack的相关插件来集成一样也是可以实现的。详细看官网 Rspack

上示例代码(js和less的相关loader需要单独装,具体装什么就不写了 后面把包文件放上去直接copy)

module.exports = {
  ...
   module: {
        rules: [
            {
                test: /.m?js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            },
            {
                test: /.less$/,
                use: [
                    rsPack.CssExtractRspackPlugin.loader, 'css-loader', 'less-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [
                                    require('autoprefixer'),
                                    // 其他插件...
                                ],
                            },
                        },
                    }
                ]
            },
            {
                test: /.css$/,
                use: [
                    rsPack.CssExtractRspackPlugin.loader, 'css-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [
                                    require('autoprefixer'),
                                    // 其他插件...
                                ],
                            },
                        },
                    }
                ]
            }
        ]
    },
   plugins: [
        new rsPack.HtmlRspackPlugin({
            title: '一个新的测试程序',
            favicon: undefined,
            template: 'index.html',
            filename: '../index.html',
        }),
        new rsPack.CssExtractRspackPlugin({
            filename: "./css/[name].css",
        })
    ],
  ...
}

上面就是一个简单的rspack打包demo的测试版本

说一下我碰到的问题,在刚开始做的时候less配置的loder写反了一直报错,😭也是傻这个小错误没发现刚好记录一下这些loader顺序的问题把

'style-loader',  // 将 CSS 插入到 DOM 中,miniMiniCssExtractPlugin和rspack内部的大概也是这个用处
'css-loader',    // 解析 CSS 文件
'less-loader'    // 将 LESS 编译为 CSS
'post-loader'    // 解析层叠样式,并对css文件中的属性做集中处理,
// 相关配置建议看官网
// 加载器的顺序很重要,style-loader 应该在最前面,less-loader 在最后面,
// 因为加载器的执行顺序是从右到左。不转义less就直接引入肯定会报错的,

demo相关配置代码

{
  "name": "bun-test",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "rspack serve",
    "build": "rspack build",
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "@rspack/cli": "^1.1.0",
    "@rspack/core": "^1.1.0"
  },
  "dependencies": {
    "@babel/core": "^7.26.0",
    "@babel/preset-env": "^7.26.0",
    "autoprefixer": "^10.4.20",
    "babel-loader": "^9.2.1",
    "css-loader": "^7.1.2",
    "less": "^4.2.0",
    "less-loader": "^12.2.0",
    "postcss": "^8.4.49",
    "postcss-loader": "^8.1.1",
    "style-loader": "^4.0.0"
  }
}
const path = require('path');
const rsPack = require("@rspack/core");
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
    // rspack.config.js
    mode: isProduction? 'production' : 'development',
    context: __dirname,
    entry: {
        main: path.join(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist/assets'),
        filename: "./js/[name].js",
        clean: true,
    },
    resolve: {
        alias: {
            '@': path.resolve(__dirname, './src')
        },
        extensions: ['.vue', '.js', '.jsx', '.less', '.css']
    },
    module: {
        rules: [
            {
                test: /.m?js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            },
            {
                test: /.less$/,
                use: [
                    rsPack.CssExtractRspackPlugin.loader, 'css-loader', 'less-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [
                                    require('autoprefixer'),
                                    // 其他插件...
                                ],
                            },
                        },
                    }
                ]
            },
            {
                test: /.css$/,
                use: [
                    rsPack.CssExtractRspackPlugin.loader, 'css-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [
                                    require('autoprefixer'),
                                    // 其他插件...
                                ],
                            },
                        },
                    }
                ]
            }
        ]
    },

    plugins: [
        new rsPack.HtmlRspackPlugin({
            title: '一个新的测试程序',
            favicon: undefined,
            template: 'index.html',
            filename: '../index.html',
        }),
        new rsPack.CssExtractRspackPlugin({
            filename: "./css/[name].css",
        })
    ],
    devServer: {
        host: '0.0.0.0',
        port: 1230,
        compress: true, // 是否启用 gzip 压缩
        hot: true, // 是否启用热更新
        open: true, // 是否自动打开浏览器
        proxy: [
            {
                context: ['/api'],
                target: 'http://localhost:3000',
            },
        ], // 代理配置
        static: ['public'], // 静态资源目录
        client: {
            logging: 'error', // 控制台日志级别
            overlay: false, // 是否在浏览器中显示错误
            progress: true, // 是否在浏览器中显示打包进度
        }
    }

}

📎package.json📎rspack.config.js

一个简单的vue+ts的配置

上面的一个简单的demo完成之后这个vue+ts的相关配置就会简单许多了,只需要配置vue和ts相关的插件和loader就可以了。这里我使用的是ts作为配置文件

所以需要在本地初始化ts的相关配置

npm init   // 初始化包配置文件
bun add tyscript ts-node -d  // 安装ts包
tsc --init  //初始化一个tsconfig.json文件

tsconfig.json具体配置的详解这里不做讲解有兴趣的看大佬的文章tsconfig.json配置 - 磊~~ - 博客园

这套操作下来大概率你会生成这样一个目录

剩下的就是安装js、css 等等的依赖这里就不重复了,直接安装vue、ts的相关依赖

bun add vue vue-loader @vue/babel-plugin-jsx swc-loader

// 配置
import { VueLoaderPlugin } from 'vue-loader';
 module: {
        rules: [
            {
                test: /.vue$/,
                loader: 'vue-loader',
                options: {
                    // 注意,为了绝大多数功能的可用性,请确保该选项为 `true`
                    experimentalInlineMatchResource: true,
                },
            },
            {
                test: /.ts$/,
                loader: 'builtin:swc-loader',
                options: {
                    sourceMap: true,
                    jsc: {
                        parser: {
                            syntax: 'typescript',
                        },
                    },
                },
                type: 'javascript/auto',
            },
        ]
    },
plugins: [
        new VueLoaderPlugin(),
]

上面的配置完成打包就差不多可以打包一个vue的项目了,哦忘记了在使用vue+ts自定义打包配置的时候需要添加一个解析文件shims-vue.d.ts 否则会报错

declare module "*.vue" {
	import type { DefineComponent } from "vue";
	const component: DefineComponent<{}, {}, any>;
	export default component;
}


// declare module '*.vue'
// 这是一个模块声明,告诉 TypeScript 对于所有 .vue 文件,都使用这个模块声明。

// import { DefineComponent } from 'vue';
// 从 Vue 库中导入 DefineComponent 类型。
// Vue 3 提供了这个类型来定义组件,确保类型安全。

// const component: DefineComponent<{}, {}, any>;
// 声明每个 .vue 文件默认导出一个 Vue 组件。
// 这里使用 DefineComponent 类型来描述这个组件,参数通常可以根据需要进行调整。

export default component;
// 声明导出默认组件。这与 Vue 单文件组件的导出方式一致。


// 解决TypeScript 对 .vue 文件的默认识别问题,提供了类型支持,
// 从而使得开发者可以在 TypeScript 环境中顺利使用 Vue 单文件组件。

这样下来就可以完成一个基本的项目打包了,如果想要本地运行 这个vue项目需要在对rspack的devserver进行一些配置

devServer: {
        host: '0.0.0.0',
        port: 12311,
        compress: true, // 是否启用 gzip 压缩
        hot: true, // 是否启用热更新
        open: true, // 是否自动打开浏览器
        // historyApiFallback: true, // 是否启用 HTML5 History API 回退
        static: {
            directory: path.join(__dirname, 'public'), // 静态文件目录
        },
        proxy: [
            {
                context: ['/api'],
                target: 'http://localhost:3000',
            },
        ], // 代理配置
        client: {
            logging: 'error', // 控制台日志级别
            overlay: false, // 是否在浏览器中显示错误
            progress: true, // 是否在浏览器中显示打包进度
        }
    }

这样一个完整的流程就基本完成了,这里偷懒了 没有一点一点写,有问题的看后面的配置文件吧,这只是一个基本的打包配置,剩下的优化内容可以后续自己在里面添加,例如代码压缩,图片压缩,添加chunk配置等等,小编比较菜这些都不会,只是做一个记录自己学习的过程hhhhhh。

vue+ts+rspace相关配置

📎package.json📎tsconfig.json

import path from 'path';
import rspack from "@rspack/core";
import { Configuration } from '@rspack/cli';
import { VueLoaderPlugin } from 'vue-loader';


const isProduction = process.env.NODE_ENV === 'production';
const config: Configuration = {
    mode: isProduction? 'production' : 'development',
    context: __dirname,
    entry: {
        main: path.join(__dirname, './src/main.ts')
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: './assets/js/[name].js',
        clean: true
    },
    resolve: {
        alias: {
            '@': path.resolve(__dirname, 'src'),
        }
        ,
        extensions: ['.vue','.ts', '.js', '.json']
    },
    module: {
        rules: [
            {
                test: /.vue$/,
                loader: 'vue-loader',
                options: {
                    // 注意,为了绝大多数功能的可用性,请确保该选项为 `true`
                    experimentalInlineMatchResource: true,
                },
            },
            {
                test: /.less$/,
                loader: "less-loader",
                type: "css"
            },
            {
                test: /.js$/,  // 匹配所有的 .js 文件
                exclude: /node_modules/,  // 排除 node_modules 目录
                use: {
                    loader: 'babel-loader',  // 使用 Babel 处理 JS 文件
                    options: {
                        presets: ['@babel/preset-env'],  // 使用 Babel 预设
                    },
                },
            },
            {
                test: /.jsx$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            plugins: ['@vue/babel-plugin-jsx'],
                        },
                    },
                ],
            },
            {
                test: /.ts$/,
                loader: 'builtin:swc-loader',
                options: {
                    sourceMap: true,
                    jsc: {
                        parser: {
                            syntax: 'typescript',
                        },
                    },
                },
                type: 'javascript/auto',
            },
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
        new rspack.HtmlRspackPlugin({
            template: './index.html',
            title: '一个新的测试程序',
            favicon: undefined,
            filename: 'index.html',
        }),
        new rspack.CssExtractRspackPlugin({
            filename: "./assets/css/[name].css",
        }),
        new rspack.DefinePlugin({
            __VUE_OPTIONS_API__: JSON.stringify(true),
            __VUE_PROD_DEVTOOLS__: JSON.stringify(false),
        }),
    ],

    devServer: {
        host: '0.0.0.0',
        port: 12311,
        compress: true, // 是否启用 gzip 压缩
        hot: true, // 是否启用热更新
        open: true, // 是否自动打开浏览器
        // historyApiFallback: true, // 是否启用 HTML5 History API 回退
        static: {
            directory: path.join(__dirname, 'public'), // 静态文件目录
        },
        proxy: [
            {
                context: ['/api'],
                target: 'http://localhost:3000',
            },
        ], // 代理配置
        client: {
            logging: 'error', // 控制台日志级别
            overlay: false, // 是否在浏览器中显示错误
            progress: true, // 是否在浏览器中显示打包进度
        }
    }
}

module.exports = config;

参考

git的相关配置链接

gitee.com/white23/rsp…