Skip to content

Commit

Permalink
Add option to substitute isWeb and shouldBeUseWeb in babel plugin. (
Browse files Browse the repository at this point in the history
#5283)

<!-- Thanks for submitting a pull request! We appreciate you spending
the time to work on these changes. Please follow the template so that
the reviewers can easily understand what the code changes affect. -->

## Summary

This PR changes the Babel plugin to substitute `isWeb()` and
`shouldBeUseWeb()` calls with `true` so that Webpack is able to
recognize dead code.

## Test plan
Modify the NextExample/babel.config.js file:
```js
['react-native-reanimated/plugin', { omitNativeOnlyData: true, substituteWebPlatformChecks: true }]
```
Run yarn build in NextExample and verify that the difference between
reanimated and noreanimated is around 34KB.
  • Loading branch information
bartlomiejbloniarz committed Dec 22, 2023
1 parent ea5c667 commit 1932f8d
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 2 deletions.
39 changes: 39 additions & 0 deletions __tests__/__snapshots__/plugin.test.ts.snap
Expand Up @@ -1620,6 +1620,40 @@ function App() {
}"
`;

exports[`babel plugin for web configuration doesn't substitute isWeb and shouldBeUseWeb in worklets 1`] = `
"var _worklet_8641000714901_init_data = {
code: "function foo(){const{isWeb,shouldBeUseWeb}=this.__closure;const x=isWeb();const y=shouldBeUseWeb();}",
location: "/dev/null",
sourceMap: "\\"mock source map\\"",
version: "x.y.z"
};
var foo = function () {
var _e = [new global.Error(), -3, -27];
var foo = function foo() {
var x = true;
var y = true;
};
foo.__closure = {
isWeb: isWeb,
shouldBeUseWeb: shouldBeUseWeb
};
foo.__workletHash = 8641000714901;
foo.__initData = _worklet_8641000714901_init_data;
foo.__stackDetails = _e;
return foo;
}();"
`;

exports[`babel plugin for web configuration doesn't substitute isWeb and shouldBeUseWeb with true when substituteWebPlatformChecks option is set to false 1`] = `
"var x = isWeb();
var y = shouldBeUseWeb();"
`;

exports[`babel plugin for web configuration doesn't substitute isWeb and shouldBeUseWeb with true when substituteWebPlatformChecks option is undefined 1`] = `
"var x = isWeb();
var y = shouldBeUseWeb();"
`;

exports[`babel plugin for web configuration includes initData when omitNativeOnlyData option is set to false 1`] = `
"var _worklet_17472070642672_init_data = {
code: "function foo(){var foo='bar';}",
Expand Down Expand Up @@ -1653,6 +1687,11 @@ exports[`babel plugin for web configuration skips initData when omitNativeOnlyDa
}();"
`;

exports[`babel plugin for web configuration substitutes isWeb and shouldBeUseWeb with true when substituteWebPlatformChecks option is set to true 1`] = `
"var x = true;
var y = true;"
`;

exports[`babel plugin for worklet nesting doesn't process nested worklets when disabled 1`] = `
"var _worklet_1678749606628_init_data = {
code: "function foo(x){function bar(x){'worklet';return x+2;}return bar(x)+1;}",
Expand Down
63 changes: 63 additions & 0 deletions __tests__/plugin.test.ts
Expand Up @@ -1609,5 +1609,68 @@ describe('babel plugin', () => {
expect(code).toHaveWorkletData(1);
expect(code).toMatchSnapshot();
});

it('substitutes isWeb and shouldBeUseWeb with true when substituteWebPlatformChecks option is set to true', () => {
const input = html`<script>
const x = isWeb();
const y = shouldBeUseWeb();
</script>`;

const { code } = runPlugin(
input,
{},
{ substituteWebPlatformChecks: true }
);
expect(code).toContain('var x = true;');
expect(code).toContain('var y = true;');
expect(code).toMatchSnapshot();
});

it("doesn't substitute isWeb and shouldBeUseWeb with true when substituteWebPlatformChecks option is set to false", () => {
const input = html`<script>
const x = isWeb();
const y = shouldBeUseWeb();
</script>`;

const { code } = runPlugin(
input,
{},
{ substituteWebPlatformChecks: false }
);
expect(code).toContain('var x = isWeb();');
expect(code).toContain('var y = shouldBeUseWeb();');
expect(code).toMatchSnapshot();
});

it("doesn't substitute isWeb and shouldBeUseWeb with true when substituteWebPlatformChecks option is undefined", () => {
const input = html`<script>
const x = isWeb();
const y = shouldBeUseWeb();
</script>`;

const { code } = runPlugin(input);
expect(code).toContain('var x = isWeb();');
expect(code).toContain('var y = shouldBeUseWeb();');
expect(code).toMatchSnapshot();
});

it("doesn't substitute isWeb and shouldBeUseWeb in worklets", () => {
const input = html`<script>
function foo() {
'worklet';
const x = isWeb();
const y = shouldBeUseWeb();
}
</script>`;

const { code } = runPlugin(
input,
{},
{ substituteWebPlatformChecks: true }
);
expect(code).toContain('const x=isWeb();');
expect(code).toContain('const y=shouldBeUseWeb();');
expect(code).toMatchSnapshot();
});
});
});
28 changes: 27 additions & 1 deletion plugin/build/plugin.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion plugin/src/plugin.ts
Expand Up @@ -7,6 +7,7 @@ import { processInlineStylesWarning } from './processInlineStylesWarning';
import { processIfCallback } from './processIfCallback';
import { addCustomGlobals } from './addCustomGlobals';
import { initializeGlobals } from './globals';
import { substituteWebCallExpression } from './substituteWebCallExpression';

module.exports = function (): PluginItem {
function runWithTaggedExceptions(fun: () => void) {
Expand All @@ -27,7 +28,12 @@ module.exports = function (): PluginItem {
visitor: {
CallExpression: {
enter(path: NodePath<CallExpression>, state: ReanimatedPluginPass) {
runWithTaggedExceptions(() => processForCalleesWorklets(path, state));
runWithTaggedExceptions(() => {
processForCalleesWorklets(path, state);
if (state.opts.substituteWebPlatformChecks) {
substituteWebCallExpression(path);
}
});
},
},
'FunctionDeclaration|FunctionExpression|ArrowFunctionExpression': {
Expand Down
13 changes: 13 additions & 0 deletions plugin/src/substituteWebCallExpression.ts
@@ -0,0 +1,13 @@
import type { NodePath } from '@babel/core';
import { booleanLiteral, isIdentifier } from '@babel/types';
import type { CallExpression } from '@babel/types';

export function substituteWebCallExpression(path: NodePath<CallExpression>) {
const callee = path.node.callee;
if (isIdentifier(callee)) {
const name = callee.name;
if (name === 'isWeb' || name === 'shouldBeUseWeb') {
path.replaceWith(booleanLiteral(true));
}
}
}
1 change: 1 addition & 0 deletions plugin/src/types.ts
Expand Up @@ -12,6 +12,7 @@ export interface ReanimatedPluginOptions {
processNestedWorklets?: boolean;
omitNativeOnlyData?: boolean;
globals?: string[];
substituteWebPlatformChecks?: boolean;
}

export interface ReanimatedPluginPass {
Expand Down

0 comments on commit 1932f8d

Please sign in to comment.