一、問(wèn)題
在OPPO平臺(tái),要接入一個(gè)打點(diǎn)SDK,渠道只提供了JS版本,需要將部分JS代碼添加到main.js中。

二、使用構(gòu)建模板build-templates
參考自定義構(gòu)建模板
可以在build-templates放一個(gè)已經(jīng)添加過(guò)代碼的main.js,每次打包后,覆蓋過(guò)去。但是,如果在構(gòu)建面板勾選了MD5緩存,每次的main.js實(shí)際上是動(dòng)態(tài)變化的:
...
System.import('./application.45421.js').then(({ createApplication }) => {
...
這樣覆蓋過(guò)去的main.js,如果MD5碼有變動(dòng),就會(huì)導(dǎo)致覆蓋錯(cuò)誤。
解決辦法也有,就是打包完成后,不要改項(xiàng)目任何配置,緊接著再打包一次,這樣兩次打出來(lái)的包因?yàn)闊o(wú)任何變化,實(shí)際上MD5碼是不變的。步驟如下:
- 第一次打包時(shí),清除build-templates目錄中的main.js
- 在第二次打包之前,使用gulp腳本把第一次打出來(lái)的main.js添加上JS代碼,然后復(fù)制到build-templates目錄中,緊接著第二次打包,就可以正確覆蓋過(guò)去了。
三、重新打包rpk
思路就是每次打包完,使用gulp腳本把要添加的代碼復(fù)制到main.js當(dāng)中,然后重新壓縮一個(gè)rpk放到dist路徑中。
參考OPPO 小游戲 rpk 打包方法,但是使用quickgame subpack重新打包時(shí)出現(xiàn)了錯(cuò)誤

這里是打main分包時(shí),部分COCOS代碼引用不到。這條路走不通,就只能在COCOS打包過(guò)程中想辦法了。
四、使用COCOS插件
1.官方文檔 第一個(gè)擴(kuò)展
這個(gè)很好弄明白。然后大概看了以下教程,發(fā)現(xiàn)對(duì)我解決問(wèn)題幫助不大。
CocosCreator3D插件教程 插件小王子
B站制作插件視頻:
https://www.bilibili.com/video/BV1Ya411w7iA
https://www.bilibili.com/video/BV11z4y1k7aZ
https://www.bilibili.com/video/BV1Bt4y1Y7q3
https://www.bilibili.com/video/BV15p4y1z7YW
2.官方文檔 擴(kuò)展構(gòu)建流程
在編輯器的菜單欄中點(diǎn)擊 項(xiàng)目 -> 新建構(gòu)建擴(kuò)展包,得到cocos-build-template插件。
接著參考插件里的readme:
自定義構(gòu)建插件模板使用指南
首先歡迎體驗(yàn)自定義構(gòu)建插件功能,這是一份自定義構(gòu)建插件的簡(jiǎn)單模板,里面寫(xiě)了一些簡(jiǎn)單的添加構(gòu)建配置以及自定義鉤子函數(shù)的代碼示例,更多的用法可以參考官方文檔。
基本使用流程
- 插件模板內(nèi)使用了一些
node模塊方法,目前在packages.json內(nèi)添加了插件支持的模塊types,安裝后才能正常編譯通過(guò)以及得到更好的類(lèi)型提示。
npm install
- 通過(guò)直接修改該文件夾內(nèi)的代碼,編譯后,再 擴(kuò)展管理器 中找到對(duì)應(yīng)的構(gòu)建插件,然后點(diǎn)擊 重新載入 圖標(biāo)按鈕重啟插件即可。

示例代碼使用 ts 編寫(xiě),在使用之前請(qǐng)先在當(dāng)前目錄下執(zhí)行 tsc 編譯代碼。如果直接在當(dāng)前文件夾內(nèi)修改使用,可以執(zhí)行 tsc -w 監(jiān)聽(tīng)編譯。
如果還不知道如何編譯代碼或者如何使用 ts 編寫(xiě),可以參考 TypeScript 的官方文檔。
在使用過(guò)程中有任何建議反饋,歡迎在論壇上和我們交流。
-
啟用插件后打開(kāi)構(gòu)建插件面板,選擇任意平臺(tái),即可看到構(gòu)建插件注入的新參數(shù)。
image.png
3.按照readme實(shí)踐中遇到的問(wèn)題
- npm install失敗,此時(shí)建議使用cnpm install
- readme的package.json依賴如下:
"dependencies": {
"@types/electron": "^1.6.10",
"@types/fs-extra": "^5.0.4",
"@types/node": "^10.5.2"
}
如果需要切換node.js的版本,可以參考
使用nvm解決gulp ReferenceError: primordials is not defined
- 執(zhí)行tsc
使用npm install -g typescript安裝完ts,然后在cocos-build-template路徑下執(zhí)行tsc命令
node_modules/_electron@12.0.9@electron/electron.d.ts:6647:21 - error TS2694:
Namespace 'NodeJS' has no exported member 'Require'.
6647 require: NodeJS.Require;
~~~~~~~
Found 1 error.
這里我將dependencies中的node升級(jí)到12.1.0,還是無(wú)法解決。最后先使用cnpm install安裝fs-extra和node
"dependencies": {
"@types/fs-extra": "^5.0.4",
"@types/node": "^12.1.0"
},
然后再使用cnpm i --save electron@6.1.7完成安裝。現(xiàn)在再執(zhí)行tsc命令,終于可以編譯TS文件了。
- 當(dāng)我嘗試把官方文檔 第一個(gè)擴(kuò)展中的console.log代碼移植到build插件中,發(fā)現(xiàn)無(wú)法成功。最后把dist目錄中build.js改了一個(gè)名字就可以了,可見(jiàn)build.js是專門(mén)用來(lái)構(gòu)建使用的……
四、在cocos-build-template插件中使用鉤子
1.測(cè)試一下各個(gè)鉤子
把Hook.ts中各個(gè)函數(shù)都加個(gè)console,然后在構(gòu)建時(shí),打開(kāi)console控制臺(tái)觀察一下:

比如:
function onBeforeBuild(options) {
return __awaiter(this, void 0, void 0, function* () {
// Todo some thing
console.log("xxxxxxxxxxxxxxxonBeforeBuild");
log(`${PACKAGE_NAME}.webTestOption`, 'onBeforeBuild');
});
}

注意,這里如果看不到,刷新擴(kuò)展管理器是沒(méi)用的,可以重啟一下項(xiàng)目代碼試試。
2.一分鐘學(xué)會(huì) 定制項(xiàng)目構(gòu)建流程
var path = require('path');
var fs = require('fs');
function onBeforeBuildFinish (options, callback) {
Editor.log('Building ' + options.platform + ' to ' + options.dest); // 你可以在控制臺(tái)輸出點(diǎn)什么
var mainJsPath = path.join(options.dest, 'main.js'); // 獲取發(fā)布目錄下的 main.js 所在路徑
var script = fs.readFileSync(mainJsPath, 'utf8'); // 讀取構(gòu)建好的 main.js
script += '\n' + 'window.myID = "01234567";'; // 添加一點(diǎn)腳本到
fs.writeFileSync(mainJsPath, script); // 保存 main.js
callback();
}
這里因?yàn)閞equire的原因,我們就沒(méi)辦法在hooks.ts里引入path,fs了。這里參考 creator3.0, 引入js文件 require 不存在,怎么解決和 creator 3.0 如何使用js啊,仍然未得到解決。
所以只能在dist文件夾中直接改hooks.js文件。
var path = require('path');
var fs = require('fs');
function onAfterBuild(options, result) {
if(options.platform == "oppo-mini-game"){
console.log("xxxxxxxxxxxxxxxonAfterBuild i am oppo");
}
console.log("xxxxxxxxxxxxxxxonAfterBuild result", result.dest);
var mainJsPath = path.join(result.dest, '\main.js');// 獲取發(fā)布目錄下的 main.js 所在路徑
console.log("xxxxxxxxxxxxxxxmainJsPath", mainJsPath);
var script = fs.readFileSync(mainJsPath, 'utf8'); // 讀取構(gòu)建好的 main.js
console.log("xxxxxxxxxxxxxxxscript", script);
script += '\n' + 'window.myID = "01234567";'; // 添加一點(diǎn)腳本到
fs.writeFileSync(mainJsPath, script); // 保存 main.js
經(jīng)過(guò)測(cè)試,上述代碼在3.01和3.1.0版本中可行,但是在3.0.0版本中不行,控制臺(tái)如下:
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] Browserslist: caniuse-lite is outdated. Please run:
[Build] Browserslist: caniuse-lite is outdated. Please run the following command: `npx browserslist --update-db`
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] 構(gòu)建插件 cocos-build-template 的鉤子函數(shù) onBeforemake 執(zhí)行失敗,請(qǐng)檢查插件的代碼邏輯~
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] 構(gòu)建插件 cocos-build-template 的鉤子函數(shù) make 執(zhí)行失敗,請(qǐng)檢查插件的代碼邏輯~
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
[Build] 構(gòu)建插件 cocos-build-template 的鉤子函數(shù) onAftermake 執(zhí)行失敗,請(qǐng)檢查插件的代碼邏輯~
[Build] Cannot find module 'D:\CocosProject\Hello1\extensions\cocos-build-template\dist\web-hooks'
加了這個(gè)仍然不行
function onBeforeMake(root, options){
}
exports.onBeforeMake = onBeforeMake;
function onAfterMake(root, options){
}
exports.onAfterMake = onAfterMake;
function make(root, options){
}
exports.make = make;
