Typescript使用笔记

使用AnyTypescript已经有一段时间了,这期间踩了不少坑,也发现了一些骚操作。这里简单记录一下。

CommonJS与ES Module兼容的问题

由于各种原因,CommonJS的模块化方式与ES Module的模块化方式之间并不能很容易地一一对应起来。ES Module中有default export的概念,如果在0.js中写

1
export default A

那么就可以在1.js里面使用

1
import anyNameYouLike from './0'

来加载。但同时,一个模块在拥有default export的同时,也允许拥有别的export,这样一来,default export就得被编译成

1
module.exports.default=A

而不是

1
module.exports=A

但是问题在于,CommonJS的模块只导出一个对象时,往往会采用后一种方式,而ES Module又不能实现后一种方式,这就会导致许多混乱。

Typescript的编译器提供了一个编译选项--esModuleInterop,加上它就能解决这个问题。这样就可以在自己的代码里统一使用default export和default import了。

前端项目Code Splitting及磁盘空间节省

因为种种原因我不想用webpack,而我还不能使rollup正常工作,所以我用的bundler一直还是browserify。于是我必须手动进行Code Splitting。

为了使用类型推断等功能带来的便利,使用前端库的时候,同样需要将其安装到本地并import。但另一方面,为了减小bundle体积,优化首屏体验,用到的很多库其实应该从cdn加载。为了兼顾这两点,可以使用一个browserify的transform:browserify-shim。以React这个包为例,在package.json里加上如下配置:

1
2
3
4
5
6
7
8
9
10
{
"browserify":{
"transform":[
"browserify-shim"
]
},
"browserify-shim":{
"react":"global:React"
}
}

注意第一个react是包名,第二个React是由cdn导入的库提供的全局变量名。

那这个跟磁盘空间节省又有什么关系呢?它之所以能节省磁盘空间,是因为这么做了之后,本地不需要安装react,只需要安装@types/react,就可以import然后正常使用了。

顺便提一下,可以把所有脚本加上defer然后放到<head>里面,这样脚本会异步并行加载,并在dom渲染完成后,按照<script>标签的顺序执行。