热门标签 | 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

欢迎访问!



推荐阅读
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java如何导入和导出Excel文件的方法和步骤详解
    本文详细介绍了在SpringBoot中使用Java导入和导出Excel文件的方法和步骤,包括添加操作Excel的依赖、自定义注解等。文章还提供了示例代码,并将代码上传至GitHub供访问。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 本文讨论了在dva中引入antd组件table时没有显示样式的问题。提供了.roadhogrc文件的配置,包括环境和import的设置。同时介绍了extraBabelPlugins和transform-runtime的使用方法,并解释了libraryName和css的含义。 ... [详细]
  • 本文介绍了Java调用Windows下某些程序的方法,包括调用可执行程序和批处理命令。针对Java不支持直接调用批处理文件的问题,提供了一种将批处理文件转换为可执行文件的解决方案。介绍了使用Quick Batch File Compiler将批处理脚本编译为EXE文件,并通过Java调用可执行文件的方法。详细介绍了编译和反编译的步骤,以及调用方法的示例代码。 ... [详细]
  • Tomcat安装与配置教程及常见问题解决方法
    本文介绍了Tomcat的安装与配置教程,包括jdk版本的选择、域名解析、war文件的部署和访问、常见问题的解决方法等。其中涉及到的问题包括403问题、数据库连接问题、1130错误、2003错误、Java Runtime版本不兼容问题以及502错误等。最后还提到了项目的前后端连接代码的配置。通过本文的指导,读者可以顺利完成Tomcat的安装与配置,并解决常见的问题。 ... [详细]
  • Annotation的大材小用
    为什么80%的码农都做不了架构师?最近在开发一些通用的excel数据导入的功能,由于涉及到导入的模块很多,所以开发了一个比较通用的e ... [详细]
  • 基于分布式锁的防止重复请求解决方案
    一、前言关于重复请求,指的是我们服务端接收到很短的时间内的多个相同内容的重复请求。而这样的重复请求如果是幂等的(每次请求的结果都相同,如查 ... [详细]
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社区 版权所有