美文网首页H5游戏
使用gulp对微信小游戏进行分包

使用gulp对微信小游戏进行分包

作者: 吴海生 | 来源:发表于2020-03-12 18:33 被阅读0次

方案

  1. 生成未压缩混淆的游戏整包 wxgame.js
  2. 截取中间部分标记切割wxgame.js为两个wxgame.js
  3. 把依赖包含到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;

相关文章

网友评论

    本文标题:使用gulp对微信小游戏进行分包

    本文链接:https://www.haomeiwen.com/subject/inxcoctx.html