7.Babel

89 阅读2分钟

Babel作用

Babel 是一个工具链,主要用于旧浏览器或者缓解中将ECMAScript 2015+代码转换为向后兼容版本的 JavaScript,包括:语法转换、源代码转换、Polyfill 实现目标缓解缺少的功能等。

Babel原理

由 Babel 理解前端编译原理

Babel编译器的作用就是将我们的源代码,转换成浏览器可以直接识别的另外一段源代码。

  • Babel的执行阶段

QQ截图20240405130655.png

Babel命令行使用

babel本身可以作为一个独立的工具(和postcss一样),不和webpack等构建工具配置来单独使用。
安装:npm install @babel/core @babel/cli -D
@babel/core:babel的核心代码,必须安装。
@babel/cli:可以让我们在命令行使用 babel。

  • 以箭头函数为例:
const fun = () => {
    console.log("显示");
}
fun()

安装编译箭头函数的插件:@babel/plugin-transform-arrow-functions
安装:npm install @babel/plugin-transform-arrow-functions -D
使用npx babel src --out-dir dist --plugins=@babel/plugin-transform-arrow-functions
编译后:

const fun = function () {
  console.log("显示");
};
fun();

Babel 的预设 preset

如果要转换的内容过多,一个个设置是比较麻烦的,我们可以使用预设(preset)

  • 安装@babel/preset-env预设 npm install @babel/preset-env -D
  • 执行 npx babel src --out-dir dist --presets=@babel/preset-env

webpack 中配置 babel

babel-loader 作用:可以在 webpack 中使用 babel

安装 npm install babel babel-loader @babel/core

  • 使用单个插件的方式
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
              plugins: [
                // 箭头函数
                "@babel/plugin-transform-arrow-functions",
                // 将 const 转换为 var
                "@babel/plugin-transform-block-scoping"
              ]
           }
        }
      }
    ]
  }
  • 使用 preset-env 预设(多个插件的组合,具体使用哪些插件是根据 .browserlistrc 适配的浏览器需要的语法)
    安装npm install @babel/preset-env
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
              presets: [
                  ["@babel/preset-env"]
              ]
           }
        }
      }
    ]
  }

babel 会按照 browserslist 的配置将源代码编译成 目标浏览器 可以识别的语法。也可以在 targets 中进行配置浏览器的范围。

  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
              presets: [
                  ["@babel/preset-env",{
                      target:"last 2 version"
                  }]
              ]
           }
        }
      }
    ]
  }

如果 browserslist 和 targets 都设置了,targets 属性会覆盖 browserslist,但是在开发中,更推荐通过browserslist 来配置,因为类似于 postcss 工具,也会使用 browserslist,进行统一浏览器的适配。

可以对比一下不同的配置,打包的区别: QQ截图20240405132355.png

Babel的配置文件

可以将babel的配置信息放到一个独立的文件中,babel给我们提供了两种配置文件的编写:

  1. babel.config.json(或者.js,.cjs,.mjs)文件
  2. .babelrc.json(或者.babelrc,.js,.cjs,.mjs)文件

区别: .babelrc.json:早期使用较多的配置方式,但是对于配置Monorepos项目是比较麻烦的,babel.config.json(babel7):可以直接作用于Monorepos项目的子包,更加推荐。

  • webpack.config.js
module: {
    rules: [
              {
                test: /\.m?js$/,
                exclude: /node_modules/,
                use: {
                  loader: "babel-loader"
                }
              }
        ]
}
  • babel.config.js
module.exports = {
    presets: [
        ["@babel/preset-env"]
    ]
}

React的jsx支持

react使用的语法是jsx,jsx是可以直接使用babel来转换的。 对react jsx代码进行处理需要如下的插件

  • @babel/plugin-syntax-jsx
  • @babel/plugin-transform-react-jsx
  • @babel/plugin-transform-react-display-name

开发中并不需要一个个去安装这些插件,可以使用preset来配置。
安装 npm install @babel/preset-react -D
源代码:
index.jsx

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "Hello React"
    }
  }
  render() {
    return (
      <div>
        <h2>{this.state.message}</h2>
      </div>
    )
  }
}
ReactDOM.render(<App/>, document.getElementById("app"));

webpack 配置:

module.exports = {
    entry: "./src/index.jsx",
    module: {
        rules: [
                 {
                    test: /\.jsx?$/,
                    exclude: /node_modules/,
                    use: {
                      loader: "babel-loader"
                    }
              }
        ]
    }
}

babel.config.js

module.exports = {
    presets: [
        ["@babel/preset-react"]
      ]
}

加载 Vue 文件

源代码: src / index.js

import Vue from 'vue';
import App from "./App.vue";

new Vue({
  render: h => h(App)
}).$mount("#app");

src / App.vue

<template>
  <div id="app">
    <h2 class="title">{{message}}</h2>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello Vue"
    }
  }
}
</script>

<style scoped lang="less">
  .title {
    color: red
  }
</style>

安装相关的依赖:

npm install vue-loader -D
npm install vue-template-compiler -D

QQ截图20240405155031.png