源码地址

https://github.com/vuejs/vue-next

环境准备

1. 查看 Vuejs 贡献指南

https://github.com/vuejs/vue-next/blob/master/.github/contributing.md
使用的是 pnpm(不是本期重点,可查看附录链接,查看使用原因):https://pnpm.io/
截屏2021-11-10 下午2.46.45.png

2. 生成 sourcemap 代码版本

截屏2021-11-10 下午5.25.42.png

  1. npm run dev --sourcemap

3. 例子引用

执行后生成 vue.global.js,因此可以直接构造 html 例子引入即可定位查看源码:

  1. created packages/vue/dist/vue.global.js in 2.3s
  1. <html>
  2. <body>
  3. <div id="counter">{{ counter }}</div>
  4. <script src="../packages/vue/dist/vue.global.js"></script>
  5. <script>
  6. const Counter = {
  7. data() {
  8. return {
  9. counter: 12321321
  10. }
  11. }
  12. }
  13. Vue.createApp(Counter).mount('#counter')
  14. </script>
  15. </body>
  16. </html>

截屏2021-11-14 下午4.58.34.png

工具函数

1. 常量赋值

一般使用在默认值赋值上:

  1. // 空 object
  2. export const EMPTY_OBJ: { readonly [key: string]: any } = __DEV__
  3. ? Object.freeze({})
  4. : {}
  5. // 空 array
  6. export const EMPTY_ARR = __DEV__ ? Object.freeze([]) : []
  7. // 空 function
  8. export const NOOP = () => {}
  9. // 永远只会返回 false 的函数
  10. /**
  11. * Always return false.
  12. */
  13. export const NO = () => false

开发环境(DEV = true)时,EMPTY_OBJ 和 EMPTY_ARR 都使用 Object.freeze,避免在开发过程中修改到该引用类型值(https://github.com/vuejs/vue-next/commit/edd49dcab40eb3faa44248772b176d5eebfd30fe

2. 类型判断

  1. // 判断是不是 数组
  2. export const isArray = Array.isArray
  3. // 判断是不是 Map
  4. export const isMap = (val: unknown): val is Map<any, any> =>
  5. toTypeString(val) === '[object Map]'
  6. // 判断是不是 Set
  7. export const isSet = (val: unknown): val is Set<any> =>
  8. toTypeString(val) === '[object Set]'
  9. // 判断是不是 日期
  10. export const isDate = (val: unknown): val is Date => val instanceof Date
  11. // 判断是不是 函数
  12. export const isFunction = (val: unknown): val is Function =>
  13. typeof val === 'function'
  14. // 判断是不是字符串
  15. export const isString = (val: unknown): val is string => typeof val === 'string'
  16. // 判断是不是 Symbol
  17. export const isSymbol = (val: unknown): val is symbol => typeof val === 'symbol'
  18. // 判断是不是 Object
  19. export const isObject = (val: unknown): val is Record<any, any> =>
  20. val !== null && typeof val === 'object'
  21. // 判断是不是 Promise
  22. export const isPromise = <T = any>(val: unknown): val is Promise<T> => {
  23. return isObject(val) && isFunction(val.then) && isFunction(val.catch)
  24. }

附录

  1. 为什么使用 pnpm:https://zhuanlan.zhihu.com/p/352437367
  2. pnpm 使用符号链接创建 node_modules 结构:https://pnpm.io/zh/symlinked-node-modules-structure
  3. pnpm 严格性有助于避免愚蠢错误:https://www.kochan.io/nodejs/pnpms-strictness-helps-to-avoid-silly-bugs.html