若想在浏览器中运行TypeScript,编译过程比在服务器中运行要复杂一些
首先,要为编译选择一个目标模块系统。如果是发布一个库,供他人使用(例如发布到NPM上),应该始终使用umd,以便最大程度上兼容各人在自己的项目中使用的不同的模块打包工具。
如果代码只供自己使用,不发布到NPM上,那么编译为哪种格式取决于你使用的模块打包工具。
例如WebPack和Rollup对ES2015模块支持最好,而Browserify要求使用CommonJS模块。以下做一些参考:
-
如果使用SystemJS模块加载器,把module设为systemjs。
-
如果使用兼容ES2015的模块打包工具,例如Webpack或Rollup,把module设为ES2015或更高的版本。
-
如果使用兼容ES2015的模块打包工具,而且代码中用到动态导入,把module设为esnext。
-
如果构建供其他项目使用的库,而且经过tsc处理之后没有再通过额外的构建步骤处理,为了最大程度上兼容各种加载器,把module设为umd。
-
如果使用CommonJS打包工具打包模块,例如Browserify,把module设为commonjs。
-
如果打算使用RequireJS或者其他AMD模块加载器加载代码,把module设为amd。
-
如果希望导出的顶级代码可在window对象上全局使用,把module设为none。注意,如果代码在模块模式下,为了减少对开发者的痛苦,TSC会强制把代码编译成commonjs模块。
接下来,配置构建流程,把所有TypeScript代码编译成一个JavaScript文件或一系列JavaScript文件。虽然设置outFile标志后,TSC会把小型项目编译为一个JavaScript文件,但是只能打包成SystemJS和AMD模块。另外,与专门的构建工具不同,TSC不支持构建插件和智能代码分拆,在某个阶段,你会发现需要使用功能更强大的打包工具。
签于此,对前端项目来说,一开始就建议使用功能更强大的构建工具。各种构建工具基本上都有TypeScript插件,例如:
- Webpack的ts-loader。
- Browserify的tsify。
- Babel的@babel/preset-typescript。
- Gulp的gulp-typescript。
- Grunt的grunt-ts。
最后,结合个人经验,给出几点基本建议:
- 保持代码模块化,避免隐式依赖(比如修改window或其他全局对象),以便让构建工具更为准确地分析项目的依赖图。
- 合理利用构建工具提供的自动代码分拆功能,以免加载过多的JavaScript代码,拖慢页面的加载速度。
- 针对生产环境的构建过程要尽量与开发过程中使用的构建过程一样。两者之间的差异越大,在生产环境中暴露出来的难以修复的BUG越多。
- 在容易报错的地方,用try catch捕获错误,在try catch 中的错误并不会阻塞整个页面,即使发生错误,页面也可以继续执行。