热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

配置babel_Babel7下配置TypeScript支持

本文将展示,如何使用babelpreset-typescript和babelpreset-env配置一个最小但完整的编译环境,打包工具使用webpack
本文将展示,如何使用 @babel/preset-typescript 和 @babel/preset-env 配置一个最小但完整的编译环境,打包工具使用 webpack@4.41.2

插件集 preset-typescript

preset-typescript 是 Babel 提供的预设插件集之一,Babel 官方对其有一篇简短的介绍:

https://babeljs.io/docs/en/babel-preset-typescript

其中仅包含插件:@babel/plugin-transform-typescript

顾名思义,它的作用是转换 TypeScript 代码。

插件集 preset-env

preset-env 也是 Babel 提供的预设插件集之一,它可以将 ES6 转换为 ES5。preset-env 对于插件的选择是基于某些开源项目的,比如 browserslist、compat-table 以及 electron-to-chromium。我们常用 .browserslistrc 来设置我们预想满足的目标运行环境,如:

> 0.25%
not dead

这里不详细展开 browserslist 的使用,有时间会专门写一篇文章。我现在要详细说的是 preset-env 的重要配置之一:useBuiltIns

useBuiltIns 从其名字来说是“使用内置”,“内置”的什么呢?从官方看来是“polyfills”。它的取值可以是以下三种:

1) false:

不使用内置的“polyfills”,这意味着你需要自行解决必要的“polyfills”问题。

2) "entry":

只在“入口模块”处导入“polyfills”,你需要“根模块”写上import "core-js"import "regenerator-runtime/runtime",babel 会自动展开全部必要模块导入import "core-js/modules/X",X 是根据你配置的目标环境选择出来的 polyfill,如es.string.pad-startes.array.unscopables.flat。注意,如果你没有写import "core-js",则不会展开任何导入(import)语句。

3) "usage":

你不用写什么了,babel 会根据你配置的目标环境,在你使用到一些“ES6特性X”的时候,自动补充import "core-js/modules/X"。我觉得这是比较棒的选择!

另一个选项 corejs,指定的是使用的 corejs 的版本,corejs 需要你自己安装:

npm i -S core-js@2

或者

npm i -S core-js@3

corejs 只在 useBuiltIns 取值为 “entry”“usage” 的时候有用,因为 Babel 所谓内置的 polyfills 工具就是 corejs。corejs 可以配置为 23

安装 Babel 基础

5 个包需要下载安装,它们分别是:

  • @babel/core
  • @babel/preset-env
  • @babel/preset-typescript
  • @babel/plugin-proposal-class-properties
  • @babel/plugin-proposal-object-rest-spread

其中包含了 2 个插件 plugin-proposal-class-propertiesplugin-proposal-object-rest-spread,分别用于转换语法特性“类属性”、“对象展开”,二者均处于“提议”阶段。

三步配置 babel

首先,在项目的根目录创建文件 .babelrc,写入下面的内容:

{"presets": [["@babel/env",{"useBuiltIns": "usage","corejs": {"version": 3,"proposals": true // 使用尚在“提议”阶段特性的 polyfill}}],"@babel/typescript"],"plugins": ["@babel/proposal-class-properties","@babel/proposal-object-rest-spread"]
}

然后,创建 .browserlistrc 文件,配置目标环境:

> 0.25%
not dead

最后,创建 tsconfig.json 文件,配置 TypeScript 编译器:

{"compilerOptions": {// Target latest version of ECMAScript."target": "esnext",// Search under node_modules for non-relative imports."moduleResolution": "node",// Process & infer types from .js files."allowJs": true,// Don't emit; allow Babel to transform files."noEmit": true,// Enable strictest settings like strictNullChecks & noImplicitAny."strict": true,// Disallow features that require cross-file information for emit."isolatedModules": true,// Import non-ES modules as default imports."esModuleInterop": true},"include": ["src"]
}

安装 babel-cli 以执行编译

为了执行编译,你可以安装 cli:

npm i -D @babel/cli

并在package.json 文件的 scripts 字段中加上命令:"compile": "babel src --out-dir lib --extensions ".ts""

在终端执行命令:

npm run compile

集成 webpack

现在加入 webpack 打包工具,首先安装它:

npm i -D webpack

配置 webpack,在项目根目录创建 webpack.config.js:

const path = require("path")module.exports = {mode: "production",entry: "./src/index.ts",output: {path: path.resolve("./www/dist"),filename: "[name].bundle.js",chunkFilename: "[name].chunk.[chunkhash:7].js"},resolve: {extensions: [".ts", ".js"],},module: {rules: [{test: /.ts$/,use: "babel-loader"}]}
}

编写执行 webpack 的脚本,创建 scripts.js:

const webpack = require("webpack")
const config = require(`./webpack.config`)const compiler = webpack(config)
compiler.run((err, stat) => {if (err) throw errconsole.log(stat.toString({colors: true}))
})

在 package.json 文件中加入命令:"pack": "node scripts.js"

执行打包:npm run pack

区别 runtime 和 polyfills

为了性能,Babel 官方建议使用插件 @babel/plugin-transform-runtime。这个插件有什么作用呢?

1)不使用 plugin-transform-runtime

提供如下 TypeScript 脚本内容:

class Staff {name: string = "Singhi"say() {console.log(`I am ${this.name}`)}
}

Babel 转换后的代码如下:

"use strict";require("core-js/modules/es.function.name");Object.defineProperty(exports, "__esModule", {value: true
});function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }function _defineProperties(target, props) { for (var i = 0; i /*#__PURE__*/
function () {function Animal() {_classCallCheck(this, Animal);_defineProperty(this, "name", "Singhi");}_createClass(Animal, [{key: "say",value: function say() {console.log("I am ".concat(this.name));}}]);return Animal;
}();

可以看到 Babel 为我们插入了很多的函数:

  • _classCallCheck
  • _defineProperties
  • _createClass
  • _defineProperty

它们都是用来创建类Animal的,我们的类Animal被转换了。需要注意,Babel 会为每个模块(js 文件)写入这样一段内容,如果我们有 1000 个模块,那么就会有 1000 段这样的“东西”,这是内容上的重复。为了复用,Babel 允许我们配置这个插件。

2)使用 plugin-transform-runtime

配置如下:

"plugins": ["@babel/plugin-transform-runtime",// ...
]

我们来看看配置后的输出:

...var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));...

可以看出来,Babel 从 @babel/runtime/helpers 中引入了一些工具,并经过_interopRequireDefault处理赋值给局部变量。这里的 @babel/runtime 包是需要额外安装的:

npm i -S @babel/runtime

@babel/runtime 为我们提供了一些额外的函数,以辅助语言的降级转换。而 plugin-transform-runtime 插件则基于 @babel/runtime 避免了内容上的重复,从而减小了程序包的体积。

与@babel/runtime不同,polyfills 用于提供 API,如 Array.fromString.prototype.split 等。我们可以在 preset-env 下配置 polyfills,corejs 是 Babel 使用的内置 polyfills 库。

默认,polyfills 会写入全局环境,插件 plugin-transform-runtime 提供了“隔离”能力,你只需修改一下默认配置:corejs: 3 或者 corejs: 2。配置项corejs默认为false,也就是不管 polyfills 那部分工作。但corejs 被设置为23的时候,你需要额外安装:

npm i -S @babel/runtime-corejs2

或:

npm i -S @babel/runtime-corejs3

并且将 preset-env 的配置项 useBuiltIns 设置为false,否则就重复了。

假如我们的代码使用了Promise,Babel 会生成以下内容:

require("@babel/runtime-corejs3/core-js-stable/promise")

你可能会疑惑,当我们未安装包 @babel/runtime 的时候,Babel 从哪里获得 helpers?这个问题参考我在 github 上的一个提问:

https://github.com/babel/babel/issues/10984#issuecomment-573347933

维护者 nicolo-ribaudo 给出了回答:

e59f778ddc6b7a13f9b487b083561c09.png

综上

有了 @babel/preset-typescript ,配置 TypeScript 环境确实方便了很多。需要注意的是,@babel/preset-typescript 只做语法转换,不做类型检查,因为类型检查的任务可以交给 IDE (或者用 tsc)去做。另外,Babel 负责两件事:1)语法转换,由各种 transform 插件、helpers 完成;2)对于可 polyfill 的 API 的提供,由 corejs 实现。@babel/plugin-transform-runtime 插件可用于减少生成代码的量,以及对 corejs 提供的 API 与 runtime 提供的帮助函数(helpers)进行模块隔离。


本人博客地址:https://www.zhangxinghai.cn

欢迎访问!



推荐阅读
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • feat: Enhances Jest Testing Capabilities with Snapshot Support ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • Java中不同类型的常量池(字符串常量池、Class常量池和运行时常量池)的对比与关联分析
    在研究Java虚拟机的过程中,笔者发现存在多种类型的常量池,包括字符串常量池、Class常量池和运行时常量池。通过查阅CSDN、博客园等相关资料,对这些常量池的特性、用途及其相互关系进行了详细探讨。本文将深入分析这三种常量池的差异与联系,帮助读者更好地理解Java虚拟机的内部机制。 ... [详细]
  • 本文介绍了 Vue 开发的入门指南,重点讲解了开发环境的配置与项目的基本搭建。推荐使用 WebStorm 作为 IDE,其下载地址为 。安装时请选择适合您操作系统的版本,并通过 获取激活码。WebStorm 是前端开发者的理想选择,提供了丰富的功能和强大的代码编辑能力。 ... [详细]
  • 深入解析:React与Webpack配置进阶指南(第二部分)
    在本篇进阶指南的第二部分中,我们将继续探讨 React 与 Webpack 的高级配置技巧。通过实际案例,我们将展示如何使用 React 和 Webpack 构建一个简单的 Todo 应用程序,具体包括 `TodoApp.js` 文件中的代码实现,如导入 React 和自定义组件 `TodoList`。此外,我们还将深入讲解 Webpack 配置文件的优化方法,以提升开发效率和应用性能。 ... [详细]
  • Netty框架中运用Protobuf实现高效通信协议
    在Netty框架中,通过引入Protobuf来实现高效的通信协议。为了使用Protobuf,需要先准备好环境,包括下载并安装Protobuf的代码生成器`protoc`以及相应的源码包。具体资源可从官方下载页面获取,确保版本兼容性以充分发挥其性能优势。此外,配置好开发环境后,可以通过定义`.proto`文件来自动生成Java类,从而简化数据序列化和反序列化的操作,提高通信效率。 ... [详细]
  • 字节码开发笔记:深入解析与应用技巧 ... [详细]
  • Linux CentOS 7 安装PostgreSQL 9.5.17 (源码编译)
    近日需要将PostgreSQL数据库从Windows中迁移到Linux中,LinuxCentOS7安装PostgreSQL9.5.17安装过程特此记录。安装环境&#x ... [详细]
  • 字符串学习时间:1.5W(“W”周,下同)知识点checkliststrlen()函数的返回值是什么类型的?字 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 单元测试:使用mocha和should.js搭建nodejs的单元测试
    2019独角兽企业重金招聘Python工程师标准BDD测试利器:mochashould.js众所周知对于任何一个项目来说,做好单元测试都是必不可少 ... [详细]
  • 深入浅出 webpack 系列(二):实现 PostCSS 代码的编译与优化
    在前一篇文章中,我们探讨了如何通过基础配置使 Webpack 完成 ES6 代码的编译。本文将深入讲解如何利用 Webpack 实现 PostCSS 代码的编译与优化,包括配置相关插件和加载器,以提升开发效率和代码质量。我们将详细介绍每个步骤,并提供实用示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本文详细探讨了Zebra路由软件中的线程机制及其实际应用。通过对Zebra线程模型的深入分析,揭示了其在高效处理网络路由任务中的关键作用。文章还介绍了线程同步与通信机制,以及如何通过优化线程管理提升系统性能。此外,结合具体应用场景,展示了Zebra线程机制在复杂网络环境下的优势和灵活性。 ... [详细]
author-avatar
华华eva3
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有