babel 在前端工程化开发中施展着至关重要的作用,它能将较高级的语法转成浏览器可辨认的代码,无论中 es6 中 const 、promise 还是 React、TypeScript。

以下babel在线工具中左侧输出代码,右侧为编译后的后果,设置须要浏览器兼容的版本后,能够看到 "const" 编译成 "var","箭头函数" 编译成 "一般函数"。

命令行应用

babel 和之前说到的 postcss 一样,能够通过命令行运行,解析文件夹或者文件。装置命令行工具所须要的依赖,npm install @babel/cli @babel/core -D

通过 npx 执行 .bin 目录下的指令,--out-file 示意输入文件地址,执行编译语句 npx babel src --out-file dist/main.js

可咱们发现,指标文件和源文件代码是一样的,const 和 箭头函数都没有被编译。这是因为,咱们没有设置编译代码所须要的插件。

下面代码中有标识符和箭头函数,须要【装置】并应用这些插件

  • 转换箭头函数:@babel/plugin-transform-arrow-functions
  • 转换const:@babel/plugin-transform-block-scoping

插件须要通过 --plugins 增加在命令前面

npx babel src --out-file dist/function.js --plugins=@babel/plugin-transform-arrow-functionsnpx babel src --out-file dist/const.js --plugins=@babel/plugin-transform-block-scopingnpx babel src --out-file dist/plugins.js --plugins=@babel/plugin-transform-arrow-functions, @babel/plugin-transform-block-scoping

指定插件之后,babel 就会依据插件的性能再进行编译

但插件只能实现繁多性能,咱们代码里个别也不只有 const 、箭头函数这种语法,当须要解决的代码品种变多,可能就要列举出十分多的插件来执行,所以 babel 提供了一种插件的汇合,叫做"预设","预设"会依据咱们所配置的须要兼容解决的逻辑来进行编译。

装置 @babel/preset-env 依赖后,在命令行应用 --presets 来代替 --plugins。npx babel src --out-file dist/presets.js --presets=@babel/preset-env

babel-loader

除了在命令行中间接通过 babel 编译文件,更多状况下会在我的项目中对批量文件进行解决,这时候就须要用到 babel-loader 来进行解决啦。

装置依赖 npm install babel-loader @babel/core @babel/core是babel的外围

在webpack.config.js文件中配置对于js的解决规定,如果对配置不分明能够参考 webpack初体验、loader配置形式,这里和在命令行中执行一样,须要配置"插件"或者"预设"。

const path = require("path");module.exports = {  entry: "./src/index.js",  output: {    filename: "./bundle.js",    path: path.resolve(__dirname, "./dist"),  },  mode: "development",  devtool: "source-map",  module: {    rules: [      {        test: /\.js/,        exclude: /node_modules/,        use: [          {            loader: "babel-loader",            options: {              // "插件"是这样配置,这里间接应用"预设"              // plugins: [              //   "@babel/plugin-transform-arrow-functions",              //   "@babel/plugin-transform-block-scoping",              // ],              presets: ["@babel/preset-env"],            },          },        ],      },    ],  },};

这样 babel 就会把代码编译成咱们所须要的兼容要求

这里咱们没有设置到底须要对什么样的浏览器进行兼容,应用的就是browserslist默认配置,browserslist作用及具体介绍

有两种形式能够设置babel兼容性解决的规定

  • browserslist:设置的兼容规定对css和js都通用,可配置在 .browserslist 或 package.json 文件中
  • targets:webpack.config.js 中配置在 loader 的options里

以上两种形式都能够配置,但更倡议应用 browserslist,因为 css 和 js 须要兼容的浏览器版本一般来说是统一的,应用 browserslist 只须要配置一套规定即可。

比方咱们设置 兼容谷歌浏览器版本99

// package.json"browserslist": [    "chrome 99"]// 配置在 webpack.config.js 中use: [  {    loader: "babel-loader",    options: {      presets: [        [          "@babel/preset-env",          {            targets: ["chrome 99"],          },        ],      ],    },  },],

因为 chrome 99 是最新的浏览器版本,对于高级的js语法都可能反对,所以不须要将es6编译成es5的语法。

babel 解决文件不止在 js 中须要,如果是 react 我的项目的话,还须要反对 jsx 文件、可能还存在 ts 文件,所以能够将 babel 配置信息放到一个独自的文件中,达到共享的目标。

// webpack.config.js rules: [    {      test: /\.js/,      exclude: /node_modules/,      use: [        {          loader: "babel-loader",        },      ],    },],// babel.config.jsmodule.exports = {  presets: ["@babel/preset-env"],};

polyfill

以上 babel 能够对于一些 js 语法进行解决,但有些新个性比方 promise 在默认状况下不会被解决,这样不能被低版本浏览器所辨认。

那么咱们须要借助"polyfill"来打补丁,对某些特定的语法做解决,这样编译后的代码中就能蕴含这些新个性。

  • babel 7.4 以前,通过 @babel/polyfill
  • babel 7.4 当前,通过 core-js regenerator-runtime

这里应用的 babel 版本是7.17,所以应用第二种形式,装置依赖 npm install core-js regenerator-runtime @babel/runtime-corejs3,在 babel.config.js 中给 preset 配置 polyfill 相干的属性

  • useBuiltIns:规定以什么形式来应用 polyfill

    • false:不应用 polyfill,不必配置 corejs
    • usage:自动检测源代码所须要应用的 polyfill,需配置corejs
    • entry:导入所有 polyfill,文件体积很大,需配置corejs,以及在入口文件中引入 core-js 与 regenerator-runtime
  • corejs:所应用的 corejs 版本
// babel.config.jsmodule.exports = {  presets: [    [      "@babel/preset-env",      {        useBuiltIns: "entry",        corejs: 3,      },    ],  ],};// 入口文件import "core-js/stable";import "regenerator-runtime/runtime";

应用所有的 polyfill ,编译后的代码行数达到了一万七,外面包含很多新个性的实现

对React的反对

react 应用的是 jsx 语法,babel 能够间接对其解决,与 js 文件的解决形式一样,能够抉择应用"插件"或者插件的汇合"预设"。

插件

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

预设

  • @babel/preset-react
// babel.config.jsmodule.exports = {  presets: [    [      "@babel/preset-env",      {        useBuiltIns: "entry",        corejs: 3,      },    ],    ["@babel/preset-react"],  ],};

react 代码被解决且编译胜利,能够在浏览器上看到渲染的页面成果

解决TypeScript文件

在我的项目中解决 ts 文件有两种形式

  • ts-loader:将ts文件编译成js文件,有类型检测,但没有polyfill
  • babel-loader:有polyfill,没有类型检测,代码谬误不会提醒

首先来看 ts-loader 解决的状况,装置 ts-loader,ts-loader 依赖于 typescript 这个工具,npm install ts-loader typscript -D

在 webpack.config.js 配置 ts-loader 解决 ts 文件

module: {  rules: [    {      test: /\.ts$/,      exclude: /node_modules/,      use: [        {          loader: "ts-loader",        },      ],    },  ],},

能够看到,ts 代码曾经被齐全编译成了 js 代码,然而 Promise 是没有被解决的

换成 babel-loader 来解决,和 react 、js 一样,能够抉择"插件"或者插件的汇合"预设"。

  • 插件 @babel/plugin-transform-typescript
  • 预设 @babel/preset-typescript

将webpack.config.js 中的 ts-loader 替换成 babel-loader,以及在 babel.config.js 中进行配置。

// babel.config.jsmodule.exports = {  presets: [    [      "@babel/preset-env",      {        useBuiltIns: "usage",        corejs: 3,      },    ],    ["@babel/preset-typescript"],  ],};

这种状况下,编译后文件就减少了 polyfill 的解决,这里 useBuiltIns 应用的是 usage,比 entry 这种模式下代码量要少一些。

从 polyfill 的角度来说,babel-loader 解决 ts 文件会更好,毕竟咱们写的代码可能会有新个性和兼容性要求,但 babel-loader 存在的问题是无奈进行谬误类型检测,也就是检测不到代码出错,依然会编译通过。

但咱们是心愿可能在开发阶段尽早的发现错误,这样就能防止测试阶段或者公布线上存在问题,在这里能够配合编译的命令来解决这个问题。

tsc 就是 typescript 工具的命令行语法,执行 npm run build通过 tsc 来检测代码是否正确,正确时才应用 webpack 编译,或者执行 npm run type-check-watch实时检测ts代码是否正确

// package.json"scripts": {    "build": "npm run type-check && webpack",    "type-check": "npx tsc --noEmit",    "type-check-watch": "npx tsc --noEmit --watch"},

当代码中存在谬误语法时,会间接报错。

这样就能够对ts文件达到类型谬误的检测以及polyfill的成果了。

以上对于 babel-loader 解决 js、react、ts 文件,以及对于新个性的 polyfill,设置浏览器兼容版本,babel 配置文件 都十分的重要, 更多无关webpack的内容能够参考我其它的博文,继续更新中~