《laya源码分析》laya是如何将TS转成bundle.js的

-前言-

随着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进行编译的。

{
"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文件。

从这部分截图看到,一个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的时候会静态分析我们的代码,并排除任何未实际使用的内容。编译的时候还会计算循环引用,方便我们检查代码的正确性。

这个版本不光编译速度所有提升,另外增加了代码检查的等功能,让我们能在本地调试阶段就注意到一些代码上的潜在问题。

总结:

1.x   tasks.json调用tsc命令,tsc是编译Typescipt命令,运行项目时候会将TS文件编译成ES5格式js文件

        缺点:index.html里添加了大量js引用

2.x(x<3) 引入gulp工程自动化工具,使用browserify编译,tsify(访问编译器)/vinyl-source-steam(将browserify输出成gulp能够解析的格式vinyl)等插件

        缺点:每次运行项目走一遍gulp流程,bundle.js越大编译越慢

2.x(x>3) 使用rollup.js模块打包器插件,只支持es6,编译时生成cache文件,编译时长更短,还会计算循环引用,方便检查代码

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值