目录
1.Babel
1.1 babel
- 为什么需要babel?
- babel对于前端开发是非常重要的一部分;
- 使用ES6+的语法,想要使用TypeScript,开发React项目,都离不开Babel;
- 学习babel对于理解代码从编写到线上的转变过程至关重要;
- react 中的 jsx代码 通过babel转换成JavaScript代码;
- Babel的定义:
- Babel是一个工具链,主要用于旧浏览器或者环境中将ECMAScript 2015+(ES6)代码转换为向后兼容版本的JavaScript;
- 包括:语法转换、源代码转换等;
- Webpack 也是一个工具链;
- 并不是所有的JS引擎都可以解析ES6语法;
1.2 Babel命令行使用
- babel本身可以作为一个独立的工具(和postcss一样),不和webpack等构建工具配置来单独使用;
- 在命令行使用babel,需要安装的库:
- @babel/core:babel的核心代码,必须安装;
- @babel/cli:可以让我们在命令行使用babel;
@babel 这种方式是通过 monorepo的方式进行管理的
- 命令行使用babel:
安装: yarn add @babel/core @babel/cli -D // 局部安装
使用: npx babel demo.js --out-dir dist // npx 是局部使用 寻找node_module bin下的 babel 然后使用
–out-dir 转换之后的输出文件目录 是 dist目录
–out-file 输出一个文件
1.3 插件的使用
- 如果我们需要转换箭头函数,那么我们必须使用箭头函数转换相关的插件;
yarn add @babel/plugin-transform-arrow-functions -D // 箭头转换的插件
npx babel demo.js --out-dir dist --plugins=@babel/plugin-transform-arrow-functions // 使用 插件执行
- const 转换成为 var:
yarn add @babel/plugin-transform-block-scoping -D
npx babel demo.js --out-dir dist --plugins=@babel/plugin-transform-block-scoping
1.4 Babel的预设preset
- 如果一个功能需要一个插件,比较麻烦,出现预设preset;
- 安装@babel/preset-env预设:
yarn add @babel/preset-env -D
npx babel demo.js --out-file test.js --presets=@babel/preset-env,···其他预设
- “use strict”; 使用严格模式
1.5 Babel的底层原理
- babel是如何将一段代码转成另一段代码?
- 从一种源代码(原生语言)转换成另一种源代码(目标语言),这是什么工作?
- 编译器,我们可以把babel看成一个编译器;
- Babel编译器的作用就是将我们的源代码,转换成浏览器可以直接识别的另外一段源代码;
- Babel编译器的工作流程:
- 解析阶段(Parsing)
- 转换阶段(Transformation)
- 生成阶段(Code Generation)
1.6 Babel编译器执行原理
-
Babel的执行阶段
-
源代码 通过 词法分析器 进行分割,放到 tokens数组中, 通过语法分析器将语法进行分析,生成一个AST树(抽象语法树)(树结构),遍历抽象语法树,访问到 const 等关键字之后,通过使用应用插件转换为var,转化完之后,生成新的AST树,通过这个抽象语法树生成目标源代码。
-
lisp 是各种括号;
1.7 babel-loader
- 安装babel-loader
yarn add babel-loader -D
- 配置babel-loader
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
plugins: [
// 或者可以添加预设
presets: [
"@babel/preset-env"
],
// 另外一种写法
presets: [ " @babel/preset-env " , { // 写参数 } ]
--------------------------------------------------------------------------
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-block-scoping"
]
}
}
}
- 我们也可以将babel的配置文件抽取到一个独立的文件中,babel提供两种配置文件的编写:
- babel.config.json(或者.js .cjs .mjs)文件;
- .babelrc.json (或者 .babelrc .js .cjs .mjs)文件;
- rc -> runtime compiler 运行时编译
- 两种文件的区别
- 第二种是早期使用较多的配置方式,但是对于配置Monorepos项目是比较麻烦的;
- 第一种可以直接作用域Monorepos项目的子包,更加推荐(从babel 7开始);
1.8 Vue源码的打包(webpack + vue)
- 安装vue
yarn add vue@next // 安装的是 vue 3.x
- npm下载vue的时候,打包的时候没有问题,但是运行到浏览器的时候会出现警告并且不会显示;
- 在createApp中的template,Vue源代码对其进行解析;
- 两种编译(举例)版本解析 : runtime + compiler 、runtime-only (实际上Vue有很多的编译版本)
- 一部分源代码(compiler) 对 template 进行编译;
- 默认使用的是 runtime-only,所以不会对template进行编辑;
- 常见版本解析:
- vue(.runtime).global(.prod).js:
- 通过浏览器中的 script src直接使用;
- 通过CDN引入和下载的Vue版本就是这个版本;
- 会暴露一个全局的Vue来使用;
- vue(.runtime).esm-browser(.prod).js:
- 用户通过原生ES模块导入使用(浏览器中通过给script 添加 type="module"来使用);
- vue(.runtime).esm-bundler.js:
- 用于webpack,rollup和parcel等构建工具;
- 构建工具中默认是vue.runtime.esm-bundler.js;
- 如果我么需要解析模板template,那么需要手动指定vue.esm-bundler.js;
- vue.cjs(.prod).js:
- 服务器端渲染使用;
- 通过require()在Node.js中使用;
- import { createApp } from ‘vue/dist/vue.esm-bundler’; 指定版本之后,在进行打包 就可以渲染到浏览器上;
1.9 运行时+编译器 vs 仅运行时
- 在Vue开发过程中我们有三种方式来编写DOM元素:
- 方式一:template模板的方式;
- 方式二:render函数的方式,使用h函数来编写渲染的内容;
- 方式三:通过**.vue文件**中的template来编写模板;
- 如何处理:
- 方式二中的函数可以直接返回一个虚拟节点,也就是Vnode节点;
- 方式一和方式三的template可以通过在vue-loader对其进行编译和处理;
- 方式一的template我们必须要通过源码中的一部分代码来进行编译;
- Vue在让我们选择版本的时候分为运行时 + 编译器 vs 仅运行时
- 运行时 + 编译器 包含了对template模板的编译代码,更加完整,但是也更大一些;
- 仅运行时没有包含对template版本的编译代码,相对更小一些;
1.10 VSCode对SFC文件(.vue)的支持
- 默认情况下不支持 .vue 文件;
- 使用插件对SFC进行支持:
- Vetur,从Vue2开发就一直在使用的VSCode支持Vue的插件;
- Volar,官方推荐的插件(后续会基于Volar开发官方的VScode插件);
2.Vue
2.1 vue-loader@next
- 处理 Vue 3.x 使用的是vue-loader@next;
2.2 @vue/compiler-sfc
- 这个才是真正进行编译template等的包;
- 还需要一个插件才能正常打包:const { VueLoaderPlugin } = require(“vue-loader/dist/index”);
- style scoped 这是作用域;
- vue-loader相当于是一个函数,在内部使用的是@vue/compiler-sfc;
2.3 全局标识
-
vue_options_api:对vue2做适配
-
tree shaking:把代码从源代码中删除
-
vue_prod_devtools:在生产环境下 是不是要支持devtools
-
消除警告
new DefinePlugin({
BASE_URL: "'./'",
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
}),