Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
leotm opened this issue Aug 21, 2023 · 2 comments
Closed

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

leotm opened this issue Aug 21, 2023 · 2 comments
Labels
error build/run time blocker jsc JavaScriptCore lockdown v8 Chrome V8

Comments

@leotm
Copy link
Member

leotm commented Aug 21, 2023

# 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 leotm added jsc JavaScriptCore v8 Chrome V8 error build/run time blocker lockdown labels Aug 21, 2023
@leotm
Copy link
Member Author

leotm commented Aug 22, 2023

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 added a commit to MetaMask/metamask-mobile that referenced this issue Aug 28, 2023
leotm added a commit to MetaMask/metamask-mobile that referenced this issue Aug 28, 2023
…) and hardenIntrinsics

Including eslint exceptions

Note with this simple SES vetted implementation (unbaked into RN core), our high priority issue persists (requiring better solution)
- LavaMoat/docs#24
leotm added a commit to MetaMask/metamask-mobile that referenced this issue Aug 30, 2023
- remove SES vetted shims implementation from entry file
- bake lockdown into RN
  - import [email protected]
  - import reflect-metadata (prior lockdown)
  - call lockdown (prior polyfillPromise, setUpXHR and setUpTimers)
  - (preserve polyfillPromise)
- update prev doc comments
- add detailed doc comments

Fix LavaMoat/docs#24
(Fix LavaMoat/docs#25)
Fix LavaMoat/docs#26

Next we can improve this implementation further with unreleased [email protected]
allowing for reflect-metadata as a vetted shim, rather than called prior lockdown
leotm added a commit to MetaMask/metamask-mobile that referenced this issue Sep 4, 2023
- remove SES vetted shims implementation from entry file
- bake lockdown into RN
  - import [email protected]
  - import reflect-metadata (prior lockdown)
  - call lockdown (prior polyfillPromise, setUpXHR and setUpTimers)
  - (preserve polyfillPromise)
- update prev doc comments
- add detailed doc comments

Fix LavaMoat/docs#24
(Fix LavaMoat/docs#25)

Partially fix LavaMoat/docs#26
(Unreleased) [email protected] is required for the full fix
Allowing for reflect-metadata as a vetted shim, rather than called prior lockdown
@leotm
Copy link
Member Author

leotm commented Sep 5, 2023

fixed in MetaMask/metamask-mobile@310defe

@leotm leotm closed this as completed Sep 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error build/run time blocker jsc JavaScriptCore lockdown v8 Chrome V8
Projects
None yet
Development

No branches or pull requests

1 participant