最近在搞一个公司用的插件开发环境,环境是以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环境有不少坑,而每一个人根据 需求遇到的问题可能不一样,还需耐心解决!