收藏
回答

自带的js minify(压缩)导致预览及调试的js出现问题;可否自定义minify过程?

开启自带的js minify之后实机调试出现 Uncaught TypeError: n is not a function 一类的报错。

通过调试工具查看 usr/app-service.js 之后发现似乎是minify的过程中将函数inline再加上重命名导致函数参数和外部函数发生混淆,怀疑是微信使用的老版本uglify-js的bug。(详情见最后面)

如果可能的话尽量不考虑修改js规避问题的解决方案,因为我js是从Kotlin编译出来的,要修改编译出来的js很麻烦。

自己做了一些简单实验,没有成功用简单代码片段来复现问题。

自己安装最新版uglify-js后手动minify出来是没有问题的,所以最佳解决方法应该是自定义minify过程,但在文档和社区没找到相关的资料。只知道有预编译shell指令之类的,但我不想让脚本修改项目中原始文件,否则在开发环境调试会很麻烦。最好的情况是脚本只影响实机调试和打包上传的代码,不影响开发工具内原始代码(就像自带的minify一样),但是不知道怎么实现。

项目仓库:https://github.com/shBLOCK/SolarUtils(因为是Kotlin项目所以结构很奇怪,微信开发者工具项目在wechat文件夹中。其中wechat/miniprogram/index/src中的代码是根目录中的gradle项目编译生成的。如果需要详细构建测试流程的话回复一下。)

原始代码(完整原始代码:https://gist.github.com/shBLOCK/5cad5d1ea2e2701f103d52100061e888):

function layout(_this__u8e3s4, layout) {
  _this__u8e3s4.o5t(layout);
  return _this__u8e3s4;
}
......
function addPanelSurface(_this__u8e3s4, colors, sizes, name, backgroundColor, layout, block) {
  colors = colors === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? Companion_getInstance_44().p5l() : colors;
  sizes = sizes === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? Companion_getInstance_48().h5q_1 : sizes;
  name = name === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? 'Panel' : name;
  var tmp;
  if (backgroundColor === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya) {
    tmp = addPanelSurface$lambda(colors);
  } else {
    tmp = backgroundColor;
  }
  backgroundColor = tmp;
  layout = layout === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? ColumnLayout_instance : layout;
  var panelSurface = PanelSurface(colors, sizes, name, backgroundColor, layout, block);
  _this__u8e3s4.j5q(panelSurface);
  return panelSurface;
}
function PanelSurface(colors, sizes, name, backgroundColor, layout, block) {
  colors = colors === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? Companion_getInstance_44().p5l() : colors;
  sizes = sizes === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? Companion_getInstance_48().h5q_1 : sizes;
  name = name === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? 'Panel' : name;
  var tmp;
  if (backgroundColor === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya) {
    tmp = PanelSurface$lambda;
  } else {
    tmp = backgroundColor;
  }
  backgroundColor = tmp;
  layout = layout === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? ColumnLayout_instance : layout;
  var panelSurface = UiSurface.k5q(colors, sizes, name);
  var tmp_0 = panelSurface;
  tmp_0.w5p_1 = PanelSurface$lambda_0(backgroundColor, layout, name, block);
  return panelSurface;
}
function Panel(_this__u8e3s4, backgroundColor_0, layout_0, scopeName, block) {
  backgroundColor_0 = backgroundColor_0 === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? _this__u8e3s4.e5g().w5l_1 : backgroundColor_0;
  layout_0 = layout_0 === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? ColumnLayout_instance : layout_0;
  scopeName = scopeName === _kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.VOID7hggqo3abtya ? null : scopeName;
  // Inline function 'de.fabmax.kool.modules.ui2.Box' call
  var box = _this__u8e3s4.x5e().a5g(scopeName, (0,_kotlin_kotlin_stdlib_mjs__WEBPACK_IMPORTED_MODULE_0__.getKClass1s3j9wy1cofik)(BoxNode), Companion_getInstance_42().p5d_1);
  size(box.g5e(), FitContent_instance, FitContent_instance);
  // Inline function 'de.fabmax.kool.modules.ui2.Panel.<anonymous>' call
  backgroundColor(layout(box.g5e(), layout_0), backgroundColor_0);
  block(box);
}

minify后的代码片段(IDE pretty-print后的minify代码):

var _ = function (t, i, r, e, n, s) {
    var a;
    t = t === Ks.VOID7hggqo3abtya ? hO().p5l() : t, i = i === Ks.VOID7hggqo3abtya ? pO().h5q_1 : i, r = r === Ks.VOID7hggqo3abtya ? "Panel" : r, a = e === Ks.VOID7hggqo3abtya ? bO : e, e = a, n = n === Ks.VOID7hggqo3abtya ? Di : n;
    var h = ud.k5q(t, i, r);
    return h.w5p_1 = function (t, i, r, e) {
        return s => (function (t, i, r, e, s) {
            i = i === Ks.VOID7hggqo3abtya ? t.e5g().w5l_1 : i, r = r === Ks.VOID7hggqo3abtya ? Di : r, e = e === Ks.VOID7hggqo3abtya ? null : e;
            var a = t.x5e().a5g(e, (0, Ks.getKClass1s3j9wy1cofik)(hf), nO().p5d_1);
            RO(a.g5e(), Fi, Fi), function (t, i) {
                t.q5t(null != i ? new td(i) : null)
            }(n(a.g5e(), r), i), s(a)
        }(s, t(s), i, r, e), Ks.Unit_instance14hm69wy3kr8u)
    }(e, n, r, s), h
}(i, r, e, n, s, a);ke


可以通过 g5e() 函数来帮助对应两段代码。可以发现原代码中倒数第三行中对layout的调用变成了对变量n(原名layout)的调用。

开发者工具:最新(1.06.2412050 win32-x64)

回答关注问题邀请回答
收藏

1 个回答

  • 朱德德
    朱德德
    03-11
    1. 关闭原来自带的压缩 ( 开发工具右上角 - 详情 - 本地设置 - 上传代码时自动压缩脚本文件 )
    2. 项目中在开发工具右上角 - 详情 - 本地设置 - 编译前预处理


    这个地方可以让我们有运行一个脚本的能力。

    比如node install terser之后,运行以下脚本node precompile.js。

    // precompile.js 任意喜欢的压缩工具
    
    const { minify } = require("terser");
    await minify( ...........
    


    看了一下原项目,可以让压缩后文件名为index.min.js 。index.js里面require的地方改成 index.min.js 。kotlin gen出来的依然保持 index.js。

    03-11
    有用 1
    回复 1
    • 苏杭
      苏杭
      03-14
      感谢回复!
      这样可以实现自定义压缩,但是开发者工具里运行时也用的是压缩的代码。然后开发者工具里对sourcemap的支持似乎不是很好,导致调试会很难受。不过后来发现其实可以用conditional compilation解决。或者只在需要真机调试和上传的时候手动运行一下压缩。

      总之其实不算特别严重的问题,就是麻烦点。但可以考虑官方更新一下uglifyjs?(没有向后兼容问题的话)
      03-14
      回复
登录 后发表内容