H5|探究Laya关于TypeScript多个版本的编译问题

-前言- 随着Laya版本迭代,现在已经到了2.x,每个版本除了修复固定的bug,也增加了很多特性。我们单独看看Laya对于项目工程的编译也不断进行的演变。接下来就从1.x到2.x看看Laya对于编译的变化。
-正文- 1.x编译方式
Laya1.x还没有引入gulp工程化管理工具。而是直接使用Vs Code相关配置来运行项目。其中包括两个配置。tasks.json与launch.json,tasks.json是在launch.json之前执行的配置文件。
Laya中TypeScript项目就是在tasks.json中对于TypeScript进行编译的。

//tasks.json { "version":"0.1.0", "command":"tsc", "isShellCommand":true, "args":["-p",".","--outDir","bin/js"], "showOutput":"silent", "problemMatcher":"$tsc" }

tasks.json运行tsc命令,tsc是编译TypeScript命令,当编译TypeScript的时候会去读取项目根目录读取tsconfig.json文件,这个文件是关于TypeScript编译的配置文件。关于tsconfig的详细配置:https://www.tslang.cn/docs/handbook/tsconfig-json.html
{ "compilerOptions": { "module": "commonjs", "target": "es5", "sourceMap": true }, "exclude": [ "node_modules" ] }

当我们运行项目的时候会将TS文件编译成es5格式js文件。
优缺点
尽快1.x项目这样配置可以满足我们的项目开发,优点也是很明显,配置很简单没有模块关联性,只要安装了TypeScript就可以运行项目,并且TS到JS编译是很快的过程,当我们修改了代码也能很快进行调试。但是缺点也很明显,首先我们看看项目index.html文件。
H5|探究Laya关于TypeScript多个版本的编译问题
文章图片

从这部分截图看到,一个html文件中会把我们项目中运用到的js文件全部引入,这个截图只是一小部分,随着项目越大,代码量越多,引入的JS文件会更加多。TypeScript天然符合面向对象编程思想,我们在编写ts文件的时候基本都是一个类一个文件,包括框架、功能这个js文件数量是不可估量的。大量细小文件会带来大量http请求,对于Laya这个追求性能的引擎怎么能容忍这种问题出现。另外这种引入js的方式是需要注意js引入顺序的,稍不注意就会造成报错。因此一种模块化的引入方式势在必行。接下来让我看看2.x的编译方式。
2.3.0之前
Laya到了2.x时代已经就开始引入gulp工程自动化工具了。这个时候我们依然除了TypeScript不需要安装任何node模块即可运行项目,因为当我们下载Laya的时候所有需要用到的模块已经放到了Laya的安装包内中了。目前Laya2.x的编译方式已经出现了两种方式。首先我们来看看2.x初期版本的编译方式。
这个版本主要使用browserify这个模块编译ts,当然也会用到tsify,vinyl-source-stream等插件,用户还可以用watchify监听文件变更进行时时编译。tsify主要用于访问TypeScript编译器,vinyl-source-stream用于将browserify输出成gulp能够解析的格式vinyl。另外诸如uglify等插件功能都可以在管道中使用。
//省略模块引入代码//使用browserify,转换ts到js,并输出到bin/js目录 gulp.task("default", function () { return browserify({ basedir: workSpaceDir, //是否开启调试,开启后会生成jsmap,方便调试ts源码,但会影响编译速度 debug: true, entries: ['src/Main.ts'], cache: {}, packageCache: {} }) //使用tsify插件编译ts .plugin(tsify) .bundle() //使用source把输出文件命名为bundle.js .pipe(source('bundle.js')) //把bundle.js复制到bin/js目录 .pipe(gulp.dest(workSpaceDir + "/bin/js")); });

通过这种自动化的过程,我们最终可以得到一个bundle.js文件,这个js文件整合了我们所有项目代码,解决了我上面说到的问题。程序运行的时候首先加载index.html并执行,接着拉取index.js并执行,index里面会去拉取我们项目所依赖的库文件以及我们自己的项目文件。
//index.js //库文件随着版本不同有所不同//-----libs-begin----- loadLib("libs/laya.core.js") loadLib("libs/laya.webgl.js") loadLib("libs/laya.ui.js") loadLib("libs/laya.physics.js") //-----libs-end------- loadLib("js/bundle.js");

以上做法按理说应该没有问题了,所有文件都打包到了bundle.js中了,不过当我们的项目越来越大还是会出问题,每当我们运行项目的时候都会走一次gulp流程,编译打包整个流程下来随着bundle.js越大时间会越慢。可能我们只需要修改一行代码马上调试,编译就有30s,这对于H5项目是无法容忍的,就因为我们使用TS写代码就受这种待遇么。接下来看看2.3.0版本中Laya对于编译的优化。
2.3.0版本
到了2.3.0版本,官方优化了发布压缩JS参数。首先来看看新版Laya的发布流程。
//省略模块引入代码gulp.task("compile", prevTasks, function () { // 发布时调用编译功能,判断是否点击了编译选项 if (global.publish && !global.config.compile) { return; } else if (global.publish && global.config.compile) { // 发布时调用编译,workSpaceDir使用publish.js里的变量 workSpaceDir = global.workSpaceDir; } return rollup.rollup({ input: workSpaceDir + '/src/Main.ts', treeshake: true,//建议忽略 plugins: [ typescript({ check: false, //Set to false to avoid doing any diagnostic checks on the code //删除注释 tsconfigOverride:{compilerOptions:{removeComments: true}} }), //shader文件 glsl({ // By default, everything gets included include: /.*(.glsl|.vs|.fs)$/, sourceMap: false, compress:false }), /*terser({ output: { }, numWorkers:1,//Amount of workers to spawn. Defaults to the number of CPUs minus 1 sourcemap: false })*/ ] }).then(bundle => { return bundle.write({ file: workSpaceDir + '/bin/js/bundle.js', format: 'iife',//编译成立即调用函数表达式 name: 'laya', sourcemap: true }); }); });

这个版本的Laya使用到了rollup.js这个模块打包器插件。这个工具默认只支持es6语法代码,如果需要支持commonJS需要引入rollup-plugin-commonjs模块,不过这个版本的Laya已经更改为es6语法代码库了,如果需要向下兼容需要修改编译文件。使用了rollup-plugin-typescript2对于TypeScript进行编译,当编译的时候会生成cache文件,编译时长变得更短。另外当treeshake设置为true的时候会静态分析我们的代码,并排除任何未实际使用的内容。编译的时候还会计算循环引用,方便我们检查代码的正确性。
【H5|探究Laya关于TypeScript多个版本的编译问题】这个版本不光编译速度所有提升,另外增加了代码检查的等功能,让我们能在本地调试阶段就注意到一些代码上的潜在问题。

    推荐阅读