babel是什么??
在学习es6之后,代码开始基于模块化开发;开始使用import和export进行模块的导入导出,但经过模块的导入导出,出现了问题:
- es6 ie浏览器不支持
- import 谷歌浏览器不支持
当使用import
时,
浏览器会报错:Uncaught SyntaxError: Cannot use import statement outside a module
无法在模块外部引入import.
想让浏览器支持es6,则就需要想办法让es6代码编译成浏览器支持的。想让es6代码编译为浏览器支持的,满足兼容性,就需要使用工具-----babel
Babel
官网:babeljs.io/
在线编译:babeljs.io/repl
基于node.js环境下使用。
babel是Javascript的编译器,用来将es6代码,转换成es6之前的代码,让浏览器识别。
举个栗子:
这是es6代码:
let name = 'Alex';
const age = 18;
const add = (x, y) => x + y;
new Promise((resolve, reject) => {
resolve('成功');
}).then(value => {
console.log(value);
});
Array.from([1, 2]);
class Person {
constructor(name, age) {
Object.assign(this, { name, age });
}
}
new Person('Alex', 18);
import './index.js';
使用Babel编译后的js代码:
('use strict');
require('./index.js');
function _instanceof(left, right) {
if (
right != null &&
typeof Symbol !== 'undefined' &&
right[Symbol.hasInstance]
) {
return !!right[Symbol.hasInstance](left);
} else {
return left instanceof right;
}
}
function _classCallCheck(instance, Constructor) {
if (!_instanceof(instance, Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}
var name = 'Alex';
var age = 18;
var add = function add(x, y) {
return x + y;
};
new Promise(function (resolve, reject) {
resolve('成功');
}).then(function (value) {
console.log(value);
});
Array.from([1, 2]);
var Person = function Person(name, age) {
_classCallCheck(this, Person);
Object.assign(this, {
name: name,
age: age
});
};
new Person('Alex', 18);
Babel 本身可以编译 ES6 的大部分语法,比如 let、const、箭头函数、类
但是对于 ES6 新增的 API,比如 Set、Map、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign/Array.from)都不能直接编译,需要借助其它的模块
Babel 一般需要配合 Webpack 来编译模块语法
使用babel的准备工作
使用babel是在node的环境下,进行的
1. 什么是 Node.js 和 npm
Node.js 是个平台或者工具,对应浏览器
后端的 JavaScript = ECMAScript + IO + File + ...等服务器端的操作
npm:node 包管理工具
npm install 安装....
2. 初始化项目
在该项目的目录下,右键单击打开终端
npm init
在目录中产生node_modules
文件夹和package.json
文件
3. 安装babel解析代码需要的包
npm install --save-dev @babel/core @babel/cli
安装包
npm install --save-dev @babel/core@7.11.0 @babel/cli@7.10.5
安装指定版本的包
4. 运行
npx babel --version
查看版本号
npx
局部的命令工具: npx 命令 xxx
,全局省略npx
执行编译的命令
在 package.json 文件中添加执行 babel 的命令
babel src -d dist
babel src --out-dir dist
src 是被编译的文件名
dist 编译后输出的文件名
-d 参数 作用配置输出文件名
--out-dir 是 -d全称
运行:
npm run build
babel 的配置文件
.babelrc
在文件中创建
npm install @babel/preset-env@7.11.0 --save-dev
创建配置文件 .babelrc,并配置
{
"presets": ["@babel/preset-env"]
}
在这个文件中编写 使用插件
@babel/preset-env 作用,完成语法的编译转化
将编译后的代码,加载到html中测试,在html文件中引入编译后的js文件
总结:将来遇到是 js 语法编译问题;就找 babel
用babel中哪一个工具解决什么问题
babel中的工具详解
babel本身不具有任何转换功能, 如果没有plugin(插件),那么经过babel的代码和输入的是相同的
1. Babel的两种插件
语法插件:在解析的过程中,能使babel能够解析更多的语法
转译插件: 在转换的过程中将代码输出。比如将箭头函数转译成正常的函数
其中preset就是babel常用的转译插件
@babel/cli
终端cli工具。
@babel/preset-env
preset是一套规范, 里面包含了几十个转译插件。这是一组插件的集合
@babel/core
babel编译器。被拆分三个模块:@babel/parser、@babel/traverse、@babel/generator
@babel/plugin
babel插件机制、方便扩展、集成。
其他工具
babel-loader:使用Babel转换JavaScript依赖关系的Webpack加载器, 简单来讲就是webpack和babel中间层,允许webpack在遇到js文件时用bable来解析
@babel相当于一种官方标记,和以前大家随便起名形成区别
@babel/preset-env:即babel-preset-env,根据您要支持的浏览器,决定使用哪些transformations / plugins 和 polyfills,例如为旧浏览器提供现代浏览器的新特性。
@babel/preset-react:即 babel-preset-react,针对所有React插件的Babel预设,例如将JSX转换为函数.
babel-polyfill :Babel默认只转换新的JavaScript语法,而不转换新的API。例如,Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转译。如果想使用这些新的对象和方法,必须使用 babel-polyfill,为当前环境提供一个垫片。
babel-runtime 为了解决:Babel转译后的代码要实现源代码同样的功能需要借助一些帮助函数,而这些帮助函数可能会重复出现在一些模块里,导致编译后的代码体积变大。所以提供了:单独的包babel-runtime供编译模块复用工具函数。
在没有使用babel-runtime之前,库和工具包一般不会直接引入 polyfill。否则像Promise这样的全局对象会污染全局命名空间,这就要求库的使用者自己提供 polyfill。这些 polyfill一般在库和工具的使用说明中会提到,比如很多库都会有要求提供 es5的polyfill。
在使用babel-runtime后,库和工具只要在 package.json中增加依赖babel-runtime,交给babel-runtime去引入 polyfill 就行了
babel 一些插以及用法
使用前请去官网查看
babel-plugin-dynamic-import-node //支持import('comXXX').then()写法
babel-plugin-dynamic-import-webpack //支持import('comXXX').then()写法
babel-plugin-import //支持对antd, antd-mobile, lodash, material-ui等库进行按需加载
babel-plugin-syntax-dynamic-import //支持import('comXXX').then()写法
babel-plugin-transform-class-properties //支持类内直接写属性和静态属性
babel-plugin-transform-decorators-legacy //支持装饰器
babel-plugin-transform-runtime //转换为ES5需要辅助函数,将所有的辅助函数集中到一个模块中,避免所有js文件中有重复的辅助函数生命
babel presets 和 plugins的区别
Babel插件一般尽可能拆成小的力度,开发者可以按需引进。比如对ES6转ES5的功能,Babel官方拆成了20+个插件。
这样的好处显而易见,既提高了性能,也提高了扩展性。比如开发者想要体验ES6的箭头函数特性,那他只需要引入transform-es2015-arrow-functions插件就可以,而不是加载ES6全家桶。
但很多时候,逐个插件引入的效率比较低下。比如在项目开发中,开发者想要将所有ES6的代码转成ES5,插件逐个引入的方式令人抓狂,不单费力,而且容易出错。
这个时候,可以采用Babel Preset。
可以简单的把Babel Preset视为Babel Plugin的集合。比如babel-preset-es2015就包含了所有跟ES6转换有关的插件。