TS打包后文件里含有大量的extends等辅助函数

  • Creator 版本:2.3.1和2.4.2

  • 目标平台:微信小游戏

typescript打包后,源码内含有大量的__extends,__ decorate ,__awaiter ,__generator等函数,增加了没必要的体积。
想知道怎么去掉这些函数,我自己来引入。
给tsconfig.json加"noEmitHelpers": true也没有效果。

修改gulp/util/create-bundler.js可行吗?我改了一下,可能是不熟悉babel的原因,没什么效果。

那是ts编译自带的,一个字母能占用多少体积?

我观察了下自己的一个项目,extends和 decorate函数分别有100多个,大概有100多KB的样子;awaiter和generator分别有77个,大概有200多KB的样子。
js文件有708KB,完全没必要,本来应该只有400KB的。

刷到你的这个问题,目前我的项目中也碰到了,解决了吗?

没有解决啊

查阅了typescript的资料,cocos官方2.4.4应该是实现了这个功能。
只是之前的版本你上文提到的这个配置选项没有作用。

自己写了一个替换的gulp工具,手动替换里面的工具函数,替换extends這些函數。
你看看能不能用得上,我公司两个项目试了可以的。
只是要去project.js里面找到这些函数替换工具里面的let变量。

有可能不同电脑打包出来的这些函数的形参不一样,所以要去找到这些工具函数的代码,提取出来。

gulp包:
ReplaceCode.zip (35.6 KB)

效果从之前的995減少到814,如果把下面的配置drop_console:true ,能到810,最終減少了185KB:

/**
导入gulp提供的api函数
src 输入流文件
dest 输出流文件
parallel 并行队列任务函数
series 顺序执行队列函数
watch 实时监听函数
**/
const { src, dest, parallel, series, watch } = require(‘gulp’);
let gulp = require(‘gulp’);
let size = require(‘gulp-size’);
let notify = require(‘gulp-notify’);
let header = require(‘gulp-header’);
let uglify = require(‘gulp-uglify’);
let replace = require(‘gulp-replace’);
let pipeline = require(‘readable-stream’).pipeline;

let projectPath = ‘…/…/code/build/wechatgame/src’;
let projectName = ‘project.js’;

let ASSIGN = function(t){for(var e,n=1,o=arguments.length;n<o;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t};

let EXTENDS = function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function o(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(o.prototype=n.prototype,new o)}};

let AWAITER = function(t,e,n,o){return new(n||(n=Promise))(function(i,r){function a(t){try{c(o.next(t))}catch(t){r(t)}}function s(t){try{c(o.throw(t))}catch(t){r(t)}}function c(t){t.done?i(t.value):new n(function(e){e(t.value)}).then(a,s)}c((o=o.apply(t,e||[])).next())})};

let DECORATE = function(t,e,n,o){var i,r=arguments.length,a=r<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,n,o);else for(var s=t.length-1;s>=0;s--)(i=t[s])&&(a=(r<3?i(a):r>3?i(e,n,a):i(e,n))||a);return r>3&&a&&Object.defineProperty(e,n,a),a};

let GENERATOR = function(t,e){var n,o,i,r,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function s(t){return function(e){return c([t,e])}}function c(r){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return a.label++,{value:r[1],done:!1};case 5:a.label++,o=r[1],r=[0];continue;case 7:r=a.ops.pop(),a.trys.pop();continue;default:if(!(i=(i=a.trys).length>0&&i[i.length-1])&&(6===r[0]||2===r[0])){a=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){a.label=r[1];break}if(6===r[0]&&a.label<i[1]){a.label=i[1],i=r;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(r);break}i[2]&&a.ops.pop(),a.trys.pop();continue}r=e.call(t,a)}catch(t){r=[6,t],o=0}finally{n=i=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}};

gulp.task(‘computed_prev_size’, function () {
let s = size();
return gulp.src([${projectPath}/${projectName}])
.pipe(s)
.pipe(gulp.dest(projectPath))
.pipe(notify({
onLast: true,
message: () => 替换前的文件大小为:${s.prettySize}
}));
});

gulp.task(‘computed_over_size’, function () {
let s = size();
return gulp.src([${projectPath}/${projectName}])
.pipe(s)
.pipe(gulp.dest(projectPath))
.pipe(notify({
onLast: true,
message: () => 替换后的文件大小为:${s.prettySize}
}));
});

gulp.task(‘replace_assign’, function () {
return gulp.src([${projectPath}/${projectName}])
.pipe(replace(ASSIGN, ‘ASSIGN’))
.pipe(gulp.dest(projectPath))
});

gulp.task(‘replace_extends’, function () {
return gulp.src([${projectPath}/${projectName}])
.pipe(replace(EXTENDS, ‘EXTENDS’))
.pipe(gulp.dest(projectPath))
});

gulp.task(‘replace_awaiter’, function () {
return gulp.src([${projectPath}/${projectName}])
.pipe(replace(AWAITER, ‘AWAITER’))
.pipe(gulp.dest(projectPath))
});

gulp.task(‘replace_decorate’, function () {
return gulp.src([${projectPath}/${projectName}])
.pipe(replace(DECORATE, ‘DECORATE’))
.pipe(gulp.dest(projectPath))
});

gulp.task(‘replace_generator’, function () {
return gulp.src([${projectPath}/${projectName}])
.pipe(replace(GENERATOR, ‘GENERATOR’))
.pipe(gulp.dest(projectPath))
});

gulp.task(‘inject_tools’, function () {
let tool1 = let __ASSIGN__ = ${__ASSIGN__};;
let tool2 = let __EXTENDS__ = ${__EXTENDS__};;
let tool3 = let __AWAITER__ = ${__AWAITER__};;
let tool4 = let __DECORATE__ = ${__DECORATE__};;
let tool5 = let __GENERATOR__ = ${__GENERATOR__};;
let tools = [
tool1,
tool2,
tool3,
tool4,
tool5
];
return gulp.src(${projectPath}/${projectName})
.pipe(header(tools.join(’\n\n’)))
.pipe(gulp.dest(projectPath))
});

gulp.task(‘file_compress’, function () {
return pipeline(
gulp.src(${projectPath}/${projectName}),
uglify({
compress: {
// 过滤 console
drop_console: false,
// 过滤 debugger
drop_debugger: true
}
}),
gulp.dest(projectPath)
);
});

gulp.task(‘default’, gulp.series(
‘computed_prev_size’,
‘replace_assign’,
‘replace_extends’,
‘replace_awaiter’,
‘replace_decorate’,
‘replace_generator’,
‘inject_tools’,
‘file_compress’,
‘computed_over_size’
));

牛逼!

替换字符串可以用正则, 应该只需要把里面的变量名都换成英文句点?

正则也可以,主要是还得去翻阅正则资料,这玩意现学现用,我就直接去project.js里面找到这些函数提取出来。

我试了下, 换成正则还是挺麻烦的, 大概步骤是这样:

  1. 先使用f2把变量都重命名为test
  2. 将部分字符替换为转义, 譬如(){}[].+*?之前都需要加反斜杠
    3.将test替换为句点.
let ASSIGN = /function\(.\)\{for\(var .,.=1,.=arguments\.length;.<.;.\+\+\)for\(var . in .=arguments\[.\]\)Object\.prototype\.hasOwnProperty\.call\(.,.\)&&\(.\[.\]=.\[.\]\);return .\};/

牛,这样就可以规避了不同电脑打包出来的形参不一样,要去修改let变量的麻烦了

我采取了在添加脚本插件提供辅助函数, gulp里仅替换掉辅助函数而不添加的方法.
插件:typescript.zip (3.3 KB)
gulp代码:

gulp.task('replaceTslib', function (cb) {
    let replace = require('gulp-replace');
    let tslibMap = [
        ['window.__extends', /this&&this\.__extends\|\|function\(\)\{var .*?\)\}\}\(\)/g,],
        ['window.__awaiter', /this&&this\.__awaiter\|\|function\(.*?\|\|\[\]\)\)\.next\(\)\)\}\)\}/g,],
        ['window.__decorate', /this&&this\.__decorate\|\|function\(.*?\),.\}/g,],
        ['window.__generator', /this&&this\.__generator\|\|function\(.*?\[1\]:void 0,done:!0\}\}\}/g,],
    ];
    let stream = gulp.src([
        destDir + '/**/*.js'
    ]);
    for (let arr of tslibMap) {
        stream = stream.pipe(replace(arr[1], arr[0]));
    }
    return stream.pipe(gulp.dest(destDir))
        .on('end', cb);
})

没有使用你那个方式是因为cocos 2.4分包后project.js位置每个项目情况并不一致. 干脆不后期注入了.
正则我缩短了, 中间一部分用.*?代替了, 测试没有出问题, 但不排除出错的可能. 仅供参考.

该主题在最后一个回复创建后14天后自动关闭。不再允许新的回复。