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

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 分钟前
从 Markdown 到 Generative UI:AI 如何从“生成答案”进化到“生成界面”?
前端·人工智能·后端
请为小H留灯8 分钟前
Windows 本地前端项目一键运行指南:Volta+Node+pnpm + 阿里镜像完整初始化流程
前端·pnpm·node·js
J船长26 分钟前
从 App 开发到 Unity 游戏开发:建立认知地图,结合 AI 开始实践
前端
牛奔1 小时前
mise 管理多版本 Go 项目
开发语言·前端·chrome·后端·golang
能源革命2 小时前
Vue 网格拖拽布局组件全景指南:7 大方案深度对比
前端·javascript·vue.js
PC2005_cloud2 小时前
AI 汉字漂移实录:它为什么总把「学习」写成日语「学習」
前端·后端
穆梓兰煊2 小时前
AI供应链安全不再只是包安全,还涉及模型与数据
前端·数据库
RaaS1002 小时前
AI网关能做Prompt注入防护吗?AI网关核心功能详解
前端·后端
deli0072 小时前
Skill 怎么写才被 Agent 命中?18 条规则做成 SKILL.md 校验器,规范样例 92 分
前端