配置babel_Babel 7 下配置 TypeScript 支持
插件集 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-start、es.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@3corejs 只在 useBuiltIns 取值為 “entry” 或 “usage” 的時候有用,因為 Babel 所謂內置的 polyfills 工具就是 corejs。corejs 可以配置為 2 或 3。
安裝 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-properties 和 plugin-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 < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }var Animal = /*#__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.from、String.prototype.split 等。我們可以在 preset-env 下配置 polyfills,corejs 是 Babel 使用的內置 polyfills 庫。
默認,polyfills 會寫入全局環境,插件 plugin-transform-runtime 提供了“隔離”能力,你只需修改一下默認配置:corejs: 3 或者 corejs: 2。配置項corejs默認為false,也就是不管 polyfills 那部分工作。但corejs 被設置為2或3的時候,你需要額外安裝:
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 給出了回答:
綜上
有了 @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
歡迎訪問!
總結
以上是生活随笔為你收集整理的配置babel_Babel 7 下配置 TypeScript 支持的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Python 代码优化常见技巧
- 下一篇: java免费游戏,java – 分配免费
