配置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环境有不少坑,而每一个人根据 需求遇到的问题可能不一样,还需耐心解决!

相关文章
相关标签/搜索