Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Worklets without captured variables are rejected as "Regular javascript function" when transpiled by react-native-worklets' Babel plugin

未关闭
#275 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

@wn-na 已经在做这个了。

开始于 2026年10月19日。

  • #276 来自 @wn-na —— 未关闭

评估

难度
3/5
预计耗时
1-2 天
新手友好度
55/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
cpp, javascript, react-native
领域
backend, mobile

调研方向

Start with cpp/WKTJsiWorklet.h, especially isDecoratedAsWorklet() and createWorklet(), then trace how JsiObjectWrapper::setFunctionValue() handles a function without __closure. Reproduce with the supplied Babel output: a numeric __workletHash, string __initData.code, and no closure. Done when that no-capture worklet is recognized and invoked successfully while existing captured worklets still work.

由索引模型根据 Issue 内容生成。

描述

Description

When a project uses the Babel plugin from react-native-worklets (the Reanimated 4 worklets package) together with react-native-worklets-core, any 'worklet' function that does not capture any outer variables is not recognized as a worklet by worklets-core.

Calling such a function from inside another worklet that runs on a worklets-core context throws:

Regular javascript function 't' cannot be shared. Try decorating the function with the 'worklet' keyword to allow the javascript function to be used as a worklet.

('t' is just the minified function name in a release bundle.)

We hit this through react-native-filament: EntitySelector's MaterialModifier worklet calls the module-level applyMaterialParameters worklet, which captures nothing, so every model with materialParameters fails on the worklet thread.

Environment

  • react-native: 0.88.0 (New Architecture, Hermes)
  • react-native-worklets-core: 1.6.3
  • react-native-worklets: 0.13.0 (its Babel plugin is active)
  • react-native-filament: 1.9.0 (where we first saw it; 1.11.0 has the same code)
  • Babel plugins:
    plugins: [
      ['react-native-worklets-core/plugin', { processNestedWorklets: true }],
      'react-native-worklets/plugin',
    ]
    

Minimal reproduction

import { Worklets } from 'react-native-worklets-core'

// Captures nothing from the outer scope
const double = (x: number) => {
  'worklet'
  return x * 2
}

const context = Worklets.createContext('repro')

// The worklet passed to runAsync captures `double`
context
  .runAsync(() => {
    'worklet'
    return double(21) // <- throws "Regular javascript function '...' cannot be shared"
  })
  .then(console.log)

If double captures any outer variable (so it gets a __closure), the call works.

What the transpiled code looks like

With the react-native-worklets plugin (0.13.0, and the same in the 0.14 nightlies), a worklet that captures nothing is emitted without __closure, and the hash is a number literal:

var double = function double_Factory([_worklet_123_init_data]) {
  const double = function (x) { return x * 2 }
  double.__workletHash = 123                    // number, not string
  double.__initData = _worklet_123_init_data   // { code: "(function ...)" }
  return double                                // no __closure assignment
}([_worklet_123_init_data])

The plugin only emits __closure when closureVariables.length > 0 (see plugin/index.js), so leaving it out is intended behavior there, not a bug.

Root cause

In cpp/WKTJsiWorklet.h:

  1. isDecoratedAsWorklet() returns true right away only when __workletHash is a string. Otherwise it requires __closure to be present, so a numeric hash with no __closure is treated as a regular function.
  2. createWorklet() returns early when __closure is undefined/null, so even if detection passed, the worklet would not be created.

JsiObjectWrapper::setFunctionValue() then wraps the function in a host function that throws the "cannot be shared" error when called.

Suggested fix

Treat a function as a worklet when __workletHash is a number and __initData.code is a string, and use an empty closure when __closure is missing. Code generated for a worklet with no captures never reads this.__closure, so an empty array is safe.

I have a small patch for this and can open a PR.

Possibly related

#258 reports release builds failing with "is not a Worklet" when the Reanimated plugin and the worklets-core plugin are used together. It might be the same root cause, but I haven't verified that.

主要语言
C++
星标
791
派生
66
PR 合并指标
30 天内没有已合并 PR

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

margelo/react-native-worklets-core 的其他 Issue

查看 margelo/react-native-worklets-core 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。