在看文章前,先做个定位,这不是一篇纯粹的技术性文章,可以把它理解成一个叙述文章,记录我开发插件的过程。

开始前简单的吹个牛

vue2 也写了很多年了,多人合作始终避不开用到别人的组件。关键是有些组件没有文档看起来是真的费劲。props还可以直接通过组件看出来,emit,ref,slot代码一多看起来就比较费劲了。也想过一些解决方案,比如每个组件写一个 readme。这就有一个问题,时间太紧了,谁来给你写 readme 哦,开玩笑。

所以如果有一个能够自动解析 vue 组件的东西就好了。在网上搜索了一下,vue 自动生成文档,还真的有这么个东西vuese,基本满足要求,但是有几点不是很满意。

  • 不支持 vue3
  • 每次生成文档需要 run 一下命令,当然也可以用 nodemon 监听。但就是觉得有点 low
  • ui 不是很好看(这个有点鸡蛋挑骨头,也是后面开始自己造 vite 插件的原因)

总体来说 vuese 是一个很好的项目,我的插件里面很多的思路都是参考(其实就是抄 )了 vuese,我列出他的不好的,只是单纯的给自己找个理由造个轮子。。。

说了这么多你可能已经猜到我要造一个什么插件了,总结一下:

  • 自动解析 vue,并且支持 vue3
  • 支持热更新,写了代码能立即看到实时预览
  • 好看的 ui,最好能够让别人一看到文档就觉得我写的代码很 nb,先不说代码好不好,就看文档就要能唬住人

那么为什么是 vite 插件南?

  • 刚出来没多久,相比于 webpack 轮子比较少
  • 初步了解好像大多数轮子都是用 ts 写的,所以蹭着机会,学一波 ts。
  • vite 介绍比传统快 10-100 倍,初步体验确实比较快。不过这不是主要原因,主要的是他比较新呀,轮子少,我可以顺势蹭一波热度,说不定火了,就涨工资了。

吹了牛,需求也明确了

一直以为做一个开源最难的不是开发,而是弄到一个好一点的需求。但是这个 vite 插件的开发,还真的有点麻烦,差点就推翻了我的想法。

刚一开始就遇到了一个问题

  • 如何从 vue 文件中获取到 props,slots?

在此之前没有做过类似的项目,也没有遇到过类似的问题,完全不知道如何下手。初步想法是用正则去匹配,仔细想了哈,感觉不是很靠谱,主要是因为我的正则不行。

我想不到怎么去实现,总有人知道怎么做嘛,去瞅瞅vuese怎么实现的。首先看哈 package.json 里面用了那些插件,把不认识的插件全部搜一下,了解有些啥作用。最后发现了这么几个库,可以将 js 代码解析成 ast 语法树,完美的解析 vue。

  1. {
  2. "dependencies": {
  3. "@babel/parser": "^7.10.3",
  4. "@babel/traverse": "^7.10.3",
  5. "@babel/types": "^7.3.0",
  6. "vue-template-compiler": "^2.6.11"
  7. }
  8. }

经常听到 bable 这个东西,却没有深入了解过,没想到 vue 是用 bable 解析出来的,看来还是不行呀

言归正传,一一列举一下他们的作用

插件 作用
@babel/parser 通过 parse 方法将 script 解析成 ast 语法树
@babel/traverse 遍历 ast 语法树,可以更新删除节点
@babel/types 判断当前这个节点是什么类型的
vue-template-compiler 解析.vue 为 ast,vue3 用的是@vue/compiler-sfc

在使用中勒,发现@vue/compiler-sfc 中暴露除了@bable/parse的 parse 方法,bableParse

  1. // compiler-sfc.d.ts
  2. import { parse as babelParse } from '@babel/parser';
  3. ...
  4. export { babelParse }

同时还发现了一个好工具,可在线将 js 代码转换成 ast:astexplorer

搭建开发环境

解决了一个技术性难题后,就开始创建项目,搭建开发环境了。这里就忽略体验 vite demo 和插件 demo 了。

awesome-vite,看了很多的插件源码,总结了一下几个特点

  • 几乎都有两个项目,一个是插件源码,一个是 example 实例,有些插件是 vue、react 等多个框架公用的还会有多个实例
  • 开发环境为了快速打包环境,用的比较多的是 tsup、tsc 这两个插件
  • 因为是源码是 ts 的需要打包成 js,所以 package.json 里面都要 main,types 这两个字段

基础项目结构创建

既然有了这些特点,就可以创建项目,逐步搭建开发环境了

大概的目录结构是这样的

  1. - pacakges/
  2. - vue-docs # 插件源码
  3. - example # example
  4. - packages.json

看到这个 packages,里面还有多个模块,首先想到的就是 lerna + yarn + workspaces,所以直接一把梭

  1. yarn init -y
  2. yarn add lerna -D
  3. npx lerna init
  4. npx lerna create vue-docs
  5. npx lerna create @vue-docs/exampe # 本来应该是这样的,但是example他是一个vite的vue项目,所以用vite来创建
  6. yarn create vite

最后的目录是这样的

  1. - .git
  2. - pacakges/
  3. - example # vite创建的vue项目
  4. - ...
  5. - vue-docs # 插件代码
  6. - ...
  7. - lerna.json
  8. - package.json

修改一下 package.json,结果如下

  1. {
  2. "name": "monorepo", // 参考了一下lerna的写法
  3. "version": "0.0.0", // 0.0.0
  4. "main": "index.js",
  5. "license": "MIT",
  6. "devDependencies": {
  7. "lerna": "^4.0.0"
  8. },
  9. // 新增的
  10. "private": true,
  11. "workspaces": ["packages/*"]
  12. }

项目结构有了,接下来搞一搞vue-docs这个目录

vue-docs 插件目录的搭建

前面已经说了,大多数插件用的都是 ts,并且用到了 tsup/tsc 这两个插件。所以就按照这个标准去搭建

先来安装插件, 这里就直接使用 tsup 了

  1. yarn workspace vue-docs add typescript tsup @babel/preset-typescript @babel/preset-env -D

配置 bable.config.js

  1. // babel.config.js
  2. module.exports = {
  3. presets: [
  4. ["@babel/preset-env", { targets: { node: "current" } }],
  5. "@babel/preset-typescript",
  6. ],
  7. };

在 lib 中新建一个 index.ts,测试一下

  1. export function sum(a: number, b: number): number {
  2. return a + b;
  3. }
  4. sum(1, 2);
  1. npx tsup ./lib/index.ts

发现生成了一个 dist/index.js 文件

  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true }); // lib/index.ts
  3. function sum(a, b) {
  4. return a + b;
  5. }
  6. sum(1, 2);
  7. exports.sum = sum;

到这里基本 vue-docs 的搭建也算完成了,最后把命令加载 package.jsonscripts

  1. {
  2. "scripts": "tsup ./lib/index.ts"
  3. }

到这里,项目基本的雏形已经有了,接下来就是继续完善开发环境。下一节在再见

最后再来推广一波

【记录】如何造一个vite插件(1)的更多相关文章

  1. 【记录】如何造一个vite插件(2)

    上一篇已经把vite插件的基础结构搭建起来了,这一次就来聊聊继续完善开发环境. 完善开发环境 生成d.ts文件 先来修改一下lib/index.ts这个文件 export interface user ...

  2. 第一个Vue插件从封装到发布

    前言 这是我封装的第一个Vue插件,实现的功能是滑动选择省市区,虽然只是一个简单的插件,但还是挺开心的,记录一下步骤. 插件地址:https://github.com/leichangchun/vue ...

  3. 你真的需要一个jQuery插件吗

    jQuery的插件提供了一个很好的方法,节省了时间和简化了开发,避免程序员从头开始编写每个组件.但是,插件也将一个不稳定因素引入代码中.一个好的插件节省了无数的开发时间,一个质量不好的插件会导致修复错 ...

  4. 手把手教你实现一个支持插件化的 uTools 工具箱(一)

    前言 对于前端同学来说,我们会经常用到各种小工具,比如:图床.颜色拾取.二维码生成器.url 管理.文本比对.json 格式化.当然我们可以 chrome 收藏夹来管理各种在线的小工具,但作为一个有追 ...

  5. 动手做第一个Chrome插件

    Chrome插件是令人惊讶的简单,一旦你弄懂它的工作和实现原理.它是由一部分HTML,一部分Js,然后混合了一个叫做manifest.json的Json文件组合而成的整体.这意味着你可以使用你最擅长的 ...

  6. 哇 真的是一个好插件!!!Sublime Text编辑文件后快速刷新浏览器

    http://9iphp.com/web/html/sublime-text-refresh-browser.html这篇博文咯 来源:[Tips]Sublime Text编辑文件后快速刷新浏览器 - ...

  7. 如何自己编写一个easyui插件续

    接着如何自己编写一个easyui插件继续分享一下如何从上一节写的“hello”插件继承出一个“hello2”. 参考了combobox的源码中继承combo,当然我这个简单很多了.都是根据自己的理解来 ...

  8. CKEditor在线编辑器增加一个自定义插件

    CKEditor是一个非常优秀的在线编辑器,它的前身就是FCKEditor,CKEditor据官方说是重写了内核的,但功能和性能比FCKEditor更为强大和优越.记得07年的时候第一次接触FCKEd ...

  9. 【转】怎样创建一个Xcode插件(Part 1)

      原文:How To Create an Xcode Plugin: Part 1/3 原作者:Derek Selander 译者:@yohunl 译者注:原文使用的是xcode6.3.2,我翻译的 ...

随机推荐

  1. CodeGen融合核心关系循环扩展

    CodeGen融合核心关系循环扩展 Expansion Tokens <HARMONYCORE_RELATION_NAME> 插入当前关系的名称.关系名称将自动生成,但可以由Harmony ...

  2. 权限管理(基本权限、附加权限、ACL权限)

    基本权限 •访问方式(权限) 读取:允许查看内容-read   r 写入:允许修改内容-write    w 可执行:允许运行和切换-execute  x 对于文本文件 r: cat   head  ...

  3. 《Docker基础与实战,看这一篇就够了》

    什么是Docker? Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术 ...

  4. bzoj1925 地精部落

    神题! 地精部落 内存限制:128 MiB 时间限制:1000 ms 标准输入输出     题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度 ...

  5. 使用Azure WebJob的一点心得

    Azure WebApp Service 是非常适合中小型项目的云服务. 从我实际使用的感受来看, 有如下几个优点: 1 部署方便, 可以从VS一键发布 2 缩放方便, scale in / scal ...

  6. JavaScript中子函数访问外部变量的方法

    我们在写web页面时,肯定会经常遇到下面这种情况: <body> <div class="btns-wrapper"></div> <sc ...

  7. [Abp vNext 源码分析] - 20. 电子邮件与短信支持

    一.简介 ABP vNext 使用 Volo.Abp.Sms 包和 Volo.Abp.Emailing 包将短信和电子邮件作为基础设施进行了抽象,开发人员仅需要在使用的时候注入 ISmsSender ...

  8. 用python的matplotlib根据文件里面的数字画图像折线图

    思路:用open打开文件,再用a=filename.readlines()提取每行的数据作为列表的值,然后传递列表给matplotlib并引入对应库画出图像 代码实现:import matplotli ...

  9. 基于HSI和局部同态滤波的彩色图像增强

    简介 在图像采集过程中,由于光照环境或物体表面反光等原因会造成图像光照不均 .图像的光照不均会直接影响图像分析的结果.因此,对光照不均图像进行增强,消除光照的影响是光照不均图像处理中不可缺少的环节 . ...

  10. 41、mysql数据库(存储过程)

    0.创建表: (1)建表: CREATE TABLE blog ( id INT PRIMARY KEY auto_increment, name CHAR(64), sub_time datetim ...