Vuex 4源码学习笔记 - 通过build我们能学习到什么(八)
在上一篇笔记中:Vuex 4源码学习笔记 - 通过单元测试来看工具函数(七)
我们通过单元测试学习了Vuex所用到的工具函数。
今天我们通过Vuex的npm run build
,看看能学习到什么
首先我们通过package.json中的scripts可以看到,实际是使用node运行了scripts/build.js
文件
"scripts": {//..."build": "node scripts/build.js",//...
}
打开scripts/build.js
文件
// fs-extra 是原生fs的替代品。 fs中的所有方法都附加到fs-extra。如果回调未通过,所有fs方法都会返回Promise。
const fs = require('fs-extra')
// chalk 用来在终端内输出带有样式的字符串
const chalk = require('chalk')
// execa 用来在Node.js中运行各种命令
const execa = require('execa')
// Gzip压缩文件
const { gzipSync } = require('zlib')
// Brotli压缩文件算法
const { compress } = require('brotli')const files = ['dist/vuex.esm-browser.js','dist/vuex.esm-browser.prod.js','dist/vuex.esm-bundler.js','dist/vuex.global.js','dist/vuex.global.prod.js','dist/vuex.cjs.js'
]async function run() {await Promise.all([build(), copy()])checkAllSizes()
}async function build() {await execa('rollup', ['-c', 'rollup.config.js'], { stdio: 'inherit' })
}async function copy() {await fs.copy('src/index.mjs', 'dist/vuex.mjs')}function checkAllSizes() {console.log()files.map((f) => checkSize(f))console.log()
}function checkSize(file) {const f = fs.readFileSync(file)const minSize = (f.length / 1024).toFixed(2) + 'kb'const gzipped = gzipSync(f)const gzippedSize = (gzipped.length / 1024).toFixed(2) + 'kb'const compressed = compress(f)const compressedSize = (compressed.length / 1024).toFixed(2) + 'kb'console.log(`${chalk.gray(chalk.bold(file))} size:${minSize} / gzip:${gzippedSize} / brotli:${compressedSize}`)
}run()
这个文件主要依赖的NPM包有:
fs-extra
:fs-extra 是原生fs的替代品。 fs中的所有方法都附加到fs-extra。如果回调未通过,所有fs方法都会返回Promise。chalk
:用来在终端内输出带有样式的字符串execa
:用来在Node.js中运行各种命令zlib
:Gzip压缩文件brotli
:Brotli压缩文件算法
这个文件主要做了下面三件事情:
build()
函数用来使用rollup
来进行打包copy()
函数用来将src/index.mjs
文件拷贝到dist/vuex.mjs
checkAllSizes()
函数用来检查每个打包后的文件的大小
接下来就是重要的使用rollup进行将源代码进行打包,我们来查看rollup配置文件rollup.config.js
import buble from '@rollup/plugin-buble'
import replace from '@rollup/plugin-replace'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import pkg from './package.json'const banner = `/*!* vuex v${pkg.version}* (c) ${new Date().getFullYear()} Evan You* @license MIT*/`const configs = [// 浏览器引入ES Module的开发版本{ input: 'src/index.js', file: 'dist/vuex.esm-browser.js', format: 'es', browser: true, env: 'development' },// 浏览器引入ES Module的生产版本{ input: 'src/index.js', file: 'dist/vuex.esm-browser.prod.js', format: 'es', browser: true, env: 'production' },// ES模块方式引入 import Vuex from 'vuex'{ input: 'src/index.js', file: 'dist/vuex.esm-bundler.js', format: 'es', env: 'development' },// 浏览器CDN方式引入的开发版本{ input: 'src/index.cjs.js', file: 'dist/vuex.global.js', format: 'iife', env: 'development' },// 浏览器CDN方式引入的生产版本{ input: 'src/index.cjs.js', file: 'dist/vuex.global.prod.js', format: 'iife', minify: true, env: 'production' },// commonjs模块方式引入 require('vuex'){ input: 'src/index.cjs.js', file: 'dist/vuex.cjs.js', format: 'cjs', env: 'development' }
]function createEntries () {return configs.map((c) => createEntry(c))
}function createEntry (config) {const isGlobalBuild = config.format === 'iife'const isBundlerBuild = config.format !== 'iife' && !config.browserconst isBundlerESMBuild = config.format === 'es' && !config.browserconst c = {external: ['vue'], // 要排除的模块ID,排除vue依赖input: config.input, // 入口文件地址plugins: [], // 所有插件output: {banner, // 在打包后文件顶部插入的代码file: config.file, // 输出文件地址format: config.format, // 输出类型(amd、cjs、es、iife、umd、system)globals: { // 告诉Rollup,Vue 是外部依赖vue: 'Vue'}/*var MyBundle = (function (Vue) {// code goes here}(Vue));*/},// 拦截警告消息的函数onwarn: (msg, warn) => {if (!/Circular/.test(msg)) {warn(msg)}}}if (isGlobalBuild) {// 对于导出的iife/umd包是必需的,它代表包的全局变量名称。c.output.name = c.output.name || 'Vuex'}if (!isGlobalBuild) {// 排除@vue/devtools-api依赖c.external.push('@vue/devtools-api')}// Rollup插件,在打包时替换文件中的目标字符串。c.plugins.push(replace({preventAssignment: true,__VERSION__: pkg.version,__DEV__: isBundlerBuild? `(process.env.NODE_ENV !== 'production')`: config.env !== 'production',__VUE_PROD_DEVTOOLS__: isBundlerESMBuild? '__VUE_PROD_DEVTOOLS__': 'false'}))// 一个使用buble编译器转换ES2015+代码的Rollup插件。if (config.transpile !== false) {c.plugins.push(buble())}// 一个使用Node解析算法定位模块的Rollup插件,用于在node_modules中使用第三方模块c.plugins.push(resolve())// 一个Rollup插件,用于将CommonJS模块转换为ES6c.plugins.push(commonjs())// Rollup插件,用于缩小生成的es包。if (config.minify) {c.plugins.push(terser({ module: config.format === 'es' }))}return c
}export default createEntries()
使用Rollup打包主要用到了下面的一些插件功能:
@rollup/plugin-buble
:使用buble编译器转换ES2015+代码的Rollup插件。@rollup/plugin-replace
:在打包时替换文件中的目标字符串。@rollup/plugin-node-resolve
:使用Node解析算法定位模块的Rollup插件,用于在node_modules中使用第三方模块@rollup/plugin-commonjs
:用于将CommonJS模块转换为ES6rollup-plugin-terser
:用于缩小生成的es包。
打包的目标产物有以下六个:
dist/vuex.esm-browser.js
:用于通过原生 ES 模块导入使用 (在浏览器中通过<script type="module">
来使用)。开发版本。dist/vuex.esm-browser.prod.js
:同上,作为生产版本。dist/vuex.esm-bundler.js
:ES模块方式引入import Vuex from 'vuex'
,用于webpack
,rollup
和parcel
等构建工具,不提供压缩版本 (打包后与其余代码一起压缩)。dist/vuex.global.js
:浏览器CDN方式引入的开发版本dist/vuex.global.prod.js
:浏览器CDN方式引入的生产版本dist/vuex.cjs.js
:commonjs模块方式引入const Vuex = require('vuex')
,通过 require() 在 Node.js 服务器端渲染使用。
每个产物对应着不同的使用平台。
一起学习更多前端知识,微信搜索【小帅的编程笔记】,每天更新
Vuex 4源码学习笔记 - 通过build我们能学习到什么(八)相关推荐
- libreCAD源码阅读笔记2
libreCAD源码阅读笔记2 1. 前言 继续学习QC_MDIWindow类.QG_ActionHandler类相关代码 2. QC_MDIWindow类 QC_MDIWindow类继承QT QMd ...
- Vuex 4源码学习笔记 - 通过Vuex源码学习E2E测试(十一)
在上一篇笔记中:Vuex 4源码学习笔记 - 做好changelog更新日志很重要(十) 我们学到了通过conventional-changelog来生成项目的Changelog更新日志,通过更新日志 ...
- Vuex 4源码学习笔记 - 通过dispatch一步步来掌握Vuex整个数据流(五)
在上一篇笔记中:Vuex 4源码学习笔记 - Store 构造函数都干了什么(四) 我们通过查看Store 构造函数的源代码可以看到主要做了三件事情: 初始化一些内部变量以外 执行installMod ...
- React深入学习与源码解析笔记
***当前阶段的笔记 *** 「面向实习生阶段」https://www.aliyundrive.com/s/VTME123M4T9 提取码: 8s6v 点击链接保存,或者复制本段内容,打开「阿里云盘」 ...
- Android Dialer,Mms,Contacts源码修改笔记,移动端混合开发经验
②在AndroidManifest.xml中修改相应Activity的theme <activity android:name=".HomeActivity" android ...
- libreCAD源码阅读笔记1
libreCAD源码阅读笔记1 一 前言: 正如官网(https://www.librecad.org)所说,libreCAD是一个开源的CAD制图软件,可以运行在Windows.Apple.Linu ...
- libreCAD源码阅读笔记4
libreCAD源码阅读笔记4 前言 总的来说,程序主窗口QC_ApplicationWindow使用QMdiArea作为多文档主界面,每个文档QC_MDIWindow使用RS_Document作为数 ...
- 源码解析:Spring源码解析笔记(五)接口设计总览
本文由colodoo(纸伞)整理 QQ 425343603 Java学习交流群(717726984) Spring解析笔记 启动过程部分已经完成,对启动过程源码有兴趣的朋友可以作为参考文章. 源码解析 ...
- HashMap源码阅读笔记
HashMap是Java编程中常用的集合框架之一. 利用idea得到的类的继承关系图可以发现,HashMap继承了抽象类AbstractMap,并实现了Map接口(对于Serializable和Clo ...
- dgl源码阅读笔记(3)——DeepWalk
dgl源码阅读笔记(3)--DeepWalk 图神经网络开源库dgl阅读笔记 文章目录 dgl源码阅读笔记(3)--DeepWalk 图神经网络开源库dgl阅读笔记 @[TOC](文章目录) 前言 一 ...
最新文章
- 基于Python的验证码识别技术
- The Third Revolution in Sequencing Technology 测序技术的第三次革命
- 小白的python之路11/3总结
- [BZOJ1724][Usaco2006 Nov]Fence Repair 切割木板
- 【MATLAB】二维绘图 ( 绘制二维图像 | 设置图像样式 )
- secureCRT 实现windows和linux文件互传
- Gmail技巧之无限别名
- android应用开发全程实录-实现甩动拨打和挂断电话
- MySQL学习笔记之五:存储引擎和查询缓存
- JDBC(Java语言连接数据库)
- 利用数据库来填充UltraWebTree
- 一个简单的crontab
- 安装grunt-browser-sync时报错:“未能加载Visual C++ 组件 “VCBuild.exe”
- Kotlin入门(13)类成员的众生相
- 详解python 字符串
- 数据结构c语言版堆排序,【数据结构】堆排序(C++实现)
- 【图像配准】基于matlab GUI互相关图像配准【含Matlab源码 853期】
- ArcMap进行标记符号制作
- 2012“第四届云计算中国峰会”倒计时
- 5大可以赚钱的视频平台,及收益渠道!