给我 0.02 秒,生成一套 Vite/Rsbuild 前端项目

科技   2024-11-04 08:03   江苏  
在阅读此文之前,尝试在电脑的命令行中执行npx f_cli_f create xxx(xxx是你想要构建的项目)

此篇文章所涉及到的技术有

  1. Rust
  2. 脚手架
  3. Vite
  4. Rsbuild
  5. Biome
  6. 跨平台编译

因为,行文字数所限,有些概念可能会一带而过亦或者提供对应的学习资料。请大家酌情观看。


前言

还记得我们之前写过Rust写一个前端脚手架的系列文章吗?

  1. Rust 赋能前端-开发一款属于你的前端脚手架
  2. 如何在Rust中操作JSON
  3. Rust 写脚手架,Clap你应该知道的二三事
  4. Rust跨平台编译

其实呢,要想用Rust写一个脚手架,上面的内容就足够了。剩下的核心的部分其实就是脚手架内部逻辑了。

之前呢,我们已经发布过一版f_cli_f[1]。主要是针对Vite项目的构建。此次版本升级,我们新增了对Rsbuild的支持。并且将部分冗余的功能剔除或者让用户自行选择。

运行效果

大家可以在自己的电脑环境执行上面的操作。npx f_cli_f create demo


好了,天不早了,干点正事哇。


我们能所学到的知识点

  1. 迎新
  2. 辞旧
  3. 展望

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

命令自动化

在之前的版本中,像一些

  1. husky的实例化,
  2. 项目初始化后打开编辑器
  3. 安装项目依赖

这些操作都需要自己手动完成。而此次更新之后,这些操作我们都使用了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的文件目录,用于存放项目中可能会用到的wasmweb 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的文件

其中有几点比较好玩

  1. 设置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"
  },
}
  1. 设置search.exclude限定搜索范围
{
  "search.exclude": {
    "**/node_modules"true,
    "**/*.log"true,
    "**/*.log*"true,
    //省略部分代码
  },
}

相关的配置还有files.exclude

  1. 设置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

  1. 兼容pnpm/npm/yarn
  2. 兼容常规IDE
  3. 兼容更多构建工具Webpack/Vite/Rsbuild
  4. 兼容Vue的项目构建。
  5. 兼容monorepo项目的构建

针对第四/五点,其实我们已经在做这方面的努力了。

对应的我们已经构建好对于的枚举类型- FrameworksType

#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]
pub enum FrameworksType {
    React,
    Vue,
}

同时,在create_project函数中,已经有了对MonorepoFrameworksType的渴望。只不过,因为有些效果还没达到要求。这方面的需求先搁置了。我们打算把这些需求放到下一个大版本中。


后记

分享是一种态度

全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。

Reference
[1]

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 陪你一起度过!


  • 关注公众号,发送消息:
    指南获取高级前端、算法学习路线,是我自己一路走来的实践。
    简历获取大厂简历编写指南,是我看了上百份简历后总结的心血。
    面经获取大厂面试题,集结社区优质面经,助你攀登高峰
因为微信公众号修改规则,如果不标星或点在看,你可能会收不到我公众号文章的推送,请大家将本公众号星标,看完文章后记得点下赞或者在看,谢谢各位!

前端从进阶到入院
我是 ssh,只想用最简单的方式把原理讲明白。wx:sshsunlight,分享前端的前沿趋势和一些有趣的事情。
 最新文章