LavaMoat / docs

React Native docs
1 stars 3 forks source link

MMM + SES: TypeError (0, _getPrototypeOf2.default) is not a function #24

Closed leotm closed 1 year ago

leotm commented 1 year ago
# JSC / V8
ERROR  TypeError: (0, _getPrototypeOf2.default) is not a function. (In '(0, _getPrototypeOf2.default)(Derived)', '(0, _getPrototypeOf2.default)' is undefined)

This error is located at:
    in AppContainer
    in LogBox(RootComponent)

Screenshot 2023-08-21 at 18 33 38

Screenshot 2023-08-21 at 18 34 06

_where runtime.js is: node_modules/regenerator-runtime/runtime.js_ _and asyncToGenerator.js is: node_modules/@babel/runtime/helpers/asyncToGenerator.js_

the cause remains ambiguous, with stack traces pointing to RN error logging internals and after examining the bundle

from the original error msg, the offending babel helper is:

// node_modules/@babel/runtime/helpers/getPrototypeOf.js
function _getPrototypeOf(o) {
  module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
    return o.__proto__ || Object.getPrototypeOf(o);
  }, module.exports.__esModule = true, module.exports["default"] = module.exports;
  return _getPrototypeOf(o);
}
module.exports = _getPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports;

but disabling the babel helper isn't sufficient

nor removing custom: polyfills, babel transforms, metro transforms

leotm commented 1 year ago

the current solution is to disable @babel/plugin-transform-runtime helpers in the preset

// node_modules/metro-react-native-babel-preset/src/configs/main.js
// ...
  if (!options || options.enableBabelRuntime !== false) {
    // Allows configuring a specific runtime version to optimize output
    const isVersion =
      typeof (options === null || options === void 0
        ? void 0
        : options.enableBabelRuntime) === "string";
    extraPlugins.push([
      require("@babel/plugin-transform-runtime"),
      {
        helpers: false, // default: true
        regenerator: !isHermes,
        ...(isVersion && {
          version: options.enableBabelRuntime,
        }),
      },
    ]);
  }
// ...

which in turn skips (per file/module)

// node_modules/@babel/plugin-transform-runtime/lib/index.js
// ...
    pre(file) {
      if (!useRuntimeHelpers) return; // early return when false skips the below
      file.set("helperGenerator", name => {
        if (file.availableHelper && !file.availableHelper(name, runtimeVersion)) {
          return;
        }

        const isInteropHelper = HEADER_HELPERS.indexOf(name) !== -1;
        const blockHoist = isInteropHelper && !(0, _helperModuleImports.isModule)(file.path) ? 4 : undefined;
        const helpersDir = esModules && file.path.node.sourceType === "module" ? "helpers/esm" : "helpers";
        return addDefaultImport(`${modulePath}/${helpersDir}/${name}`, name, blockHoist, true);
      });
      const cache = new Map();

      function addDefaultImport(source, nameHint, blockHoist, isHelper = false) {
        const cacheKey = (0, _helperModuleImports.isModule)(file.path);
        const key = `${source}:${nameHint}:${cacheKey || ""}`;
        let cached = cache.get(key);

        if (cached) {
          cached = _core.types.cloneNode(cached);
        } else {
          cached = (0, _helperModuleImports.addDefault)(file.path, source, {
            importedInterop: isHelper && supportsCJSDefault ? "compiled" : "uncompiled",
            nameHint,
            blockHoist
          });
          cache.set(key, cached);
        }

        return cached;
      }
    }
// ...

@babel/plugin-transform-runtime is

A plugin that enables the re-use of Babel's injected helper code to save on codesize.

where the helpers (useRuntimeHelpers) option

Toggles whether or not inlined Babel helpers (classCallCheck, extends, etc.) are replaced with calls to moduleName [see Helper aliasing]

so with the side effect of increasing codesize (not a big issue) but significantly increasing app TTI with SES ⚠️ which can be resolved for JSC only by disabling the RN promise polyfill, but not V8 so a better solution is needed

enter vetted shims

leotm commented 1 year ago

fixed in https://github.com/MetaMask/metamask-mobile/pull/6586/commits/310defe8ddf4ee3fccefebc9edd3d0a5e447f085