Skip to content

Commit 63feb1f

Browse files
authored
fix: Allow TypeScript in worklet classes (software-mansion#6667)
## Summary Turns out `@babel/preset-typescript` always has to be included when calling `transformSync` from `babel` (it cannot be included in a later call). Due to that I made all `transformSync` calls into a wrapper call that uses a required set of plugins and presets. Fixes - software-mansion#6642 ## Test plan - [x] Plugin unit tests pass - [x] Runtime tests pass
1 parent f9650e1 commit 63feb1f

File tree

5 files changed

+55
-30
lines changed

5 files changed

+55
-30
lines changed

plugin/index.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/src/class.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { NodePath } from '@babel/core';
2-
import { transformSync } from '@babel/core';
32
import generate from '@babel/generator';
43
import traverse from '@babel/traverse';
54
import type {
@@ -36,6 +35,7 @@ import { strict as assert } from 'assert';
3635
import type { ReanimatedPluginPass } from './types';
3736
import { workletClassFactorySuffix } from './types';
3837
import { replaceWithFactoryCall } from './utils';
38+
import { workletTransformSync } from './transform';
3939

4040
const classWorkletMarker = '__workletClass';
4141

@@ -96,8 +96,8 @@ function getPolyfilledAst(
9696
) {
9797
const classCode = generate(classNode).code;
9898

99-
const classWithPolyfills = transformSync(classCode, {
100-
plugins: [
99+
const classWithPolyfills = workletTransformSync(classCode, {
100+
extraPlugins: [
101101
'@babel/plugin-transform-class-properties',
102102
'@babel/plugin-transform-classes',
103103
'@babel/plugin-transform-unicode-regex',

plugin/src/transform.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { transformSync } from '@babel/core';
2+
import type { PluginItem, TransformOptions } from '@babel/core';
3+
4+
export function workletTransformSync(
5+
code: string,
6+
opts: WorkletTransformOptions
7+
) {
8+
const { extraPlugins = [], extraPresets = [], ...rest } = opts;
9+
10+
return transformSync(code, {
11+
...rest,
12+
plugins: [...defaultPlugins, ...extraPlugins],
13+
presets: [...defaultPresets, ...extraPresets],
14+
});
15+
}
16+
17+
const defaultPresets: PluginItem[] = [
18+
require.resolve('@babel/preset-typescript'),
19+
];
20+
21+
const defaultPlugins: PluginItem[] = [];
22+
23+
interface WorkletTransformOptions
24+
extends Omit<TransformOptions, 'plugins' | 'presets'> {
25+
extraPlugins?: PluginItem[];
26+
extraPresets?: PluginItem[];
27+
filename: TransformOptions['filename'];
28+
}

plugin/src/workletFactory.ts

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-var-requires */
22
import type { NodePath } from '@babel/core';
3-
import { transformSync, traverse } from '@babel/core';
3+
import { traverse } from '@babel/core';
44
import generate from '@babel/generator';
55
import type {
66
File as BabelFile,
@@ -44,25 +44,11 @@ import type { ReanimatedPluginPass, WorkletizableFunction } from './types';
4444
import { workletClassFactorySuffix } from './types';
4545
import { isRelease } from './utils';
4646
import { buildWorkletString } from './workletStringCode';
47+
import { workletTransformSync } from './transform';
4748

4849
const REAL_VERSION = require('../../package.json').version;
4950
const MOCK_VERSION = 'x.y.z';
5051

51-
const workletStringTransformPresets = [
52-
require.resolve('@babel/preset-typescript'),
53-
];
54-
55-
const workletStringTransformPlugins = [
56-
require.resolve('@babel/plugin-transform-shorthand-properties'),
57-
require.resolve('@babel/plugin-transform-arrow-functions'),
58-
require.resolve('@babel/plugin-transform-optional-chaining'),
59-
require.resolve('@babel/plugin-transform-nullish-coalescing-operator'),
60-
[
61-
require.resolve('@babel/plugin-transform-template-literals'),
62-
{ loose: true },
63-
],
64-
];
65-
6652
export function makeWorkletFactory(
6753
fun: NodePath<WorkletizableFunction>,
6854
state: ReanimatedPluginPass
@@ -91,10 +77,9 @@ export function makeWorkletFactory(
9177
codeObject.code =
9278
'(' + (fun.isObjectMethod() ? 'function ' : '') + codeObject.code + '\n)';
9379

94-
const transformed = transformSync(codeObject.code, {
80+
const transformed = workletTransformSync(codeObject.code, {
81+
extraPlugins,
9582
filename: state.file.opts.filename,
96-
presets: workletStringTransformPresets,
97-
plugins: workletStringTransformPlugins,
9883
ast: true,
9984
babelrc: false,
10085
configFile: false,
@@ -469,3 +454,14 @@ function makeArrayFromCapturedBindings(
469454

470455
return Array.from(closure.values());
471456
}
457+
458+
const extraPlugins = [
459+
require.resolve('@babel/plugin-transform-shorthand-properties'),
460+
require.resolve('@babel/plugin-transform-arrow-functions'),
461+
require.resolve('@babel/plugin-transform-optional-chaining'),
462+
require.resolve('@babel/plugin-transform-nullish-coalescing-operator'),
463+
[
464+
require.resolve('@babel/plugin-transform-template-literals'),
465+
{ loose: true },
466+
],
467+
];

plugin/src/workletStringCode.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { BabelFileResult, NodePath, PluginItem } from '@babel/core';
2-
import { transformSync, traverse } from '@babel/core';
2+
import { traverse } from '@babel/core';
33
import generate from '@babel/generator';
44
import type {
55
File as BabelFile,
@@ -34,6 +34,7 @@ import * as fs from 'fs';
3434
import type { ReanimatedPluginPass, WorkletizableFunction } from './types';
3535
import { workletClassFactorySuffix } from './types';
3636
import { isRelease } from './utils';
37+
import { workletTransformSync } from './transform';
3738

3839
const MOCK_SOURCE_MAP = 'mock source map';
3940

@@ -130,8 +131,9 @@ export function buildWorkletString(
130131
}
131132
}
132133

133-
const transformed = transformSync(code, {
134-
plugins: [prependClosureVariablesIfNecessary(closureVariables)],
134+
const transformed = workletTransformSync(code, {
135+
filename: state.file.opts.filename,
136+
extraPlugins: [getClosurePlugin(closureVariables)],
135137
compact: true,
136138
sourceMaps: includeSourceMap,
137139
inputSourceMap: inputMap,
@@ -222,9 +224,8 @@ function prependRecursiveDeclaration(path: NodePath<WorkletizableFunction>) {
222224
}
223225
}
224226

225-
function prependClosureVariablesIfNecessary(
226-
closureVariables: Array<Identifier>
227-
): PluginItem {
227+
/** Prepends necessary closure variables to the worklet function. */
228+
function getClosurePlugin(closureVariables: Array<Identifier>): PluginItem {
228229
const closureDeclaration = variableDeclaration('const', [
229230
variableDeclarator(
230231
objectPattern(

0 commit comments

Comments
 (0)