在阅读此文之前,尝试在电脑的命令行中执行npx f_cli_f create xxx
(xxx是你想要构建的项目)
此篇文章所涉及到的技术有
Rust
脚手架 Vite
Rsbuild
Biome
跨平台编译
因为,行文字数所限,有些概念可能会一带而过亦或者提供对应的学习资料。请大家酌情观看。
前言
还记得我们之前写过用Rust
写一个前端脚手架的系列文章吗?
其实呢,要想用Rust
写一个脚手架,上面的内容就足够了。剩下的核心的部分其实就是脚手架内部逻辑了。
之前呢,我们已经发布过一版f_cli_f[1]。主要是针对Vite
项目的构建。此次版本升级,我们新增了对Rsbuild
的支持。并且将部分冗余的功能剔除或者让用户自行选择。
运行效果
大家可以在自己的电脑环境执行上面的操作。npx f_cli_f create demo
。
好了,天不早了,干点正事哇。
我们能所学到的知识点
❝
迎新 辞旧 展望
1. 迎新
相比上一个版本,我们主要有几个新的变化。
新增特性
对Rsbuild
的支持
很早就开始关注到Rsbuild[2]的功能。在不久之前,他们将版本信息更新到1.0
。在观望了几天之后,发现Rsbuild
在打包和开发阶段有着和其他打包工具截然不同的性能优势。所以,我们团队,也在逐步将Vite
替换为Rsbuild
。
下面就直接截取它官网的内容了。
其实呢,Rsbuild
在构建项目的时候,也为我们提供了很多Template
。和其他工具一样(CRA/Vue Cli/Vite
)。他们只是为我们提供一个最基础的项目。对于像一些axios/css/状态管理
都需要自己去配置。
既然,我们团队也是对于一些新项目,要用Rsbuild
。所以,这次更新cli
也将Rsbuild
作为一个打包选项。
体现在Rust
代码中就是下面的逻辑
let _build_tool = match build_tool {
Some(build_tool) => build_tool,
None => {
if default {
panic!("Fatal: 构建工具未指定");
}
logger::multiselect_msg("选择一个构建工具:");
logger::message("使用上/下箭头进行选择,使用空格或回车键确认。");
let items = vec!["Vite", "Rsbuild"];
let selection = Select::with_theme(&ColorfulTheme::default())
.items(&items)
.default(0)
.interact_on_opt(&Term::stderr())?;
match selection {
Some(0) => BuildTool::Vite,
Some(1) => BuildTool::Rsbuild,
_ => panic!("Fatal: 构建工具指定失败."),
}
}
};
然后,我们在使用交互式构建项目时候,就可以选择vite
或者rsbuild
作为项目的构建工具了。
通过,选择Rsbuild
作为构建工具,那么我们就会生成一个功能完备的项目。
然后,我们在之后的template-react
目录基础上加上rusbuild-config
的内容,在配合一些交互式配置就可以生成一个rsbuild+react
的项目了。
下面是rusbuild-config
的内容。
├── biome.json
├── index.d.ts
├── index.html
├── package.json
├── rsbuild.config.js
└── src
└── routers
└── index.tsx
命令自动化
在之前的版本中,像一些
husky
的实例化,项目初始化后打开编辑器 安装项目依赖
这些操作都需要自己手动完成。而此次更新之后,这些操作我们都使用了std::process::Command
来自动执行了。
体现在Rust
代码中,如下所示(我们拿打开Vscode
为例子)
use std::process::Command;
use console::style;
use super::logger::{ self, message };
pub fn open_vscode(project_dir: &std::path::PathBuf) {
logger::command_msg("正在打开 VS Code...");
// 使用 `code` 命令打开指定的项目目录
let status = if cfg!(target_os = "windows") {
Command::new("cmd").arg("/C").current_dir(project_dir).arg("code").arg(".").status()
} else {
Command::new("code").current_dir(project_dir).arg(".").status()
};
match status {
Ok(s) if s.success() => {
logger::command_success("VS Code 成功打开");
}
Ok(_) | Err(_) => {
logger::error("打开 VS Code 失败");
message("确保您已安装 VS Code,并且 `code` 命令可用");
message(
&format!(
"{}",
style("要将 `code` 命令配置到系统 PATH,请按照以下步骤操作:!").underlined()
)
);
message(" 1. 打开 VS Code");
message(" 2. 打开命令面板 (按下 `Ctrl + Shift + P`)");
message(" 3. 输入并选择 'Shell Command: Install 'code' command in PATH'");
message(" 4. 重启终端,并再次运行此命令");
}
}
}
其他的操作,如husky
的初始化,使用yarn
安装依赖。都是类似的操作。
css解决方案和hook,变成可选
在使用cli
过程中,我们发现有些功能不是很必须的,所以我们让这些功能变成可选。
我们是用dialoguer[3]来实现这个的二次确认操作。
体现到Rust
中就是如下
let _style = match style {
Some(style) => style,
None => {
if default {
panic!("Fatal: css解决方案未指定");
}
if
Confirm::with_theme(&ColorfulTheme::default())
.with_prompt("所构建的项目是否需要CSS解决方案(tailwindcss/styled-components)?")
.interact()
.unwrap()
{
logger::multiselect_msg("选择一个css解决方案:");
logger::message("使用上/下箭头进行选择,使用空格或回车键确认。");
let items = vec!["tailwindcss", "styled-components"];
let selection = Select::with_theme(&ColorfulTheme::default())
.items(&items)
.default(0)
.interact_on_opt(&Term::stderr())?;
match selection {
Some(0) => Style::TailwindCSS,
Some(1) => Style::StyledComponents,
_ => panic!("Fatal: css解决方案指定失败."),
}
} else {
Style::None
}
}
};
项目天然支持wasm/web worker(comlink)
我们在原始项目中,新增了wasm/worker
的文件目录,用于存放项目中可能会用到的wasm
和web worker
。
这些功能都是开箱即用的。我们已经在相应的构建工具(vite/rsbuild
)为大家配置好了。
大家可以在下载完项目后,在home
页面进行验证。(记得把控制台打开).
下面是vite.worker.config.ts
中的相关配置
import wasm from 'vite-plugin-wasm';
import topLevelAwait from 'vite-plugin-top-level-await';
import { comlink } from 'vite-plugin-comlink';
const worker = () => {
return ({
plugins: () => [wasm(), topLevelAwait(),comlink()],
})
};
export default worker;
我们在配置vite
时,按照功能将其分为几大类
├── vite.plugin.config.ts
├── vite.build.config.ts
├── vite.config.ts
├── vite.define.config.ts
├── vite.server.config.ts
├── vite.worker.config.ts
引入code-inspector-plugin
我们在项目中引入了code-inspector-plugin[4],它是一款点击页面上的 DOM 元素,它能自动打开 IDE 并将光标定位至 DOM 的源代码位置
通过tsconfig.json中的配置别名
{
//...
"compilerOptions": {
"baseUrl": ".", // 解析非相对模块的基准目录
"paths": { // 设置路径映射
"@/*": ["src/*"],
"@hooks/*": ["src/hooks/*"],
"@assets/*": ["src/assets/*"],
"@utils/*": ["src/utils/*"],
"@components/*": ["src/components/*"],
"@pages/*": ["src/pages/*"],
"@api/*": ["src/api/*"],
"@network/*": ["src/services/*"]
}
},
//....
}
设置vscode的规范
我们在构建项目的时候,会自动生成.vscode
的文件
其中有几点比较好玩
设置 explorer.fileNesting.patterns
配置文件分组
{
"explorer.fileNesting.patterns": {
"tsconfig.json": "tsconfig.*.json, env.d.ts",
"package.json": "package-lock.json, pnpm*, .yarnrc*, yarn*, .eslint*, eslint*, .prettier*, prettier*, .editorconfig",
".env":".env.*",
"vite.config.ts":"vite.*.config.ts"
},
}
设置 search.exclude
限定搜索范围
{
"search.exclude": {
"**/node_modules": true,
"**/*.log": true,
"**/*.log*": true,
//省略部分代码
},
}
相关的配置还有files.exclude
设置 cSpell.words
规范拼写检查
{
"cSpell.words": [
"vben",
"windi",
"browserslist",
"tailwindcss",
"esnext",
"antv",
//省略部分代码
]
}
2. 辞旧
之前呢,我们在template-react
中冗余了很多工具方法或者特性。
例如Sentry
/Logging
。
而此次的更新,我们将前端项目的结构做了精简。
我们只保留了一个能够直接启动的目录结构,其他冗余的功能,现在剔除掉了。因为有些需求对于一个项目来讲不是必须品。
├── src
│ ├── App.tsx
│ ├── api
│ │ ├── config.ts
│ │ └── test.ts
│ ├── components
│ │ ├── ErrorPage
│ │ │ └── index.tsx
│ │ └── Loading
│ │ └── index.tsx
│ ├── constants
│ │ └── pages.ts
│ ├── contexts
│ │ └── global.ts
│ ├── index.css
│ ├── main.tsx
│ ├── pages
│ │ ├── Home
│ │ │ └── index.tsx
│ │ └── Login
│ │ └── index.tsx
│ ├── routers
│ │ └── index.tsx
│ ├── services
│ │ ├── ApiError.ts
│ │ └── HTTPService.ts
│ ├── style
│ │ └── global.css
│ ├── types
│ │ └── index.ts
│ ├── utils
│ │ ├── deviceDetection
│ │ │ └── index.ts
│ │ ├── envDetection
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ └── storage
│ │ └── localStorage
│ │ ├── helpers.ts
│ │ └── index.ts
│ ├── wasm
│ │ └── fibonacci
│ │ ├── fibonacci_wasm.d.ts
│ │ ├── fibonacci_wasm_bg.wasm
│ │ ├── fibonacci_wasm_bg.wasm.d.ts
│ │ └── index.js
│ └── worker
│ └── fibonacciWorker.ts
├── tsconfig.json
└── yarn.lock
3. 展望
其实呢,这个项目还有很多功能需要完善。
如果大家使用了会发现,我们有些的工具是限定死的。
例如,我们推崇只使用yarn
来作为包管理器。使用vscode
作为IDE
。
这块也是我们后期需要丰富的地方。
这里我们有一个TODO List
兼容 pnpm/npm/yarn
兼容常规 IDE
兼容更多构建工具 Webpack/Vite/Rsbuild
兼容 Vue
的项目构建。兼容 monorepo
项目的构建
针对第四/五点,其实我们已经在做这方面的努力了。
对应的我们已经构建好对于的枚举类型- FrameworksType
#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]
pub enum FrameworksType {
React,
Vue,
}
同时,在create_project
函数中,已经有了对Monorepo
和FrameworksType
的渴望。只不过,因为有些效果还没达到要求。这方面的需求先搁置了。我们打算把这些需求放到下一个大版本中。
后记
分享是一种态度。
全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。
f_cli_f: https://www.npmjs.com/package/f_cli_f
[2]Rsbuild: https://rsbuild.dev/zh/guide/start/
[3]dialoguer: https://github.com/console-rs/dialoguer
[4]code-inspector-plugin: https://inspector.fe-dev.cn/
我是 ssh,工作 6 年+,阿里云、字节跳动 Web infra 一线拼杀出来的资深前端工程师 + 面试官,非常熟悉大厂的面试套路,Vue、React 以及前端工程化领域深入浅出的文章帮助无数人进入了大厂。 欢迎 长按图片加 ssh 为好友
,我会第一时间和你分享前端行业趋势,学习途径等等。2024 陪你一起度过!