>首页> IT >

【世界报资讯】秒懂Vue3+Vite3源码,只要会这20个库!

时间:2022-07-28 18:04:50       来源:转载
正所谓:工欲善其事,必先利其器!写一个开源的项目也不例外,就拿在国内很火的 vue3 框架vite 工具来讲,其中的实现与架构设计无不是一个 复杂而庞大的工程,而支撑这些工程能顺利运行的无不是一个又一个的轮子,正好最近有在阅读 vue3 和 vite3 的源码,发现一些较实用的轮子,在这里分享给大家。

如果你想对 前端工程化有所涉猎的话,我相信下面的工具总有一款是你想要的!

1. picocolors

picocolors 是一个可以在终端修改输出字符样式的 npm包,说直白点就是给字符添加颜色;


【资料图】

可能有的同学想到了,这不是跟 chalk 一样的吗?

没错,他们的作用其实就是一样的!

为什么选择 picocolors:

无依赖包;比 chalk 体积小 14 倍,速度快 2 倍;支持 CJS 和 ESM 项目;

所以大家明白选什么了吧!

当然因为 picocolors包比较小,所以功能边界没有 chalk的全面,但是用在一些自研等绝大部分的需求中是完全可以满足的。

2. promptsvs enquirervs inquirer

乍一看,可能有的同学会有点懵,其实一句话交代就是:其实他们三都是用来 实现命令行交互式界面的工具;

之所以放在一起是因为 vue3vite所使用的交互式工具不尽相同;

工具名何处使用大小周下载量github 地址
promptsvite187 kB18,185,030prompts
enquirervue3197 kB13,292,137enquirer
inquirer其它87.7 kB24,793,335inquirer

npm 近两年下载热度趋势:

简单总结:

其实 vite起初也是使用的 enquirer,只是后面为了满足用户跨平台使用时出现的 bug,才替换成了 prompts,当然也并不是说 enquirer不好,只是场景不同,所以选择会有所不同罢了;

其实如果你想在自己的项目中使用 交互式界面工具,我这边还是比较推荐 inquirer的,毕竟社区受欢迎程度和功能都是完全满足你的需求的。

3. cac

cac 是一个用于构建 CLI 应用程序的 JavaScript 库;

通俗点讲,就是给你的 cli 工具增加自定义一些命令,例如 vite create,后面的 create命令就是通过 cac 来增加的;

因为该库较适用于一些自定义的工具库中,所以只在 vite中使用, vue3并不需要该工具;

为什么不用 commander or yargs ?

主要是因为 vite 的工具是针对一些自定义的命令等场景不是特别复杂的情况;

我们看看 cac 的优势

超轻量级:没有依赖,体积数倍小于 commanderyargs易于学习:只需要学习 4 API cli.optioncli.versioncli.helpcli.parse即可搞定大部分需求;功能强大:启用默认命令,可以像使用 git 的命令一样方便去使用它,且有参数和选项的校验、自动生成 help 等完善功能;

4. npm-run-all

npm-run-all 是一个 cli工具,可以并行、或者按顺序执行多个 npm脚本;npm-run-allvite工具源码中有使用;

通俗点讲就是为了解决官方的 npm run 命令无法同时运行多个脚本的问题,它可以把诸如 npm run clean && npm run build:css && npm run build:js && npm run build:html的一长串的命令通过 glob 语法简化成 npm-run-all clean build:*一行命令。

提供三个命令:

npm-run-all:可以带 -s-p参数的简写,分别对应串行和并行;
# 依次执行这三个任务命令npm-run-all clean lint build# 同时执行这两个任务命令npm-run-all --parallel lint build# 先串行执行 a 和 b, 再并行执行 c 和 dnpm-run-all -s a b -p c d
run-s:为 npm-run-all --serial的缩写;run-p:为 npm-run-all --parallel的缩写;

5. semver

semver 是一个语义化版本号管理的 npm库;semvervue3框架源码和 vite工具源码中都有使用;

说直白一点,你在开发一个开源库的时候,肯定会遇到要提醒用户不同版本号不同的情况,那么如何去判断用户版本过低,semver就可以很好的帮助你解决这个问题;

semver内置了许多方法,比如 判断一个版本是否合法,判断版本号命名是否正确,两个版本谁大谁小之类等等方法;

如下列一些官网的例子:

const semver = require("semver")semver.valid("1.2.3") // "1.2.3"semver.valid("a.b.c") // nullsemver.clean("  =v1.2.3   ") // "1.2.3"semver.satisfies("1.2.3", "1.x || >=2.5.0 || 5.0.0 - 7.2.3") // truesemver.gt("1.2.3", "9.8.7") // falsesemver.lt("1.2.3", "9.8.7") // truesemver.minVersion(">=1.0.0") // "1.0.0"semver.valid(semver.coerce("v2")) // "2.0.0"semver.valid(semver.coerce("42.6.7.9.3-alpha")) // "42.6.7"

更多使用方法 详见文档

6. minimist

minimist 是一个命令行参数解析工具;minimistvue3框架源码和 vite工具源码中都有使用;

使用:

const args = require("minimist")(process.argv.slice(2))

例如:

# 执行以下命令vite create app -x 3 -y 4 -n5 -abc --beep=boop foo bar baz# 将获得{ _: [ "foo", "bar", "baz" ],  x: 3,  y: 4,  n: 5,  a: true,  b: true,  c: true,  beep: "boop" }

特别要说明的是返回值其中首个 key 是_,它的值是个数组,包含的是所有没有关联选项的参数。

7. magic-string

magic-string 是一个用于操作字符串和生成源映射的小而快的库;

其实它最主要的功能就是对一些源代码和庞大的 AST字符串做轻量级字符串的替换;

vite工具源码和 @vue/compiler-sfc中大量使用;

使用:

import MagicString from "magic-string";const s = new MagicString("problems = 99");// 替换 problems -> answers.overwrite(0, 8, "answer")s.toString() // "answer = 99"// 生成 sourcemapvar map = s.generateMap({  source: "source.js",  file: "converted.js.map",  includeContent: true})

8. fs-extra

fs-extra 是一个强大的文件操作库, 是 Nodejs fs 模块的增强版;

这个就不多讲了,因为它在千锤百炼之下只能形容它是 YYDS,查看 更多官方文档。

9. chokidar

chokidar 是一款专门用于文件监控的库;chokidar只在 vite工具源码中有使用;

其实 Node.js 标准库中提供 fs.watchfs.watchFile两个方法用于处理文件监控,但是为什么我们还需要chokidar呢?

主要是由于 兼容性不好、无法监听、监听多次等大量影响性能的问题;

chokidar 用法:

const chokidar = require("chokidar");const watcher = chokidar.watch("file, dir, glob, or array", {  ignored: /(^|[\/\\])\../,  persistent: true});watcher  .on("add", path => console.log(`File ${path} has been added`))  .on("change", path => console.log(`File ${path} has been changed`))  .on("unlink", path => console.log(`File ${path} has been removed`))  .on("addDir", path => console.log(`Directory ${path} has been added`))  .on("unlinkDir", path => console.log(`Directory ${path} has been removed`))  .on("error", error => console.log(`Watcher error: ${error}`))  .on("ready", () => console.log("Initial scan complete. Ready for changes"))  .on("all", (event, path) => console.log(event,path))  .on("raw", (event, path, details) => {    log("Raw event info:", event, path, details);  });

10. fast-glob

fast-glob 是一个快速批量导入、读取文件的库; fast-glob只在 vite工具源码中有使用;

基本语法:

*:匹配除斜杆、影藏文件外的所有文件内容;

**:匹配零个或多个层级的目录;

?:匹配除斜杆以外的任何单个字符;

[seq]:匹配 []中的任意字符 seq;

如何使用:

const fg = require("fast-glob");const entries = await fg([".editorconfig", "**/index.js"], { dot: true });

vite中使用:

vite工具中 import.meta.glob方法(如下)就是基于这个库来实现,所以如果你在自己的工具库中有批量文件等的操作,这个库是以很不错的选择;

const modules = import.meta.glob("./dir/*.js", { query: { foo: "bar", bar: true } })

vite通过 fast-glob工具把它生成如下代码

// vite 生成的代码const modules = {  "./dir/foo.js": () =>    import("./dir/foo.js?foo=bar&bar=true").then((m) => m.setup),  "./dir/bar.js": () =>    import("./dir/bar.js?foo=bar&bar=true").then((m) => m.setup)}

11. debug

debug 是一个模仿 Node.js核心调试技术的小型 JavaScript调试程序,在适用于 Node.jsWeb 浏览器都可使用;debug只在 vite工具源码中有使用;

说直白点就是你可以使用 debug 来对你的程序进行 毫秒级别时间差的统计对你程序代码进行优化;

使用:

var debug = require("debug")("http")  , http = require("http")  , name = "My App";// fake appdebug("booting %o", name);http.createServer(function(req, res){  debug(req.method + " " + req.url);  res.end("hello\n");}).listen(3000, function(){  debug("listening");});// fake worker of some kindrequire("./worker");

12. dotenv

dotenv 是一个零依赖模块,可将 .env 文件中的环境变量加载到 process.env中;dotenv只在 vite工具源码中有使用;

如何使用:

1、创建 .env 文件

S3_BUCKET="YOURS3BUCKET"SECRET_KEY="YOURSECRETKEYGOESHERE"

2、使用

import * as dotenv from "dotenv"dotenv.config()console.log(process.env)

13. esbuild

esbuild 是一个基于 Go 语言开发的 JavaScript 打包工具,被 Vite 用于开发环境的依赖解析;

相比传统的打包工具,主打性能优势,在构建速度上可以快 10~100 倍;

优势:

没有缓存机制也有极快的打包速度支持es6和cjs模块支持es6 modules的tree-shaking支持ts和jsxsourcemap压缩工具自定义的插件开发

使用:

esbuild在 API 层面上非常简洁, 主要的 API 只有两个: TransformBuild, 这两个 API 可以通过 CLI, JavaScript, Go 的方式调用;

1、transform:调用这个API能将 tsjsx等文件转换为js文件;

// cliexbuild ./test.ts --loader=ts // 输出 const str = "Hello World";// js api调用const esbuild = require("esbuild");const fs = require("fs");const path = require("path");const filePath = path.resolve(__dirname, "test.ts");const code = esbuild.transformSync(fs.readFilesync(filePath), {    loader: "ts",})console.log(code);// 输出// {//  code: "const str = "Hello World"",//  map: "",//  warnings: []// }

2、build:整合了transform后的代码,可以将一个或者多个文件转换并保存为文件;

// cliesbuild test.ts --outfile=./dist/test.js // { errors: [], warnings: [] }// js api调用const esbuild = require("esbuild");const path = require("path");const result = esbuild.buildSync({  entryPoints: [path.resolve(__dirname, "test.ts")],  outdir: path.resolve(__dirname, "dist"),});console.log(result); // { errors: [], warnings: [] }

14. rollup

rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,我们熟悉的 vue、react、vuex、vue-router 等都是用 rollup 进行打包的。

vite中的生产环境(Production)就是基于 rollup打包来构建主要代码的。

使用:

1、创建 rollup.config.js文件

2、配置文件

export default {  input: "src/index.js",  output: {    name: "amapUpper",    file: "dist/amapUpper.js",    format: "umd"  },  plugins: []};

3、运行

{  "scripts": {    "dev": "rollup -i src/index.js -o dist/bundle.js -f es"  },}

4、执行 npm run dev

15. ws

ws 是一个简单易用、速度极快且经过全面测试的 WebSocket 客户端服务器实现;完全可以是 Socket.io的替代方案;ws只在 vite工具源码中有使用。

说直白一点就是通过 ws,咱们可以实现服务端和客户端的长连接,且通过 ws对象,就可以获取到 客户端发送过来的信息主动推送信息给客户端

使用:

1、server.js

const WebSocket = require("ws")    const WebSocketServer = WebSocket.Server;        // 创建 websocket 服务器 监听在 3000 端口     const wss = new WebSocketServer({port: 3000})         // 服务器被客户端连接     wss.on("connection", (ws) => {         // 通过 ws 对象,就可以获取到客户端发送过来的信息和主动推送信息给客户端         var i=0         var int = setInterval(function f() {             ws.send(i++) // 每隔 1 秒给连接方报一次数         }, 1000)     })

2、client.js

const WebSocket = require("ws")const ws = new WebSocket("ws://localhost:3000")// 接受ws.on("message", (message) => {  console.log(message)    // 当数字达到 10 时,断开连接    if (message == 10) {      ws.send("close");      ws.close()  }})

16. connect

connect 是一个最早期的 HTTP 服务器框架,亦可称为中间件插件;express就是基于此框架做的扩展;

注意:从 vite2开始官方已从依赖 koa转成 connect了;

至于为什么使用 connect而不是 koa,咱们看官方的回答:

大概意思就是:由于大部分逻辑应该通过插件钩子而不是中间件来完成,因此对中间件的需求大大减少;所以使用 connect优先级会高于 Koa

17. esno

esno 是一个基于 esbuildTS/ESNextNode.js运行时;

说直白点就是可以类似 ts-node一样直接运行 TS 文件,那为甚么还用 esno呢?

因为 esno是基于 esbuild运行的,esbuild有多快,上面我们有讲到了吧,这里就不复述了。

使用:

{  "scripts": {    "start": "esno index.ts"  },  "dependencies": {    "esno": "*"  }}
npm run start

18. tsup

tsup 是一个轻小且无需配置的,由 esbuild支持的打包工具;

它可以直接把 .ts、.tsx转成不同格式 esm、cjs、iife的文件,快速打包你的工具库;

使用:

1、安装 tsup

pnpm i tsup -D

2、在根目录下的 package.json中配置

{  "scripts": {    "dev": "pnpm run build -- --watch --ignore-watch examples",    "build": "tsup src/index.ts --dts --format cjs,esm"  },}

19. vitepress

vitepress 是在 vuepress的基础上实现的静态网站生成器,区别在于 vitepress是建立在 vite之上做的开发;

优势:

基于 vite而不是 webpack,所有更快的启动时间,热重载等;使用 vue3来减少 js 的有效负载;

20. vitest

vitest 是一个由 vite提供支持的快速单元测试框架。

优势:

由 Vite ⚡️ 提供支持的极速单元测试框架。

与 Vite 的配置通用,watch 模式下极快的反应(相当于测试中 HMR)。

可以对 Vue/React 组件进行测试。

开箱即用 Typescript/JSX/ESM(这一点我想配过 jest 的人应该懂是什么意思)

与 Jest 几乎相同的 API,同时也有 Jest 的快照功能(这个非常好用!)

模拟 DOM

生成测试覆盖率

ESM优先,顶级等待

开箱即用的 TypeScript / JSX 支持

套件和测试的过滤、超时、并发

等等

其它

其实细心的同学可能会发现,目前 vue3vite3都是一个 monorepo仓库,且都是使用 pnpm workspace来进行仓库管理的;

所以了解 monorepopnpm workspace对源码的阅读也是有很大的帮助的;

当然,上面的分享的工具库只是在源码中使用 场景较多的库,还有一些库由于 场景较少所以这里没有做详细的解释说明,如果您想了解源码中的哪个工具库,欢迎补充,取舍后我会做及时的更新;

关键词: 单元测试