使用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>
标签的顺序执行。