注: 该方案为本地编辑器配合官方web编辑器的形式来进行开发,并非完全在本地开发与构建可用的playcanvas应用的方式。
虽然在上一篇文章Playcanvas本地编辑器开发方案中,我们实现了在本地的编辑器中进行Playcanvas脚本相关的开发,并同步到Web Editor中进行测试与构建的流程,并通过类型定义文件实现了第三方库的命令补全,但是javascript依旧面临着提示不足(尤其是作为对象的元素的第三方类型)以及多人合作的情况下代码越长越难维护的问题,所以我们打算尝试使用一下Typescript。在找了很久的资料之后找到了论坛以及github上"藏得很好"的两个网页:
在项目中使用Typescript
使用Typescript的话,我们的pcconfig文件会有一些变化,然后项目目录也会有一些改变,我们把ts文件都放到项目目录的src目录下,而留出一个build目录来存放最终构建成的js文件。
|
|
然后我们的 package.json 文件如下
|
|
文件保存之后先 npm install
安装一下需要的包。
最后是 tsconfig.json文件,定义了我们该从哪里去读取源文件,构建之后输出到哪,叫什么名字等等
|
|
之后我们便可以尝试 npm run build-push
构建,并将生成的js文件上传到服务器上了,注意此时所有的js文件都打包到了main.build.js中(尽管此时我们的代码还全是js文件,也会被打包),push成功之后我们还需要去playcanvas的面板中手动的点一下脚本文件的parse按钮去读取里面有哪些脚本实体。 之后我们每次添加新的 pc.ScriptTypes 或者脚本的参数(attributes)时,都需要手动的去点一下parse按钮
和Javascript的差异
查看上面的package.json,我们可以发现一个特点——这些npm的命令中没有 diff/pull 等命令了,因为使用Typescript来开发和Javascript开发有一个最大的不同——这些脚本源文件(js或ts),都不再存放在playcanvas中,playcanvas中只保有构建后的一个单独的文件,我们本地的脚本文件彻底交由git来进行管理即可,而下面这几条命令也可以实现我们的同步需求:
|
|
另外注意一点,如果项目原来使用了js,那么给playcanvas增加物理引擎支持的ammo.js这个文件不要放在src目录下,不然会出错,这个文件还是当作原有的js文件来处理就好了。,然后由于Playcanvas使用的是AMD模块而非ES6 Modules,所以我们在使用其api时需要指定类型定义文件,我们可以在tsconfig里面指定 "typeRoots": ["typings",],
,然后找到对应的库的类型定义文件,并把 .d.ts 类型定义文件都放到typings目录下,或者干脆直接npm install --save-dev
对应的模块,尽管我们并不会直接导入这些模块,但是能用上他们提供的定义文件来进行代码提示(前提是这个库的d.ts模块要支持作为全局库使用)。
webpack进行打包
该方案还是存在问题,因为如果要用node modules中的第三方包的话,我们导入包的方式就变成了 es6 module,而这样的话就不能直接在代码中使用 pc.createScript 这样的写法了(AMD MODULE),而是同样需要通过import的形式进行导入,这时webpack会把playcanvas也给打包到目标文件中,这样似乎和我们的需求有一些不同?这种方式貌似更贴近于纯本地去构建Playcanvas项目了,并且还出现了一些bug,所以感觉按照我现在的配置还是不太行的通,但是感觉这条路还是有办法走通的,不过由于我目前对Typescript的模块以及Playcanvas的构建机制不太了解,所以暂时不采用这个方案。(直接用tsc也可以直接把第三方的js文件给打包到最终的文件中,继续用amd模块就好)
由于Playcanvas不能直接编辑html去引入一些第三方的js文件,所以想要使用第三方的js时就有一些问题,我们本来采用的方案是直接用js去操纵DOM树,动态创建一个script元素并设置src然后挂载到DOM上,而我们现在既然使用了tsc将多个js/ts文件打包成了一个文件,那么我想着能不能更进一步,使用webpack将来源于node_modules里面的第三方模块也打包到最终的文件中。
之前的方案如下:
|
|
参考了下面几篇文章:
- webpack typescript
- webpack 模块打包原理
- commonJs、AMD、UMD、es6模块化的区别
- https://juejin.cn/post/6844904030649614349
先安装webpack,npm i --save-dev webpack webpack-cli
,然后编辑我们的tsconfig.json,这里我修改了module,改为了 ES2015(ES6),以及开启了sourceMap,以及moduleResolution设置为node。
|
|
然后编辑webpack的配置文件 webpack.config.js
|
|
这里额外提一点,我们的原项目是多个js文件组成的项目,并且没有一个公共的入口(都是全局作用域)。而webpack需要指定一个或多个文件作为入口,分析模块的调用,最终进行打包,所以我们这里新建了一个index.ts文件并作为入口,内容如下:
|
|
还有就是 webpack 不像 tsc 有一个 –onSuccess 的回调可以用来执行pcsync命令,所以我这里参考了 run-command-after-webpack-build 中的解决方案,以plugins的形式添加了一个插件,在每次webpack build之后同步我们的代码,最后将package.json中的对应的命令由tsc替换为webpack即可。
|
|
由于我们每次构建都会自动push,所以之前的build-push啥的都不需要了。