抹平多版本差异怎么做?vue-demi 探秘

737 阅读3分钟

什么是多版本

  • vue2 vue2.7 vue3

当前项目切换到高版本的时候,历史遗留的低版本依赖还在怎么解决?

  • 做版本兼容呗?

demi 法语里面 是 半个的意思 介于vue2 vue3之间

这个库就叫vue-demi

什么是postinstall

image.png

就是npm提供的一种能力, 在你安装完这个包以后, 执行一些东西, 可以是shell里面输出一句话, 也可以执行一个脚本, 脚本里面做更加复杂的事情, vue-demi就是采用后者。

实现原理?

  • package.json里面 有scripts的postinstall 脚本 会执行里面的内容

发现

"postinstall": "node -e \"try{require('./scripts/postinstall.js')}catch(e){}\"",

image.png

大致意思就是 包安装完以后 会 用nodejs 执行后面的内容

内容通过 commonjs require语法,动态引入scripts目录下 postinstall 脚本然后执行。

再看 scripts里面 postinstall里面做了什么?

image.png

引入两个工具方法 一个切换版本 一个加载模块

然后 if else 一顿判断:

    1. 没有Vue 或者 有Vue但是 属性version 不是字符串 不处理 给提示
    1. 只支持 2.7.1 2.* 3.* 符合就设置为当前版本,
    1. 在上面三个范围外的,不处理,给提示

加载模块方法的实现

调用nodejs 里面引入模块的语法 require 返回的结果, 做了try catch image.png

切换版本方法的实现

切换版本

image.png

如果是version是2 的话 做了一些特殊的处理

做了一些判断 和过滤 然后拿到内容 并且做了过滤 最后写入

image.png

copy的实现

通过nodejs的 内置的path模块 拿到src和目的地dest的值 通过nodejs的 内置的fs模块拿到 内容,并正则替换成传入的vue的变量的值

然后 unlink

最后将内容写入目标地址

image.png

lib里面的实现

x.iife x.cjs x.mjs 对不同的模块规范做了对应的处理

image.png

里面就是初始化一些变量 ,比如isVue2= true isVue3 =false 再根据真实引入的vue的版本,修改这几个变量的值。

v3 里面 做了什么

将Vue里面的属性 copy到exports对象上 ,并且额外添加 set和 del方法 同时更新一些属性,比如 exports.isVue2 = false exports.isVue3 = true image.png

v2里面做了什么

install方法执行的时候, 有缓存从缓存里面取,没有就引入组合式api 然后use一下 最后将vue/composition-api 里面的属性和方法 copy到exports对象上 同时更新一些属性 image.png

v2.7里面做了什么

对createApp做了mock

image.png

对没有组件进行mock 调用(vue2 里面使用没有实现的vue3里面的组件)的时候会给提示

image.png

.cjs .mjs区别

image.png

image.png

image.png

ts 里面 .d.ts有什么用

image.png

定义函数或者变量的时候 都有类型提示了, 还用这个吗

image.png

  • 1.引入第三方类库, 里面没有ts类型定义, 可以新建一个这样的文件进行补充,或者覆盖。
  • 2.全局变量或者函数的类型定义可以在xx.d.ts里面做 使用 declare
  • 3.模块化声明 image.png

总结

  • nodejs项目 pacakge.json scripts postinstall 钩子的使用 还有preinstall 阮一峰有说过www.ruanyifeng.com/blog/2016/1… 也可以看npm文档docs.npmjs.com/cli/v10/usi… image.png
  • 能有一个这样的项目,也是开发不断挑战自己,解决痛点,才实现的。
  • 后面遇到抹平差异的问题, 可以从这里找找灵感: 没有实现的给提示, 实现了的,有遗漏的,做重新实现。