配置Typescript、ESLint並支持polyfill踩坑指南

前言

最近在搞一個公司用的插件開發環境,環境是以TypeScript+Webpack+ESlint+Sass並支持polyfill爲基礎進行配置的 可是在配置的過程當中TypeScript與其餘工具的配合上總會出現一些坑,而這些坑是我翻了不少國外論壇、知乎提問、去github倉庫找到兩年前的issue才解決的,因此在此記錄分享一下,但願能夠幫助須要的人躲避這些坑。node

TypeScript支持polyfill

起初我在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了 ~

ESLint配合TypeScript使用

如今不少其餘文章的配置已經被淘汰了,或者git倉庫也再也不維護,我也是順藤摸瓜找到的一份配置方案,其中也有一些坑,在此做記錄。

先列出須要安裝的擴展:

yarn add eslint eslint-loader @typescript-eslint/parser @typescript-eslint/eslint-plugin --dev

eslint和eslint-loader就很少說了,一個是基礎支持庫無需配置,一個是webpack檢測文件處理的loader

這裏主要介紹下後面兩個

@typescript-eslint/parser

因爲eslint默認是不支持檢測typescript的,咱們須要安裝它的擴展,讓它支持typescript的語法,因此它必不可少

@typescript-eslint/eslint-plugin

但當咱們有了它的功能後,咱們如何設定它的規則?因而官方提供了一套規則的擴展插件,也就是它了

配置ESLint

當我看到官方提供了一套這麼友好簡單易讀的默認配置,個人心裏是很是激動的,在解決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上查文檔
  }
}
複製代碼

參考.eslintrc配置文檔

如此一來ESLint便可與TypeScript搭配使用了!

結尾

另外我發現webpack在編譯typescript後沒有辦法壓縮,須要藉助webpack的uglifyjs-webpack-plugin插件來進行壓縮, 在配置TS環境有不少坑,而每一個人根據 需求遇到的問題可能不一樣,還需耐心解決!

相關文章
相關標籤/搜索