babel的基本使用

928 阅读6分钟

babel是什么??

在学习es6之后,代码开始基于模块化开发;开始使用import和export进行模块的导入导出,但经过模块的导入导出,出现了问题:

  1. es6 ie浏览器不支持
  2. import 谷歌浏览器不支持

当使用import时,

图片.png

浏览器会报错: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([12]);

    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([12]);
    var Person = function Person(name, age) {
      _classCallCheck(thisPerson);
      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

图片.png

babel 的配置文件

     .babelrc 在文件中创建

     npm install @babel/preset-env@7.11.0 --save-dev

     创建配置文件 .babelrc,并配置

     {

       "presets": ["@babel/preset-env"]

     }

 在这个文件中编写 使用插件

 @babel/preset-env 作用,完成语法的编译转化
 

将编译后的代码,加载到html中测试,在html文件中引入编译后的js文件

图片.png

总结:将来遇到是 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转换有关的插件。