【Vue源码】第一节Flow、Vue源码目录设计和Rolluo构建Vue.js源码

代码地址:vue2.5.0
参考资料:
- Vue源码探秘系列
- Vue.js 技术揭秘

Flow

Vue.js 的主目录下有 .flowconfig 文件, 它是 flow 的配置文件。其中的[libs]用来描述包含指定库定义的目录,这里指向的是项目根目录下的flow文件夹。打开此目录,可以发现文件结构如下:

flow
├── compiler.js        # 编译相关
├── component.js       # 组件数据结构
├── global-api.js      # Global API 结构
├── modules.js         # 第三方库定义
├── options.js         # 选项相关
├── ssr.js             # 服务端渲染相关
├── vnode.js           # 虚拟 node 相关

Vue源码目录设计

在这里插入图片描述

  • complier

    ├── compiler    # 模板解析相关
        ├── codegen       # 代码生成,把 AST(抽象语法树)转换为 render 函数
        ├── directives    # 转换为 render 函数前要执行的指令
        ├── parser        # 把模板解析为 AST
    
  • core

    ├── core        # Vue 核心代码
        ├── components    # 全局通用组件 Keep-Alive
        ├── global-api    # 全局 api,即 Vue 对象上的方法,如 extend,mixin,use 等
        ├── instance      # Vue 实例化相关代码,如初始化,事件,渲染,生命周期等
        ├── observer      # 响应式数据修改代码
        ├── util          # 工具函数
        ├── vdom          # 虚拟 DOM 相关代码
    
  • platforms

    ├── platforms   # 平台相关代码
        ├── web           # web 平台
            ├── compiler        # 编译时相关
            ├── runtime         # 运行时相关
            ├── server          # 服务端渲染相关
            ├── util            # 工具函数
        ├── weex          # 配合 weex 运行在 native 平台
    

Rollup构建Vue

Webpack 功能相比 Rollup 更加强大,它可以将各种静态资源(包括 cssjs图片等)通通打包成一个或多个 bundle,并按需加载;同时正因为 Webpack 功能强大,打包出来的文件体积也较大。因此 Webpack 更适用于应用的开发。而 Rollup 相对于 Webpack 更加轻量,它只处理 js 文件而不处理其他静态资源文件,打包出来的文件体积也更小,因此 Rollup 更适用于像类库这种只有 js 代码的项目构建。所以大部分类库例如 VueReactAngular 等都采用 Rollup 来打包。

打包vue的命令在package.jsonscript下:

{
  "build": "node scripts/build.js",
  "build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
  "build:weex": "npm run build -- weex",
}
  • build 构建 web 平台相关
  • build:ssr 构建服务端渲染相关
  • build:weex 构建的是 weex 平台相关。

接下来学习build.js文件:

// scripts/build.js
// 引入所需模块
const fs = require('fs')
const path = require('path')
const zlib = require('zlib')
const rollup = require('rollup')
const terser = require('terser')

// 检查是否存在dist目录,不存在则创建dist目录
if (!fs.existsSync('dist')) {
  fs.mkdirSync('dist')
}

[1]
let builds = require('./config').getAllBuilds()

[2]
// filter builds via command line arg
if (process.argv[2]) {
  const filters = process.argv[2].split(',')
  builds = builds.filter(b => {
    return filters.some(f => b.output.file.indexOf(f) > -1 || b._name.indexOf(f) > -1)
  })
} else {
  // filter out weex builds by default
  builds = builds.filter(b => {
    return b.output.file.indexOf('weex') === -1
  })
}

build(builds)

// build函数声明
function build (builds) {
  
}
// scripts/config.js
if (process.env.TARGET) {
  module.exports = genConfig(process.env.TARGET)
} else {
  exports.getBuild = genConfig
  exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
}

[1] 这里 getAllBuilds 函数的处理是取出 builds 对象的所有属性组成的数组在 genConfig 函数处理后返回。即把builds里面的配置对象转换为一个Rollup对应需要的配置项并返。
[2] 通过判断是否有额外的命令参数判断是那条命令,并对builds数组做对应的过滤处理,把不需要Rollup配置项过滤掉。

最后build 函数其实就是让 builds 数组每一项都执行 buildEntry 这个函数,这里 buildEntry 函数调用了 rollup.rollup 进行编译,最终得到一个结果 output,然后判断这个 output 是否是生产版本来决定是否压缩,然后调用 write 函数。write 函数的作用就是调用 fs.writeFile 生成对应的 js 文件放在 dist 目录下。

总结

学习了flow,vue源码的编写依靠flow来进行类型断言,确保了编译的严谨性;因为Rollup比webpack轻量,专门打包js,所以vue、react等框架都使用了Rollup;在vue中,通过运行build.js文件,将各个函数处理成rollup对应需要的配置项,且根据不同环境判断是否要压缩。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值