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

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 的配置。

相关推荐
jay神7 分钟前
【计算机毕业设计】基于Flask+Vue的电影数据可视化与智能推荐系统
前端·vue.js·python·信息可视化·flask·毕业设计·课程设计
FreeTinker6 小时前
HTML本地存储技术解析:localStorage与sessionStorage的原理、差异与应用场景
前端·html
qq_452396236 小时前
第十二篇:《全链路监控与可观测性:前端错误追踪与性能分析》
前端
wangruofeng7 小时前
Phosphor Icons 官网源码拆解:URL 即存储、水波动画与 7362 Star 图标库的架构实践
前端·架构·github
BigTopOne8 小时前
WebRTC Native / Android 开发学习资源整理
前端
excel8 小时前
nuxt 3 升级 nuxt 4 报错之 hasInjectionContext
前端
何以解忧,唯有..9 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
软件聚导航10 小时前
「聚小软 AI 助手」技术升级:从数据库检索到 RAG 知识库问答
前端·数据库·mysql·微信小程序·小程序·ai编程·rag
恋猫de小郭10 小时前
看懂大模型架构术语,帮助你理解目前常见的大模型开源架构
前端·人工智能·ai编程
yma1610 小时前
通过提示词实现GitHub Pages 和 Nginx 双部署竟然这么简单?
前端