react-native-boost 0.0.2 โ†’ 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,8 +1,17 @@
1
1
  {
2
2
  "name": "react-native-boost",
3
3
  "description": "๐Ÿš€ Boost your React Native app's performance with a single line of code",
4
- "version": "0.0.2",
4
+ "version": "0.0.3",
5
5
  "main": "dist/plugin.js",
6
+ "keywords": [
7
+ "react-native",
8
+ "ios",
9
+ "android",
10
+ "performance",
11
+ "optimization",
12
+ "bundle",
13
+ "optimize"
14
+ ],
6
15
  "scripts": {
7
16
  "clean": "rm -rf plugin",
8
17
  "build": "yarn clean && esbuild src/plugin.ts --bundle --outfile=plugin/index.js --platform=node",
@@ -10,7 +19,6 @@
10
19
  "typecheck": "tsc --noEmit",
11
20
  "lint": "eslint src/**/*.ts",
12
21
  "format": "prettier --write .",
13
- "prepare": "husky",
14
22
  "release": "release-it"
15
23
  },
16
24
  "files": [
@@ -35,32 +43,35 @@
35
43
  "publishConfig": {
36
44
  "registry": "https://registry.npmjs.org"
37
45
  },
38
- "devDependencies": {
46
+ "dependencies": {
39
47
  "@babel/core": "^7.25.0",
40
48
  "@babel/helper-module-imports": "^7.25.0",
41
- "@babel/helper-plugin-utils": "^7.25.0",
49
+ "@babel/helper-plugin-utils": "^7.25.0"
50
+ },
51
+ "devDependencies": {
42
52
  "@babel/plugin-syntax-jsx": "^7.25.0",
43
53
  "@babel/preset-typescript": "^7.25.0",
44
- "@commitlint/cli": "^19.7.1",
45
- "@commitlint/config-conventional": "^17.0.2",
46
- "@eslint/js": "^9.21.0",
47
54
  "@release-it/conventional-changelog": "^10.0.0",
48
55
  "@types/babel__helper-module-imports": "^7.0.0",
49
56
  "@types/babel__helper-plugin-utils": "^7.0.0",
50
57
  "@types/node": "^20",
51
58
  "babel-plugin-tester": "^11.0.4",
52
59
  "esbuild": "^0.25.0",
53
- "eslint": "^9.21.0",
54
- "eslint-plugin-unicorn": "^57.0.0",
55
60
  "globals": "^16.0.0",
56
- "husky": "^9.1.7",
57
- "lint-staged": "^15.4.3",
58
- "prettier": "^3.5.2",
59
61
  "release-it": "^18.1.2",
60
62
  "typescript": "^5.7.3",
61
- "typescript-eslint": "^8.24.1",
62
63
  "vitest": "^3.0.6"
63
64
  },
65
+ "peerDependencies": {
66
+ "expo": "*",
67
+ "react": "*",
68
+ "react-native": "*"
69
+ },
70
+ "peerDependenciesMeta": {
71
+ "expo": {
72
+ "optional": true
73
+ }
74
+ },
64
75
  "release-it": {
65
76
  "git": {
66
77
  "commitMessage": "chore: release ${version}",
package/plugin/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -32250,9 +32251,9 @@ var require_browser = __commonJS({
32250
32251
  }
32251
32252
  });
32252
32253
 
32253
- // node_modules/has-flag/index.js
32254
+ // ../../node_modules/has-flag/index.js
32254
32255
  var require_has_flag = __commonJS({
32255
- "node_modules/has-flag/index.js"(exports2, module2) {
32256
+ "../../node_modules/has-flag/index.js"(exports2, module2) {
32256
32257
  "use strict";
32257
32258
  module2.exports = (flag, argv = process.argv) => {
32258
32259
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
@@ -32263,9 +32264,9 @@ var require_has_flag = __commonJS({
32263
32264
  }
32264
32265
  });
32265
32266
 
32266
- // node_modules/supports-color/index.js
32267
+ // ../../node_modules/supports-color/index.js
32267
32268
  var require_supports_color = __commonJS({
32268
- "node_modules/supports-color/index.js"(exports2, module2) {
32269
+ "../../node_modules/supports-color/index.js"(exports2, module2) {
32269
32270
  "use strict";
32270
32271
  var os = require("os");
32271
32272
  var tty = require("tty");
@@ -32371,7 +32372,7 @@ var require_node = __commonJS({
32371
32372
  var tty = require("tty");
32372
32373
  var util = require("util");
32373
32374
  exports2.init = init;
32374
- exports2.log = log;
32375
+ exports2.log = log2;
32375
32376
  exports2.formatArgs = formatArgs;
32376
32377
  exports2.save = save;
32377
32378
  exports2.load = load;
@@ -32506,7 +32507,7 @@ var require_node = __commonJS({
32506
32507
  }
32507
32508
  return (/* @__PURE__ */ new Date()).toISOString() + " ";
32508
32509
  }
32509
- function log(...args) {
32510
+ function log2(...args) {
32510
32511
  return process.stderr.write(util.formatWithOptions(exports2.inspectOpts, ...args) + "\n");
32511
32512
  }
32512
32513
  function save(namespaces) {
@@ -70363,7 +70364,18 @@ var import_helper_plugin_utils = __toESM(require_lib());
70363
70364
  // src/optimizers/text/index.ts
70364
70365
  var import_core = __toESM(require_lib27());
70365
70366
  var import_helper_module_imports = __toESM(require_lib11());
70366
- var textOptimizer = (path) => {
70367
+
70368
+ // src/utils/plugin-error.ts
70369
+ var PluginError = class extends Error {
70370
+ constructor(message) {
70371
+ super(`[react-native-boost] Babel plugin exception: ${message}`);
70372
+ this.name = "PluginError";
70373
+ }
70374
+ };
70375
+
70376
+ // src/optimizers/text/index.ts
70377
+ var textOptimizer = (path, log2 = () => {
70378
+ }) => {
70367
70379
  if (!import_core.types.isJSXIdentifier(path.node.name)) return;
70368
70380
  const parent = path.parent;
70369
70381
  if (!import_core.types.isJSXElement(parent)) return;
@@ -70379,7 +70391,16 @@ var textOptimizer = (path) => {
70379
70391
  }
70380
70392
  if (hasBlacklistedProperties(path)) return;
70381
70393
  if (!hasOnlyStringChildren(path, parent)) return;
70382
- const file = path.hub.file;
70394
+ const hub = path.hub;
70395
+ const file = typeof hub === "object" && hub !== null && "file" in hub ? hub.file : void 0;
70396
+ if (!file) {
70397
+ throw new PluginError("No file found in Babel hub");
70398
+ }
70399
+ if (!file.__optimized) {
70400
+ const filename = file.opts?.filename || "unknown file";
70401
+ log2(`Optimizing file: ${filename}`);
70402
+ file.__optimized = true;
70403
+ }
70383
70404
  if (!file.__nativeTextImport) {
70384
70405
  file.__nativeTextImport = (0, import_helper_module_imports.addNamed)(path, "NativeText", "react-native/Libraries/Text/TextNativeComponent");
70385
70406
  }
@@ -70465,6 +70486,11 @@ function hasBlacklistedProperties(path) {
70465
70486
  });
70466
70487
  }
70467
70488
 
70489
+ // src/utils/logger.ts
70490
+ var log = (message) => {
70491
+ console.log(`[react-native-boost] ${message}`);
70492
+ };
70493
+
70468
70494
  // src/plugin.ts
70469
70495
  var plugin_default = (0, import_helper_plugin_utils.declare)((api) => {
70470
70496
  api.assertVersion(7);
@@ -70473,7 +70499,9 @@ var plugin_default = (0, import_helper_plugin_utils.declare)((api) => {
70473
70499
  visitor: {
70474
70500
  JSXOpeningElement(path, state) {
70475
70501
  const options = state.opts ?? {};
70476
- if (options.optimizations?.text !== false) textOptimizer(path);
70502
+ const logger = options.verbose ? log : () => {
70503
+ };
70504
+ if (options.optimizations?.text !== false) textOptimizer(path, logger);
70477
70505
  }
70478
70506
  }
70479
70507
  };
@@ -1,8 +1,9 @@
1
1
  import { NodePath, types as t } from '@babel/core';
2
2
  import { addNamed } from '@babel/helper-module-imports';
3
- import { Optimizer } from '../../types';
3
+ import { HubFile, Optimizer } from '../../types';
4
+ import PluginError from '../../utils/plugin-error';
4
5
 
5
- export const textOptimizer: Optimizer = (path) => {
6
+ export const textOptimizer: Optimizer = (path, log = () => {}) => {
6
7
  // Ensure we're processing a JSX Text element
7
8
  if (!t.isJSXIdentifier(path.node.name)) return;
8
9
 
@@ -27,10 +28,22 @@ export const textOptimizer: Optimizer = (path) => {
27
28
  if (!hasOnlyStringChildren(path, parent)) return;
28
29
  // TODO: Don't bail if the element has a style prop
29
30
 
30
- // Add NativeTextComponent import (cached on file) so we only add it once per file
31
- const file = (path.hub as unknown as { file: t.File }).file as t.File & {
32
- __nativeTextImport?: t.Identifier;
33
- };
31
+ // Extract the file from the Babel hub and add flags for logging & import caching
32
+ const hub = path.hub as unknown;
33
+ const file = typeof hub === 'object' && hub !== null && 'file' in hub ? (hub.file as HubFile) : undefined;
34
+
35
+ if (!file) {
36
+ throw new PluginError('No file found in Babel hub');
37
+ }
38
+
39
+ // Log the file's optimized status only once
40
+ if (!file.__optimized) {
41
+ const filename = file.opts?.filename || 'unknown file';
42
+ log(`Optimizing file: ${filename}`);
43
+ file.__optimized = true;
44
+ }
45
+
46
+ // Add TextNativeComponent import (cached on file) so we only add it once per file
34
47
  if (!file.__nativeTextImport) {
35
48
  file.__nativeTextImport = addNamed(path, 'NativeText', 'react-native/Libraries/Text/TextNativeComponent');
36
49
  }
@@ -105,7 +118,7 @@ function hasBlacklistedProperties(path: NodePath<t.JSXOpeningElement>): boolean
105
118
  const binding = path.scope.getBinding(attribute.argument.name);
106
119
  let objectExpression: t.ObjectExpression | undefined;
107
120
  if (binding) {
108
- // If the binding node is a VariableDeclarator, use its initializer.
121
+ // If the binding node is a VariableDeclarator, use its initializer
109
122
  if (t.isVariableDeclarator(binding.path.node)) {
110
123
  objectExpression = binding.path.node.init as t.ObjectExpression;
111
124
  } else if (t.isObjectExpression(binding.path.node)) {
package/src/plugin.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { declare } from '@babel/helper-plugin-utils';
2
2
  import { textOptimizer } from './optimizers/text';
3
3
  import { PluginOptions } from './types';
4
+ import { log } from './utils/logger';
4
5
 
5
6
  export default declare((api) => {
6
7
  api.assertVersion(7);
@@ -10,7 +11,8 @@ export default declare((api) => {
10
11
  visitor: {
11
12
  JSXOpeningElement(path, state) {
12
13
  const options = (state.opts ?? {}) as PluginOptions;
13
- if (options.optimizations?.text !== false) textOptimizer(path);
14
+ const logger = options.verbose ? log : () => {};
15
+ if (options.optimizations?.text !== false) textOptimizer(path, logger);
14
16
  },
15
17
  },
16
18
  };
@@ -1,9 +1,29 @@
1
1
  import { NodePath, types as t } from '@babel/core';
2
2
 
3
3
  export interface PluginOptions {
4
+ /**
5
+ * Whether or not to log optimized files to the console.
6
+ * @default false
7
+ */
8
+ verbose?: boolean;
9
+ /**
10
+ * The optimizations to apply to the plugin.
11
+ */
4
12
  optimizations?: {
13
+ /**
14
+ * Whether or not to optimize the text component.
15
+ * @default true
16
+ */
5
17
  text?: boolean;
6
18
  };
7
19
  }
8
20
 
9
- export type Optimizer = (path: NodePath<t.JSXOpeningElement>) => void;
21
+ export type Optimizer = (path: NodePath<t.JSXOpeningElement>, log?: (message: string) => void) => void;
22
+
23
+ export type HubFile = t.File & {
24
+ opts: {
25
+ filename: string;
26
+ };
27
+ __nativeTextImport?: t.Identifier;
28
+ __optimized?: boolean;
29
+ };
@@ -0,0 +1,3 @@
1
+ export const log = (message: string) => {
2
+ console.log(`[react-native-boost] ${message}`);
3
+ };
@@ -0,0 +1,6 @@
1
+ export default class PluginError extends Error {
2
+ constructor(message: string) {
3
+ super(`[react-native-boost] Babel plugin exception: ${message}`);
4
+ this.name = 'PluginError';
5
+ }
6
+ }
package/README.md DELETED
@@ -1,87 +0,0 @@
1
- # ๐Ÿš€ react-native-boost
2
-
3
- ![npm bundle size](https://img.shields.io/bundlephobia/min/react-native-boost?style=flat-square) ![GitHub](https://img.shields.io/github/license/kuatsu/react-native-boost?style=flat-square) ![GitHub last commit](https://img.shields.io/github/last-commit/kuatsu/react-native-boost?style=flat-square)
4
-
5
- A powerful Babel plugin that automatically optimizes React Native apps through source code analysis and optimization. It identifies safe micro-optimization opportunities, which can lead to significant performance improvements.
6
-
7
- > [!WARNING]
8
- > This project is highly experimental and under active development. **Your app might break** and the optimization strategies used can change significantly between versions. Use with caution!
9
-
10
- - โšก Automatic performance optimization through source code analysis
11
- - ๐Ÿ”’ Safe optimizations that don't break your app
12
- - ๐ŸŽฏ Zero runtime overhead - all optimizations happen during build time
13
- - ๐Ÿ“ฑ Cross-platform compatible
14
- - ๐Ÿงช Works seamlessly with Expo
15
- - ๐ŸŽจ Configurable optimization strategies
16
-
17
- ## Installation
18
-
19
- ```sh
20
- npm install --save-dev react-native-boost
21
- # or
22
- yarn add --dev react-native-boost
23
- ```
24
-
25
- Then, add the plugin to your Babel configuration (`babel.config.js`):
26
-
27
- ```js
28
- module.exports = {
29
- plugins: ['react-native-boost/plugin'],
30
- };
31
- ```
32
-
33
- Optionally, you can configure the plugin to disable specific optimizations:
34
-
35
- ```js
36
- module.exports = {
37
- plugins: [
38
- [
39
- 'react-native-boost/plugin',
40
- {
41
- optimizations: {
42
- text: false,
43
- },
44
- },
45
- ],
46
- ],
47
- };
48
- ```
49
-
50
- ## How It Works
51
-
52
- Several standard components in React Native are actually wrappers around their native counterparts. These wrappers often only handle edge cases and aren't needed in most cases. However, they add additional runtime overhead and depth to the component tree, which can lead to performance bottlenecks.
53
-
54
- React Native Boost replaces these wrapper components directly with their respective native components, flattening the component tree. It intelligently analyzes your code and only optimizes components that are used in a way where they can be optimized without breaking the app.
55
-
56
- Here's an example of how it works:
57
-
58
- ```jsx
59
- // Your original code ๐ŸŒ
60
- import React from 'react';
61
- import { View, Text } from 'react-native';
62
-
63
- const MyComponent = () => (
64
- <View>
65
- <Text>Hello, World!</Text>
66
- </View>
67
- );
68
-
69
- // Automafically transformed to โœจ
70
- import React from 'react';
71
- import { View } from 'react-native';
72
- import { NativeText } from 'react-native/Libraries/Components/Text/NativeText';
73
-
74
- const MyComponent = () => (
75
- <View>
76
- <NativeText>Hello, World!</NativeText>
77
- </View>
78
- );
79
- ```
80
-
81
- ## Contributing
82
-
83
- See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
84
-
85
- ## License
86
-
87
- MIT