死磕前端之——编译工具链

JavaScript Compiler

什么是 Compiler

babel 的官方文档中说:Babel 是一个工具链,主要用于在当前和较旧的浏览器或环境中将 ECMAScript 2015+代码转换为向后兼容的 JavaScript 版本。

swc (Speedy Web Compiler) 的官方文档中说:当 swc 被用做编译工具的时候,它接受使用现代 JavaScript 特性的 JavaScript / TypeScript 文件,并输出所有主流浏览器支持的有效代码。

tsc (Typescript Compiler):tsc 是 Typescript 的官方编译器,可将 typescript 文件转换/编译为 javascript。

因此,JavaScript Compiler 就是一类工具,他们的职责大致可以划分两类:

  1. 就是将语法特性较新的 JavaScript(如 ES2015+)转换为语法特性版本比较低的 JavaScript(如 ES3、ES5)。
  2. 将非纯 JavaScript(JSX、Typescript、Flow、CoffeeScript、Vue Template 等)转换为 Vanilla JavaScript(纯 JavaScript、香草 JavaScript)。

有哪些 Compiler

  • babel
  • swc
  • tsc

流行度低或已老旧

如何使用 Compiler

Babel 的使用

Babel 的代码仓库是一个 monorepo,由许多的 npm 包构成。首先我们需要用到的两个包为:

  • @babel/core: Babel 的核心模块,负责解析、转换和生成代码
  • @babel/cli: Babel 的命令行工具,可以在终端中直接运行 Babel。

先初始化项目,并且给出一个代码文件。

js 复制代码
// index.js
const fn = () => {
  console.log("I'm a arrow function");
};

下载 babel 的 npm 包,进行编译工作。

bash 复制代码
# 下载npm包
npm install --save-dev @babel/core @babel/cli

# 使用babel的CLI工具进行编译
./node_modules/.bin/babel <source> --out-file <target>
# e.g.
./node_modules/.bin/babel index.js --out-file target.js
js 复制代码
// target.js
const fn = () => {
  console.log("I'm a arrow function");
};

但是,当你执行完成上面的编译命令后,你会发现,你的 JavaScript 中最新的语法特性(箭头函数)还是没有被降级。target.js 中的 JavaScript 代码,根本没有任何变化。

这是因为,默认情况下,Babel 不做任何事情,你需要给 Babel 提供「插件」或「预设」。Babel 是通过插件和预设来进行实际的编译工作的。

例如:我们需要将箭头函数这个 ES2015 的语法特性降级,那么我们就需要下载 @babel/plugin-transform-arrow-functions 这个插件,同时在使用的时候要告诉 Babel,我们要使用这个插件参与编译。

bash 复制代码
./node_modules/.bin/babel index.js --out-file target.js --plugins @babel/plugin-transform-arrow-functions

那么现在,我们的 target.js 中的 JavaScript 代码就没有箭头函数了,留下的只是一个普通的函数表达式。

js 复制代码
// target.js
const fn = function () {
  console.log("I'm a arrow function");
};

上面的操作都是对于「插件」而言的,那么「预设」又是什么呢?其实预设就是一组插件,一堆插件的集合。

例如我们还是想要进行箭头函数的语法降级,但同时,我们也想将类、解构赋值、展开运算符等语法特性也进行降级。那么,我们还是使用插件的话,就需要自己一个一个的寻找和下载插件,这就比较费时费力了,故 Babel 提供了预设,我们可以直接使用 Babel 的预设 ------ 插件集,来代替自己寻找一个个的插件。

js 复制代码
// index.js
const fn = () => {
  console.log("I'm a arrow function");
};

let { name, age } = {
  name: 'scoheart',
  age: 18,
};

var a = ['a', 'b', 'c'];

var b = [...a, 'foo'];

class Test {
  constructor(name) {
    this.name = name;
  }

  logger() {
    console.log('Hello', this.name);
  }
}
bash 复制代码
npm install --save-dev @babel/preset-env

./node_modules/.bin/babel index.js --out-file target.js --presets @babel/preset-env
js 复制代码
// target.js
//下面只是部分代码,省略了一些函数......
var fn = function fn() {
  console.log("I'm a arrow function");
};
var _name$age = {
    name: 'scoheart',
    age: 18,
  },
  name = _name$age.name,
  age = _name$age.age;
var a = ['a', 'b', 'c'];
var b = [].concat(a, ['foo']);
var Test = /*#__PURE__*/ (function () {
  function Test(name) {
    _classCallCheck(this, Test);
    this.name = name;
  }
  _createClass(Test, [
    {
      key: 'logger',
      value: function logger() {
        console.log('Hello', this.name);
      },
    },
  ]);
  return Test;
})();

但是,一旦我们要联合额外的插件和预设一起使用,或者增加一些配置,那么在命令行里面去指定这些就略显繁琐,例如

bash 复制代码
./node_modules/.bin/babel <source> --out-dir <dir> --presets @babel/preset-env,@babel/preset-react --plugins @babel/plugin-transform-typescript,@babel/plugin-proposal-class-properties

因此 Babel 还提供了配置文件,通过配置文件,我们可以将所有的配置集中在一个地方,而不必每次都在命令行中手动添加所有的预设和插件。

js 复制代码
// babel.config.js
module.exports = {
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript"
    // 添加其他预设
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties"
    // 添加其他插件
  ]
}

这样能够使配置更加清晰、易于维护,并且提高了可重用性。在大型项目中,使用配置文件可以更方便地组织和管理 Babel 的配置。

相关推荐
加班是不可能的,除非双倍日工资2 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi2 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip2 小时前
vite和webpack打包结构控制
前端·javascript
excel3 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国3 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼3 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy3 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT3 小时前
promise & async await总结
前端
Jerry说前后端3 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
画个太阳作晴天4 小时前
A12预装app
linux·服务器·前端