alibaba / rax

🐰 Rax is a progressive framework for building universal application. https://rax.js.org
Other
8k stars 627 forks source link

[Feature] 使用“组件开发”功能编写微信小程序编译时组件时,每个组件都会注入几个重复的函数,是否能考虑 将这些函数抽离为公共函数? #2336

Open Awen-hub opened 2 years ago

Awen-hub commented 2 years ago

组件代码

import { useState } from "rax";

const Index = () => {
  const [count, setCount] = useState(0);
  const addCount = () => {
    setCount(count + 1);
  };
  return (
    <view>
      <text>{count}</text>
      <button onClick={addCount}>addCount</button>
    </view>
  );
};

export default Index;

产物

运行build命令打包成微信小程序组件后得到产物

"use strict";
var _jsx2mpRuntimeWechat = require("jsx2mp-runtime/dist/jsx2mp-runtime.wechat.esm");
function _slicedToArray(r, t) {
  return (
    _arrayWithHoles(r) ||
    _iterableToArrayLimit(r, t) ||
    _unsupportedIterableToArray(r, t) ||
    _nonIterableRest()
  );
}
function _nonIterableRest() {
  throw new TypeError(
    "Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
  );
}
function _unsupportedIterableToArray(r, t) {
  if (r) {
    if ("string" == typeof r) return _arrayLikeToArray(r, t);
    var e = Object.prototype.toString.call(r).slice(8, -1);
    return (
      "Object" === e && r.constructor && (e = r.constructor.name),
      "Map" === e || "Set" === e
        ? Array.from(r)
        : "Arguments" === e ||
          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)
        ? _arrayLikeToArray(r, t)
        : void 0
    );
  }
}
function _arrayLikeToArray(r, t) {
  var e, n;
  for (
    (null == t || t > r.length) && (t = r.length), e = 0, n = new Array(t);
    e < t;
    e++
  )
    n[e] = r[e];
  return n;
}
function _iterableToArrayLimit(r, t) {
  var e =
    null == r
      ? null
      : ("undefined" != typeof Symbol && r[Symbol.iterator]) || r["@@iterator"];
  if (null != e) {
    var n,
      a,
      o = [],
      i = !0,
      u = !1;
    try {
      for (
        e = e.call(r);
        !(i = (n = e.next()).done) && (o.push(n.value), !t || o.length !== t);
        i = !0
      );
    } catch (r) {
      (u = !0), (a = r);
    } finally {
      try {
        i || null == e.return || e.return();
      } finally {
        if (u) throw a;
      }
    }
    return o;
  }
}
function _arrayWithHoles(r) {
  if (Array.isArray(r)) return r;
}
function MyComponent() {
  var r = _slicedToArray((0, _jsx2mpRuntimeWechat.useState)(0), 2),
    t = r[0],
    e = r[1];
  this._updateData({ _d0: t }),
    this._updateMethods({
      _e0: function () {
        e(t + 1);
      },
    });
}
var __def__ = MyComponent;
Component(
  (0, _jsx2mpRuntimeWechat.createComponent)(__def__, { events: ["_e0"] })
);

建议

就产物代码来看_slicedToArray、_arrayWithHoles、、_iterableToArrayLimit、_unsupportedIterableToArray、_nonIterableRest这几个函数都是无副作用的。同时发现每个使用了useState钩子(暂时不了解其他hooks是否有类似情况)的组件打包时都会注入一样的逻辑,当组件数量较大时会有造成较多的体积浪费。建议将这几个函数抽离到一个npm依赖,在打包产物时候通过require("xxx")的方式引入,优化产物的体积大小。

Awen-hub commented 2 years ago

观察到这几个函数是babel把es6转译成es5时候注入的helper函数,一般web项目通过@babel/plugin-transform-runtime这个插件去解决重复注入helper函数的问题。想问一下组件开发功能目前是否有不开启es6转es5配置项?微信小程序开发者工具目前自带有es6转es5功能,同时也内置了@babel/plugin-transform-runtime插件,如果把转译任务交给微信开发者工具或许是一个好的解决方案。