最近在搞一個公司用的插件開發環境,環境是以TypeScript+Webpack+ESlint+Sass並支持polyfill爲基礎進行配置的 可是在配置的過程當中TypeScript與其餘工具的配合上總會出現一些坑,而這些坑是我翻了不少國外論壇、知乎提問、去github倉庫找到兩年前的issue才解決的,因此在此記錄分享一下,但願能夠幫助須要的人躲避這些坑。node
起初我在TypeScript文檔中找到,配置tsconfig.js,其中 compilerOptions 參數中 lib 這個配置,中文文檔中的描述爲:webpack
編譯過程當中須要引入的庫文件的列表。
git
因此我一直認爲只要在lib中聲明瞭es2015.promise 它就能夠智能的爲我引入promisees6
{
"compilerOptions" :{
"lib":["dom", "scripthost", "es5","es2015.promise"],
...
},
...
}
複製代碼
然而並不會這樣,在配置文件中lib的實際做用是聲明咱們環境中TypeScript文件支持的語法方式。github
簡單一句話不易理解,咱們來測試一下:web
若是把lib中的"dom"刪掉,那麼若是你在寫代碼的時候使用JS建立了一個Element(dom)元素,在編譯的時候是不容許的。typescript
若是你使用了VScode,它會根據你tsconfig.js的配置文件,直接在使用了Element的代碼片斷告訴你,當前配置是不容許使用Element。json
若是咱們把lib中的"dom"添加回去,則編輯器就沒有錯誤提示了:promise
同時,lib這個字段是可選項,咱們能夠不配置它,它會有默認的配置,根據target的值不一樣,它的默認值也不一樣bash
//target = es5
{
"compilerOptions" :{
"target":"es5"
//"lib":["dom", "scripthost", "es5"]默認值
...
},
...
}
//target = es6
{
"compilerOptions" :{
"target":"es6"
//"lib":["dom", "scripthost", "es6","dom.iterable"]默認值
...
},
...
}
複製代碼
那麼 lib 中的配置究竟都作了什麼呢?
好比上面我想要讓它支持promise,我在lib中就添加了"es2015.promise"的值
打開node_modules找到typescript文件夾,他下面有一堆的lib.xx.xx文件
看看lib.es2015.promise都作了什麼, 它只是對promise方法作了類型語法的檢測支持
因此問題到這裏就迎刃而解了,單獨的配置lib屬性並不會帶來支持polyfill的實際做用
咱們須要安裝core-js
yarn add core-js --dev
而後在須要使用polyfill的文件中引用它
import * as Promise from 'core-js-pure/features/promise';
因爲我不但願我插件中的promise對全局的方法形成污染
因此我調用了core-js-pure中的promise,而不是core-js/features/promise注意二者的區別
另外記得配置下tsconfig.js的module參數爲commonjs
{
"compilerOptions" :{
"module":"commonjs",
...
},
...
}
複製代碼
注意這裏有坑:
core-js的官方代碼中,推薦咱們引用方式是
import Promise from 'core-js-pure/features/promise';
而不是
import * as Promise from 'core-js-pure/features/promise';
但它推薦的方式在typescript中編譯後會報錯,不符合typescript的語法
我在tsconfig.js中的module參數嘗試了umd/esnext/es2015都沒辦法正常打包
但當使用commonjs模式就能夠正常使用了,須要注意一下
配置後大功告成,環境已經能夠根據需求支持polyfill了 ~
如今不少其餘文章的配置已經被淘汰了,或者git倉庫也再也不維護,我也是順藤摸瓜找到的一份配置方案,其中也有一些坑,在此做記錄。
先列出須要安裝的擴展:
yarn add eslint eslint-loader @typescript-eslint/parser @typescript-eslint/eslint-plugin --dev
eslint和eslint-loader就很少說了,一個是基礎支持庫無需配置,一個是webpack檢測文件處理的loader
這裏主要介紹下後面兩個
因爲eslint默認是不支持檢測typescript的,咱們須要安裝它的擴展,讓它支持typescript的語法,因此它必不可少
但當咱們有了它的功能後,咱們如何設定它的規則?因而官方提供了一套規則的擴展插件,也就是它了
當我看到官方提供了一套這麼友好簡單易讀的默認配置,個人心裏是很是激動的,在解決typescript支持polyfill的問題上我已經心神憔悴了,它的出現就像夏日夜晚裏的一陣微風,你覺得是涼爽的,結果吹到臉上卻熱得發燙,讓人失望,由於這個配置會報錯!
//在根目錄建立.eslintrc.js
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/restrict-plus-operands": "error"
//這裏就調用了@typescript-eslint/eslint-plugin的rule配置,更多配置能夠去github上查文檔
}
}
//運行後報錯
Parsing error: ImportDeclaration should appear when the mode is ES6 and in the module context
複製代碼
這個ImportDeclaration是什麼東西?這個錯誤該如何解決?個人大腦比較蒙,按照以往的邏輯,國內的搜索引擎直接pass掉,確定找不到答案,因而我來到了stackoverflow.com企圖找到解決方案,結果比較遺憾,只搜到了一條相關的問題,而裏面的回答也沒有參考性,最終在github的issue看到有不少人也遇到過,可是問題都是一兩年前的,解決方案都是讓它們升級版本,而咱們在當前時間線的版本已是最新的了!開發人員真是鬼才啊,兩年前的bug又復現了呢
翻閱了四五個issue後,在絕望之際找到了解決方案,在parserOptions新增三個參數便可(ecmaVersion、sourceType、ecmaFeatures)
//在根目錄建立.eslintrc.js
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,//也就是ES6語法支持的意思
"sourceType": "module",
"ecmaFeatures": {
"modules": true
},
"project": "./tsconfig.json"
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/restrict-plus-operands": "error"
//這裏就調用了@typescript-eslint/eslint-plugin的rule配置,更多配置能夠去github上查文檔
}
}
複製代碼
如此一來ESLint便可與TypeScript搭配使用了!
另外我發現webpack在編譯typescript後沒有辦法壓縮,須要藉助webpack的uglifyjs-webpack-plugin插件來進行壓縮, 在配置TS環境有不少坑,而每一個人根據 需求遇到的問題可能不一樣,還需耐心解決!