前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
  • JavaScript Part 1

    • Ajax总结篇
    • Canvas 绘制八大行星
    • DOM编程之API学习总结篇
    • JavaScript事件机制
    • JavaScript代码片段100个
    • JavaScript作用域分析总结
    • JavaScript原型链回顾
    • JavaScript及jQuery中的各种宽高属性图解
    • JavaScript工程项目的一系列最佳实践
    • JavaScript常用API合集
    • JavaScript数组、字符串、对象常用方法
    • JavaScript数组方法总结篇
    • JavaScript深浅拷贝
    • JavaScript运动框架之速度时间版本
    • JavaScript运行机制Event Loop
    • JavaScript防抖节流原理
    • Javascript中的复制粘贴功能
    • Javascript数组详解
    • OOP之原型与原型链
    • Object.defineProperty详解
    • V8源码浅析JS数组常见方法
    • await 在 forEach 中不生效解决方案
    • iframe+表单跨域提交POST请求
    • javascript笔记总结篇
    • 业务中处理数据结构常用的JS方法
    • 作用域
    • 你真的掌握变量和类型了吗
    • 前后端分离之数据Mock
    • 原型与原型链
    • 原生JS补给(上)
    • 如何写出一个惊艳面试官的深拷贝
    • 带你填一些JS容易出错的坑
    • 彻底弄懂 JavaScript 执行机制
    • 执行上下文 执行栈
    • 正则回顾总结
    • 正则基础知识
    • 正则完整篇
    • 正则表达式
    • 浅析Promise原理
    • 浅谈JavaScript中的异步处理
    • 深拷贝 vs 浅拷贝
    • 聊一聊typeof instanceof 实现原理.
    • 聊一聊闭包
    • 高阶函数map reduce filter
  • JavaScript Part 2

  • CSS

  • HTML

  • Jquery

  • ES6

  • 小程序

  • Vue

  • React

  • 深入React

  • React Native

  • NodeJS

  • Angular

  • TypeScript

  • Webpack

  • 浏览器

  • 移动端

  • 前端工程化

  • Electron

  • HTTP

  • Nginx

  • Linux

  • 数据结构与算法

  • LeetCode算法题

  • 综合

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

Babel篇|博客系列

# 前期准备

学习一个新的知识, 我还是偏向于用案例的的方式来打开讲解它.

所以在正式开始阅读之前, 让我们先来准备一个这样的案例项目:

mkdir babel-basic && cd babel-basic
npm init -y
mkdir src && cd src
touch index.js
@前端进阶之旅: 代码已经复制到剪贴板

一顿操作之后, 我们新建的项目目录为:

/babel-basic
	|- /src
		|- index.js
	|- package.json
@前端进阶之旅: 代码已经复制到剪贴板

现在package.json是最原始的配置, 而index.js暂时没有写内容.

package.json:

{
  "name": "babel-basic",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {}
}

@前端进阶之旅: 代码已经复制到剪贴板

下面我都将围绕这个babel-basic项目来进行讲解, 我希望你也能在本地准备一个这样的项目案例, 以便你更好的理解我接下来要说的内容.

# @babel/core

我们学习Babel, 首先要了解一个叫@babel/core 的东西, 它是Babel的核心模块.

当然要使用它, 我们得先安装:

$ npm i --save-dev @babel/core
@前端进阶之旅: 代码已经复制到剪贴板

安装成功之后就可以在我们的代码中使用了, 你可以采用CommonJS的引用方式:

const babel = require('@babel/core');
babel.transform("code", options);
@前端进阶之旅: 代码已经复制到剪贴板

这里的知识点有很多, 不过你不用急于的掌握它, 只需要知道它是Babel的核心, 让我们接着往下看.

# @babel/cli

再然后就是@babel/cli, 它是一个终端运行工具, 内置的插件,运行你从终端使用babel的工具.

同样, 它也需要先安装:

$ npm i --save-dev @babel/cli @babel/core
@前端进阶之旅: 代码已经复制到剪贴板

让我们安装@babel/cli的同时再来安装一下@babel/core,

现在, 让我先在src/index.js中写上一段简单的代码, 并来看看它的基本用法.

src/index.js:

const fn = () => 1; // 箭头函数, 返回值为1
console.log(fn());
@前端进阶之旅: 代码已经复制到剪贴板

用法一: 命令行的形式(在项目根目录执行语句):

$ ./node_modules/.bin/babel src --out-dir lib
@前端进阶之旅: 代码已经复制到剪贴板

这段语句的意思是: 它使用我们设置的解析方式来解析src目录下的所有JS文件, 并将转换后的每个文件都输出到lib目录下.

但是注意了, 由于我们现在没有设置任何的解析方式, 所以你在执行了这段语句之后, 能看到项目中多了一个lib目录, 而且里面的JS代码和src中的是一样的. 至于我说的解析方式, 就是后面我要介绍的plugins和presets.

另外, 如果你是npm@5.2.0附带的npm包运行器的话, 就可以用npx babel来代替./node_modules/.bin/babel:

$ npx babel src --out-dir lib
@前端进阶之旅: 代码已经复制到剪贴板

用法二: 给package.json中配置一段脚本命令:

{
    "name": "babel-basic",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
+       "build": "babel src -d lib"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
+       "@babel/cli": "^7.8.4",
+       "@babel/core": "^7.8.4"
    }
}
@前端进阶之旅: 代码已经复制到剪贴板

现在运行npm run build效果也是一样的, -d是--out-dir的缩写…

(我们使用上面的 --out-dir 选项。你可以通过使用 --help 运行它来查看 cli 工具接受的其余选项。但对我们来说最重要的是 --plugins 和 --presets。)

$ npx babel --help
@前端进阶之旅: 代码已经复制到剪贴板

# 插件plugins

# 基本概念

知道了Babel的基本用法之后, 让我们来看看具体的代码转换.

现在要介绍的是插件plugins, 它的本质就是一个JS程序, 指示着Babel如何对代码进行转换.

所以你也可以编写自己的插件来应用你想要的任何代码转换.

# 插件案例(箭头函数插件)

但是首先让我们来学习一些基本的插件.

如果你是要将ES6+转成ES5, 可以依赖官方插件, 例如:

@babel/plugin-transform-arrow-functions:

$ cnpm i --save-dev @babel/plugin-transform-arrow-functions
$ npx babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
@前端进阶之旅: 代码已经复制到剪贴板

这个插件的作用是将箭头函数转换为ES5兼容的函数:

还记得我们之前的src/index.js吗:

const fn = () => 1; // 箭头函数, 返回值为1
console.log(fn());
@前端进阶之旅: 代码已经复制到剪贴板

现在编译之后, 你再打开lib/index.js来看看.

它是不是被转换为ES5的代码了呢? 😁

const fn = function () {
  return 1;
}; // 箭头函数, 返回值为1


console.log(fn());
@前端进阶之旅: 代码已经复制到剪贴板

捣鼓了这么久, 终于看到了一点实际的效果, 此时有点小兴奋啊😄

表情包开心

虽然我们已经实现了箭头函数转换的功能, 但是ES6+其它的语法(比求幂运算符**)却并不能转换, 这是因为我们只使用了@babel/plugin-transform-arrow-functions这个功能插件, 没有使用其它的了.

# Presets:

# 基本概念

如果想要转换ES6+的其它代码为ES5, 我们可以使用"preset"来代替预先设定的一组插件, 而不是逐一添加我们想要的所有插件.

这里可以理解为一个preset就是一组插件的集合.

presets和plugins一样, 也可以创建自己的preset, 分享你需要的任何插件组合.

# @babel/preset-env

例如, 我们使用envpreset:

cnpm i --save-dev @babel/preset-env
@前端进阶之旅: 代码已经复制到剪贴板

envpreset这个preset包括支持现代JavaScript(ES6+)的所有插件.

所以也就是说你安装使用了envpreset之后, 就可以看到其它ES6+语法的转换了.

现在让我们来用用ES7中的求幂运算符和函数参数支持尾部逗号这两个功能吧:

src/index.js:

const fn = () => 1; // ES6箭头函数, 返回值为1
let num = 3 ** 2; // ES7求幂运算符
let foo = function(a, b, c, ) { // ES7参数支持尾部逗号
    console.log('a:', a)
    console.log('b:', b)
    console.log('c:', c)
}
foo(1, 3, 4)
console.log(fn());
console.log(num);
@前端进阶之旅: 代码已经复制到剪贴板

然后在命令行里使用这个preset:

npx babel src --out-dir lib --presets=@babel/preset-env
@前端进阶之旅: 代码已经复制到剪贴板

现在打开lib/src看看:

"use strict";

var fn = function fn() {
  return 1;
}; // 箭头函数, 返回值为1


var num = Math.pow(3, 2);

var foo = function foo(a, b, c) {
  console.log('a:', a);
  console.log('b:', b);
  console.log('c:', c);
};

foo(1, 3, 4);
console.log(fn());
console.log(num);
@前端进阶之旅: 代码已经复制到剪贴板

求幂运算符被转换为成Math.pow()

函数参数的最后一个逗号也被去掉了.

截止到现在, 看完了@babel/core、@babel/cli、plugins、presets, 相信你对Babel的功能有一定了解了吧, 但是真正使用起来我们不可能都是靠命令行的形式吧, 没错, 接下来我要将这些功能做成配置项.

# 配置

上面👆介绍的都是一些终端传入CLI的方式, 在实际使用上, 我们更加偏向于配置文件.

例如我们在项目的根目录下创建一个babel.config.js文件:

const presets = [
	[
    "@babel/env",
    {
      targets: {
        edge: "17",
        chrome: "64",
        firefox: "60",
        safari: "11.1"
      }
    }
  ]	
]

module.exports = { presets };
@前端进阶之旅: 代码已经复制到剪贴板

加上这个配置的作用是:

  • 使用了envpreset这个preset
  • envpreset只会为目标浏览器中没有的功能加载转换插件

现在你要使用这个配置就很简单了, 直接用我们前面package.json配置的命令行语句:

{
	"scripts": {
		"build": "babel src -d lib"
	}
}
@前端进阶之旅: 代码已经复制到剪贴板

执行npm run build就可以了.

这个命令行语句看起来并没有修改, 那是因为它默认会去寻找跟根目录下的一个名为babel.config.js的文件(或者babelrc.js也可以, 这个在之后的使用babel的几种方式中会说到), 所以其实就相当于以下这个配置:

{
	"scripts": {
		"build": "babel src -d lib --config-file ./babel.config.js"
	}
}
@前端进阶之旅: 代码已经复制到剪贴板

因此如果你的Babel配置文件是babel.config.js的话, 这两种效果是一样的.

(--config-file指令就类似于webpack中的--config, 用于指定以哪个配置文件构建)

这里我重点要说一下只会为目标浏览器中没有的功能加载转换插件这句话的意思.

例如我这里配置的其中一项是edge: "17", 那就表示它转换之后的代码支持到edge17.

所以你会发现, 如果你用了我上面babel.config.js的配置之后生成的lib文件夹下的代码好像并没有发生什么改变, 也就是它并没有被转换成ES5的代码:

src/index.js:

← Typescript总结篇Webpack4基础配置梳理知识点 →

fe
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
  • JavaScript Part 1

    • Ajax总结篇
    • Canvas 绘制八大行星
    • DOM编程之API学习总结篇
    • JavaScript事件机制
    • JavaScript代码片段100个
    • JavaScript作用域分析总结
    • JavaScript原型链回顾
    • JavaScript及jQuery中的各种宽高属性图解
    • JavaScript工程项目的一系列最佳实践
    • JavaScript常用API合集
    • JavaScript数组、字符串、对象常用方法
    • JavaScript数组方法总结篇
    • JavaScript深浅拷贝
    • JavaScript运动框架之速度时间版本
    • JavaScript运行机制Event Loop
    • JavaScript防抖节流原理
    • Javascript中的复制粘贴功能
    • Javascript数组详解
    • OOP之原型与原型链
    • Object.defineProperty详解
    • V8源码浅析JS数组常见方法
    • await 在 forEach 中不生效解决方案
    • iframe+表单跨域提交POST请求
    • javascript笔记总结篇
    • 业务中处理数据结构常用的JS方法
    • 作用域
    • 你真的掌握变量和类型了吗
    • 前后端分离之数据Mock
    • 原型与原型链
    • 原生JS补给(上)
    • 如何写出一个惊艳面试官的深拷贝
    • 带你填一些JS容易出错的坑
    • 彻底弄懂 JavaScript 执行机制
    • 执行上下文 执行栈
    • 正则回顾总结
    • 正则基础知识
    • 正则完整篇
    • 正则表达式
    • 浅析Promise原理
    • 浅谈JavaScript中的异步处理
    • 深拷贝 vs 浅拷贝
    • 聊一聊typeof instanceof 实现原理.
    • 聊一聊闭包
    • 高阶函数map reduce filter
  • JavaScript Part 2

  • CSS

  • HTML

  • Jquery

  • ES6

  • 小程序

  • Vue

  • React

  • 深入React

  • React Native

  • NodeJS

  • Angular

  • TypeScript

  • Webpack

  • 浏览器

  • 移动端

  • 前端工程化

  • Electron

  • HTTP

  • Nginx

  • Linux

  • 数据结构与算法

  • LeetCode算法题

  • 综合