方案
- 生成未压缩混淆的游戏整包 wxgame.js
- 截取中间部分标记切割wxgame.js为两个wxgame.js
- 把依赖包含到window上
示例
gulp task配置
/**
* 编译成单个js 不创建 window.a =a ;
*
* @param {*} fileName 生成的名字
* @param {*} outPath 输出路径
* @returns
*/
function compileWXTSFile(outPath, fileName) {
// 混淆参数
const uglifyOptions = {
mangle: true,// 混淆
compress: false // 不压缩
}
return gulp.src([
"libs/*.ts",
"src/**/*.ts"
])
.pipe(sorter(false)) // 排序 false 不显示日志
.pipe(tsProj()) // 编译TS文件
.pipe(concat(fileName)) // 合并编译后的js到一个文件
.pipe(gulp.dest(outPath))
}
/**
* 筛选出 window.a=a 生成独立js
*/
function createWXExport() {
// 进行编译 不进行混淆
return gulp.src([
"libs/*.ts",
"src/**/*.ts"
])
.pipe(sorter(false)) // 排序 false 不显示日志
.pipe(tsProj()) // 编译TS文件 // 读取已经混淆好的整包
.pipe(wxTools(true)) // 筛选顶层引用 用 window.a = a 包含
.pipe(concat("wxgame_export.js"))
.pipe(gulp.dest("wxgame_out/"))
}
/**
* 添加 window.a=a 到尾部
* @param { } inFile
* @param {*} outPath
* @param {*} outFileName
*/
var conactExport = function (inPath, outPath, fileName) {
return gulp.src([
inPath + fileName,
gameJSExport,
])
.pipe(concat(fileName))
.pipe(gulp.dest(outPath))
.on("end", () => {
console.log("sub success =>> ", outPath, fileName)
})
}
/**
* 分包
* @param {string } path 切割后输出路径
* @param {string} fileName 生成文件名
* @param {boolean} isLast
* @param {string } head
*/
function subWX(tempPath, outPath, fileName, isLast, head) {
var key = `define("game/battle/control/BattleDataControl"`
var uglifyArgs = {
mangle: false, // 分包不再进行混淆 只压缩空白
compress: {}
}
return gulp.src([gameJS,])
.pipe(wxSub(key, isLast, head))
.pipe(wxTools()) // 筛选顶层引用 用 window.a = a 包含
.pipe(concat(fileName))
// .pipe(uglify(uglifyArgs)) //打开则进行混淆这里方便调试
.pipe(gulp.dest(tempPath))
.on("end", () => { // 结束后
return conactExport(tempPath, outPath, fileName);
})
}
// 微信分包
gulp.task('wxsub', function (args, args2) {
var head = `var Laya = window.Laya;\n`;
var head2 = ` var Laya = window.Laya;var __extends = window.__extends;\n`;
// 编译
if (compile && compile.c != null) {
console.log("start wx compile");
return compileWXTSFile("wxgame_out", "wxgame.js").on("end", () => {
console.log("compileWXTSFile Finish");
createWXExport().on("end", () => {
subWX("wxgame_out/sub1/", "wxgame/sub1/", "wxgame.js", false, head);
subWX("wxgame_out/sub2/", "wxgame/sub2/", "wxgame.js", true, head2);
})
})
} else {
// 不编译 直接拿已经编译的进行切割
subWX("wxgame_out/sub1/", "wxgame/sub1/", "wxgame.js", false, head);
subWX("wxgame_out/sub2/", "wxgame/sub2/", "wxgame.js", true, head2);
}
});
gulp 插件
根据key截取代码
'use strict';
var through = require('through2');
var path = require('path');
var File = require('vinyl');
var Concat = require('concat-with-sourcemaps');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
/**
* 微信分包工具 ,基于amd模式下开发的游戏
* 将 var XXX 包装到 window.XXX =XXX;
* @param key 分包关键位置
* @param isLast 是否是取后面的
* @param isMain 是否是主包 主包不分包 但是加头部
*/
var wxgameSubTools = function (key, isLast, head, isMain) {
function onFile(file, enc, cb) {
if (file.isStream()) {
console.error('Streams are not supported!');
return cb();
}
let contents = "" + file.contents;
let outStr;
if (!isMain) {
if (key == null || key == "") {
console.error("key ", 'key= ' + key);
return cb();
}
const index = contents.indexOf(key);
if (index == -1) {
console.error('not find key ! key= ' + key);
return cb();
}
if (!isLast) { //
outStr = contents.substr(0, contents.indexOf(key));
} else {
outStr = contents.substr(contents.indexOf(key));
}
}else{
outStr = contents;
}
// 头部添加的文本
if (head) {
outStr = head + outStr;
}
file.contents = new Buffer(outStr);
cb();
this.emit("data", file);
}
// 不处理end 使用默认的end
return through.obj(onFile);
};
module.exports = wxgameSubTools;
生成分包 ,提取依赖到window
'use strict';
var through = require('through2');
var path = require('path');
var File = require('vinyl');
var Concat = require('concat-with-sourcemaps');
/**
* 微信分包工具 ,基于amd模式下开发的游戏
* 将 var XXX 包装到 window.XXX =XXX;
* @param {boolean } isExport 是否是只输出window.a=a
*/
var wxgameTools = function (isExport) {
/**
* 流处理 匹配 /(?:^|\n)(function|var) [_0-9a-zA-Z]+/ig; 添加为 window.XXX = XXX;
*
* @param {*} file 流文件
* @returns
*/
function onFile(file, enc, cb) {
if (file.isStream()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!'));
return cb();
}
var contents = "" + file.contents;
// 匹配fuanction XXX 或者 var XXX
var reg = /(?:^|\n)(function|var) [_0-9a-zA-Z]+/ig;
// 匹配fuanction 或者 var 去掉 function 或者 var
var reg2 = /(?:^|\n)(function|var) /ig;
var match = contents.match(reg)
if (match && match.length > 0) {
var strs = ""
for (var i = 0; i < match.length; i++) {
var str = match[i].replace(reg2, "");
strs += "\n try{window." + str + "=" + str + ";}catch(e){console.warn("+'"'+str+'")}';
}
var bf = new Buffer( strs ); // 提前分配
if(isExport){
file.contents = bf;
}else{
file.contents = Buffer.concat([file.contents, bf])
}
}
cb();
this.emit("data",file);
}
// 不处理end 使用默认的end
return through.obj(onFile);
};
module.exports = wxgameTools;