前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue3工具函数源码踩坑记

Vue3工具函数源码踩坑记

作者头像
玖柒的小窝
修改2021-10-09 14:17:25
5350
修改2021-10-09 14:17:25
举报
文章被收录于专栏:各类技术文章~各类技术文章~

一、学习前的准备

下面内容来自若川-源码共读群~~

1.1 我开始啦

step1:
代码语言:javascript
复制
    git clone https://github.com/vuejs/vue-next.git
复制代码

听川川的,查看一下版本

代码语言:javascript
复制
admin@ayuandeMacBook-Pro vue-next % node -v
v10.19.0
admin@ayuandeMacBook-Pro vue-next % yarn -v 
zsh: command not found: yarn
复制代码

竟然没装yarn,安排一下

代码语言:javascript
复制
    npm install --global yarn
    
复制代码

OK啦:

代码语言:javascript
复制
admin@ayuandeMacBook-Pro vue-next % yarn build
yarn run v1.22.11
    
复制代码

一切准备就绪: 结果。。。 npm install??

npm run build ??

yarn install?? 没反应,一直报错,心态爆炸,认真审题很重要,仔细看文档也一样!

后来发现,傻啦吧唧的全搞错了,人家川川文章里那么明细的写着(赶紧抄过来记笔记):

为了降低文章难度,我按照贡献指南中方法打包把ts转成了js。如果你需要打包,也可以参考下文打包构建。 你需要确保 Node.js 版本是 10+, 而且 yarn 的版本是 1.x Yarn 1.x。 你安装的 Node.js 版本很可能是低于 10。最简单的办法就是去官网重新安装。也可以使用 nvm等管理Node.js版本

代码语言:javascript
复制
    node -v
    # v14.16.0
    # 全局安装 yarn

    # 推荐克隆我的项目
    git clone https://github.com/lxchuan12/vue-next-analysis.git
    cd vue-next-analysis/vue-next

    # 或者克隆官方项目
    git clone https://github.com/vuejs/vue-next.git
    cd vue-next

    npm install --global yarn
    yarn # install the dependencies of the project
    yarn build
复制代码

最后安装好了yarn之后只需要执行一下操作:

代码语言:javascript
复制
yarn

yarn build

复制代码

好了运行结束后, 终于成功将ts打包成js了。 绝绝子,想不通自己浪费大把时间在这较什么劲呢!

1.2 插曲之安装环境小总结:

之前自己的node版本是v.10.X,一些高级的东西需要高版本,为了不来回的装node不同版本,我需要用nvm工具!!!可是我滴Mac上没有装过啊,于是就有了痛苦面具下的下面的操作总结

1、macos,因为涉及升级node版本,为了方便管理node版本切换,需要安装nvm node版本管理工具。

2、安装nvm时,尝试查询资料说不macos系统安装nvm前必须要卸载npm 和node,卸载干干净净。

3、卸载完成后, 根据官网教程安装:

代码语言:javascript
复制
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
复制代码

结果抛出 SSL_ERROR_SYSCALL in connection to raw.githubusercontent.com:443错误,脑阔疼!

4、搜来搜去,说需要修改hosts文件,新增dns域名配置:配置后更新无果还是443,生气ing(原因:据说mac不能通过外部链接来安装,也有一种说法说是dns污染,需要配置host,但是把配置了host也是无效啊。)

代码语言:javascript
复制
199.232.68.133	raw.githubusercontent.com
复制代码

5、最终找到有效方法:使用gitee镜像安装

使用gitee镜像安装
1、安装nvm
代码语言:javascript
复制
git clone https://gitee.com/mirrors/nvm.git ~/.nvm && cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`
复制代码
2、配置nvm环境变量

a、进入.bash_profile文件设置环境变量:

代码语言:javascript
复制
vi ~/.bash_profile
复制代码

b、配置环境变量:

代码语言:javascript
复制
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
复制代码

c、执行命令生效:

代码语言:javascript
复制
source ~/.bash_profile
复制代码

如果shell使用的是非zsh,以上三步配置完即可,如果是zsh环境,需要多配置以下

如何查看shell:

代码语言:javascript
复制
echo $SHELL

---------
如果显示:
/bin/zsh
复制代码

则执行d、

d、zsh配置: 打开.zshrc文件,操作如下:

代码语言:javascript
复制
vim ~/.zshrc
复制代码

配置信息如下:

代码语言:javascript
复制
source ~/.bash_profile
复制代码

保存后退出执行如下命令行使之生效:

代码语言:javascript
复制
source ~/.zshrc
复制代码

经过如上步骤配置,nvm也配置成功了: 可查看nvm版本:

代码语言:javascript
复制
nvm -v

0.38.0
复制代码

抱头痛哭,这么简单的东西终于给我装好了。 !!!

好了, 之前运行的npm install --global yarn 的yarn也没有了,需要重新安装下, 巴拉巴拉一顿操作后迎接我的又是一片终端报错红彤彤,逐渐失去耐心,回头猛然想起,我的macos啊!!!没权限访问它了。

代码语言:javascript
复制
sudo npm install --global yarn
复制代码

一顿操作猛如虎,终于把这个vuex-next的打包搞定了,绝绝子,这下可以安心看小工具源码了,不费川川被我骚扰千百回解决的问题啊,好了下面我要开始认真学习看源码了!

二、 重点:工具函数

看了下文章目录vue-next/packages/shared/src/index.ts 按照这个文件里的代码顺序讲解,那我就慢慢看吧

1、 babelParserDefaultPlugins 是babel解析默认插件

来来来copy一份源代码

代码语言:javascript
复制
/**
 * List of @babel/parser plugins that are used for template expression
 * transforms and SFC script transforms. By default we enable proposals slated
 * for ES2020. This will need to be updated as the spec moves forward.
 * Full list at https://babeljs.io/docs/en/next/babel-parser#plugins
 */
export const babelParserDefaultPlugins = [
  'bigInt',
  'optionalChaining', 
  'nullishCoalescingOperator'
] as const

复制代码

不懂就问系列,上面的是TS代码中, as const 是什么意思呢? 查阅了下,哦吼,原来是TS中的类型断言啊!

对比转换为js后代码如下,顺便自带翻译一下注释:

代码语言:javascript
复制
/**
*用于模板表达式的@babel/parser插件列表
*转换和SFC脚本转换。默认情况下,我们启用计划的提案
*以下都是针对ES2020新特性做babel转换用的。
*详细babel插件列表查看:https://babeljs.io/docs/en/next/babel-parser#plugins
*/
const babelParserDefaultPlugins = [
    'bigInt', //ES2020新增特性 
    'optionalChaining', // 可选链`?.`
    'nullishCoalescingOperator' //空值合并运算符`??`
];
复制代码
1.1babel解析默认插件
1.1.1 bigInt

我们已经用Number来表示JS中的数字,问题在于最大的数字是2⁵³,再往上的数字就不可靠了。

代码语言:javascript
复制
const x = Number.MAX_SAFE_INTEGER; // 9007199254740991
const y = x + 1; // 9007199254740992 • equal to 2^53
const z = x + 2; // 9007199254740992 • well, it's broken
复制代码

BigInt提供了一种方法,来表示大于2⁵³的数字。通过在整数末尾添加n来创建

代码语言:javascript
复制
const aBigInteger = 9007199254740993n;
// There is also a constructor:
const evenBigger = BigInt(9007199254740994); // 9007199254740994n
const fromString = BigInt("9007199254740995"); // 9007199254740995n
复制代码

BigInt通常的操作与数字相同,但不能在运算中一同使用:

代码语言:javascript
复制
let sum = 1n + 2, multiplication = 1n * 2;
// TypeError: Cannot mix BigInt and other types, use explicit conversions
复制代码

可使用构造函数Number()将BigInt转化为Number,但在某些情况下可能会失去精度。因此,建议仅在代码中相应预期数值较大时再使用BigInt。

代码语言:javascript
复制
Number(900719925474099267n); // 900719925474099300 • ????‍♂️

复制代码

@babel/plugin-syntax-bigint: 官网-@babel/plugin-syntax-bigint

1.1.2 optionalChaining-可选链运算符?.

例如原来遍历对象如下:

代码语言:javascript
复制
// Checking for intermediate nodes:
const deeplyNestedValue = obj && obj.prop1 && obj.prop1.prop2;// Checking if the node exists in the DOM:
const fooInputEl = document.querySelector('input[name=foo]');
const fooValue = fooInputEl && fooInputEl.value;
复制代码

采用可选链运算符后:

代码语言:javascript
复制
// Checking for intermediate nodes:
const deeplyNestedValue = obj?.prop1?.prop2;// Checking if the node exists in the DOM:
const fooValue = document.querySelector('input[name=foo]')?.value;
复制代码

可选链运算符是一个短路计算操作,即当左侧?.检查到null或undefined时,就会停止表达式的运行

代码语言:javascript
复制
// x is incremented if and only if 'a' is not null or undefined
a?.[++x] 
复制代码

参考借鉴: 可选链plugin-proposal-optional-chaining的使用

1.1.3 nullishCoalescingOperator -空值合并运算符??

当执行属性访问时尝试提供默认值,新的方法便是采用空值合并运算符。与or运算符不同,我们在两个操作数之间以 ??来代替||操作符。

代码语言:javascript
复制
const test = {
  null: null,
  number: 0,
  string: '',
  boolean: false
};
const undefinedValue = test.dog || "Cat"; // "Cat"
const undefinedValue = test.dog ?? "Cat"; // "Cat"const nullValue = test.null || "Default"; // "Default"
const nullValue2 = test.null ?? "Default"; // "Default"const numberValue = test.number || 1; // 1
const numberValue2 = test.number ?? 1; // 0const stringValue = test.string || "Hello"; // "Hello"
const stringValue2 = test.string ?? "Hello"; // ""const booleanValue = test.boolean || true; // true
const booleanValue2 = test.boolean ?? true; // false
复制代码

如上所示,空值合并运算符仅在 ??左侧的操作数为null或undefined时,返回右侧的操作数。

官网:@babel/plugin-proposal-nullish-coalescing-operator

1.2 TS语法-TS的类型断言
1.2.1 TS断言概念及作用?

有时候你会遇到这样的情况,你会比TypeScript更了解某个值的详细信息。 通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。

通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript会假设你,程序员,已经进行了必须的检查。

1.2.2 TS断言语法?

类型断言有两种形式。 其一是“尖括号”语法:

代码语言:javascript
复制
let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;

//有兼容性问题, 在使用到了JSX的时候兼容性不是很好
复制代码

另一个为as语法:

代码语言:javascript
复制
let someValue: any = "this is a string";

let strLength: number = (someValue as string).length;
复制代码

两种形式是等价的。

至于使用哪个大多数情况下是凭个人喜好;然而,当你在TypeScript里使用JSX时,只有 as语法断言是被允许的。

延伸参考:TS的类型断言

1.3 总结

第一个工具方法:babelParserDefaultPlugins- babel 解析器默认插件 看着没几行代码, 但是平时自己用的并不多,写TS语法的代码也少。babel中的三个都是用于转换ES2020新增特性用的。其中详细看了下对应几个babel插件作用,以及复习下TS断言的作用,一步一步操作理解,印象比较深刻。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、学习前的准备
    • 1.1 我开始啦
      • step1:
    • 1.2 插曲之安装环境小总结:
      • 使用gitee镜像安装
  • 二、 重点:工具函数
    • 1、 babelParserDefaultPlugins 是babel解析默认插件
      • 1.1babel解析默认插件
      • 1.2 TS语法-TS的类型断言
      • 1.3 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档