您的位置:首页 > 移动开发 > 微信开发

egret转微信小游戏时把类挂在window下的插件

2020-03-04 23:37 1161 查看

1.从egret编译好的main.js或main.min.js找出类

方法: 使用正则表达式

/__reflect\s*\(\s*[^,]+,\s*"([^\"]*)"/g;

如果有命名空间,找出来的类是带命名空间的,比如命名空间是a,类名是b,那匹配到的就是a.b

2.把类挂到window上

代码如下

/**
* 示例自定义插件,您可以查阅 http://developer.egret.com/cn/github/egret-docs/Engine2D/projectConfig/cmdExtensionPlugin/index.html
* 了解如何开发一个自定义插件
*
* 把类挂在window上,对main.min.js或main.js操作
*/
export class AddClass2WindowPlugin implements plugins.Command {
private fileName;
private buffer;
private classRegExp = /__reflect\s*\(\s*[^,]+,\s*"([^\"]*)"/g;;//代码中类名匹配组
private referenceMap = {};//类名到全限定类名映射
private needAddGlobalReferenceClassList = [];//需要添加都window上的类名
private componentReferenceClassList = [];//自定义组件的类名

constructor() {
}

async onFile(file: plugins.File) {
// 保存main.min.js或main.js文件的内容
if (file.basename.indexOf('main.min.js') > -1 || file.basename.indexOf('main.js') > -1) {
this.buffer = file.contents;
this.fileName = file.basename;
}
return file;
}

async onFinish(commandContext: plugins.CommandContext) {
if (this.buffer) {
let contents: string = this.buffer.toString()
let newCont = this.generateClassReferenceCode(contents);
commandContext.createFile(this.fileName, new Buffer(newCont));
}
}

private generateClassReferenceCode(codeContent: string): string {
if (this.fileName.indexOf(".min.js") >= 0) {
codeContent = codeContent.replace(/[\r\n]/g, "");
}

this.needAddGlobalReferenceClassList.length = 0;
this.referenceMap = {};
let classArray = this.classRegExp.exec(codeContent);

let className;
let nameSpaceName;

while (classArray) {
let fullClassName = classArray[1];

/*
// 这部分代码是循环把类和命名空间拆出来
// 让a.b.c最后挂的时候变成,window['c'] = a.b.c, window['b'] = a.b, window['a']=a
// 如不需要把命名空间挂window则可不启用,一般也不需要启用
let splitCount = 0;
while (true) {
splitCount++;
if (fullClassName.indexOf(".") !== -1) {
let fullClassNameSplitArr = fullClassName.split(".");
className = fullClassNameSplitArr.pop();
nameSpaceName = fullClassNameSplitArr.join(".");

if (nameSpaceName != "Legend.ProtoData" && nameSpaceName != "Legend.Proxy") {  // 这两个命名空间下的类无需挂在window
if (this.needAddGlobalReferenceClassList.indexOf(className) === -1) {
this.referenceMap[className] = fullClassName;
this.needAddGlobalReferenceClassList.push(className);

} else {
if (splitCount == 1) {
console.log(`代码中${fullClassName},${this.referenceMap[className]}存在两个相同的类名${className},即使在不同的命名空间下也不行!`);
}

}
}

} else {
if (this.needAddGlobalReferenceClassList.indexOf(fullClassName) === -1) {
this.referenceMap[fullClassName] = fullClassName;
this.needAddGlobalReferenceClassList.push(fullClassName);

} else {

if (splitCount == 1) {
console.log(`代码中存在两个相同的类名${fullClassName},即使在不同的命名空间下也不行!`);
}

}
break;
}
fullClassName = nameSpaceName;
}
*/
if (fullClassName.indexOf(".") !== -1) {
} else {
if (this.needAddGlobalReferenceClassList.indexOf(fullClassName) === -1) {
this.referenceMap[fullClassName] = fullClassName;
this.needAddGlobalReferenceClassList.push(fullClassName);
} else {
console.log(`代码中存在两个相同的类名${fullClassName},即使在不同的命名空间下也不行!`);
}
}

classArray = this.classRegExp.exec(codeContent);

}

let referenceCodeStr = ";window.egret=egret;";

this.needAddGlobalReferenceClassList.forEach((className) => {
referenceCodeStr += "window[\"" + className + "\"]=" + this.referenceMap[className] + ";"
});

codeContent += referenceCodeStr;

return codeContent;

}
}

3.egret中使用

和白鹭自定义插件的使用一致
打开config.wxgame.ts
improt 引入
commands 中new一下即可

import { AddClass2WindowPlugin } from './AddClass2WindowPlugin';

//省略中间代码

commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new WxgamePlugin(),
new AddClass2WindowPlugin ()
new ManifestPlugin({ output: 'manifest.js' }),
new CustomPlugin()
]
  • 点赞
  • 收藏
  • 分享
  • 文章举报
weixin_42276579 发布了3 篇原创文章 · 获赞 0 · 访问量 53 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: