vite-plugin-rnw 0.0.10 → 0.0.11-next-0

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.
@@ -3,6 +3,6 @@ import { Options } from "@vitejs/plugin-react";
3
3
 
4
4
  //#region src/index.d.ts
5
5
  type RnwOptions = Options;
6
- declare function rnw(opts?: RnwOptions): Plugin[];
6
+ declare function rnw(opts?: RnwOptions): Array<Plugin | Plugin[]>;
7
7
  //#endregion
8
8
  export { RnwOptions, rnw };
@@ -1,13 +1,16 @@
1
1
  import * as vite from "vite";
2
- import { createFilter } from "vite";
3
- import { esbuildFlowPlugin, flowPlugin } from "@bunchtogether/vite-plugin-flow";
2
+ import { createFilter, version } from "vite";
4
3
  import commonjs from "vite-plugin-commonjs";
5
4
  import { makeIdFiltersToMatchWithQuery } from "@rolldown/pluginutils";
6
5
  import MagicString from "magic-string";
7
6
  import react from "@vitejs/plugin-react";
8
-
7
+ import { readFile } from "node:fs/promises";
8
+ import flowRemoveTypes from "flow-remove-types";
9
9
  //#region src/transforms.ts
10
10
  /**
11
+ * Code transformation utilities for fixing React Native package compatibility issues
12
+ */
13
+ /**
11
14
  * Analyzes require statements in code and maps them to module imports.
12
15
  * Handles patterns like: varName = require('path').prop or require('path').default
13
16
  */
@@ -132,9 +135,90 @@ function transformCssInteropDoctorCheck(code, id, opts) {
132
135
  changed: true
133
136
  };
134
137
  }
135
-
138
+ //#endregion
139
+ //#region src/removeFlow.ts
140
+ const defaultFlowOptions = {
141
+ all: false,
142
+ pretty: false,
143
+ ignoreUninitializedFields: false
144
+ };
145
+ const defaultPluginOptions = {
146
+ include: /\.(flow|jsx?)$/,
147
+ exclude: /node_modules/,
148
+ flow: defaultFlowOptions
149
+ };
150
+ const jsxRegex = /\.jsx$/;
151
+ const defaultLoaderFunction = (path) => jsxRegex.test(path) ? "jsx" : "js";
152
+ const toError = (error) => error instanceof Error ? error : new Error(String(error));
153
+ /**
154
+ * Create a Vite plugin object.
155
+ */
156
+ function flowPlugin({ exclude = defaultPluginOptions.exclude, include = defaultPluginOptions.include, flow = defaultFlowOptions } = defaultPluginOptions) {
157
+ const filter = createFilter(include, exclude);
158
+ return {
159
+ enforce: "pre",
160
+ name: "flow",
161
+ transform(src, id) {
162
+ if (!filter(id)) return null;
163
+ return {
164
+ code: flowRemoveTypes(src, flow).toString(),
165
+ map: null
166
+ };
167
+ }
168
+ };
169
+ }
170
+ /**
171
+ * Create an esbuild plugin object.
172
+ */
173
+ function esbuildFlowPlugin(filter = /\.(flow|jsx?)$/, loaderFunction = defaultLoaderFunction, flowOptions = defaultFlowOptions) {
174
+ return {
175
+ name: "flow",
176
+ setup(build) {
177
+ build.onLoad({ filter }, async ({ path, namespace }) => {
178
+ try {
179
+ return {
180
+ contents: flowRemoveTypes(await readFile(path, "utf-8"), flowOptions).toString(),
181
+ loader: loaderFunction(path)
182
+ };
183
+ } catch (error) {
184
+ const resolvedError = toError(error);
185
+ return { errors: [{
186
+ text: resolvedError.message,
187
+ location: {
188
+ file: path,
189
+ namespace
190
+ },
191
+ detail: resolvedError
192
+ }] };
193
+ }
194
+ });
195
+ }
196
+ };
197
+ }
198
+ function rollDownFlowPlugin(filter = /\.(flow|jsx?)$/, loaderFunction = defaultLoaderFunction, flowOptions = defaultFlowOptions) {
199
+ return {
200
+ name: "rolldown-flow",
201
+ load: {
202
+ filter: { id: { include: filter } },
203
+ handler: async (id) => {
204
+ return {
205
+ code: flowRemoveTypes(await readFile(id, "utf-8"), flowOptions).toString(),
206
+ moduleType: loaderFunction(id)
207
+ };
208
+ }
209
+ }
210
+ };
211
+ }
136
212
  //#endregion
137
213
  //#region src/index.ts
214
+ const shouldUseRolldownOptions = () => {
215
+ try {
216
+ return Number(version.split(".")[0]) >= 8;
217
+ } catch {
218
+ return false;
219
+ }
220
+ };
221
+ const shouldUseRollDown = shouldUseRolldownOptions();
138
222
  const extensions = [
139
223
  ".web.mjs",
140
224
  ".web.js",
@@ -160,6 +244,57 @@ const getJsxOption = (jsxRuntime) => {
160
244
  };
161
245
  return jsxRuntime && jsxRuntime in jsxOptionMapping ? jsxOptionMapping[jsxRuntime] : "automatic";
162
246
  };
247
+ const treeshakePlugin = {
248
+ name: "treeshake-fix",
249
+ async transform(_code, id) {
250
+ if (id.includes("react-native-css-interop") || id.includes("react-native-css") || id.includes("expo-modules-core")) return { moduleSideEffects: "no-treeshake" };
251
+ }
252
+ };
253
+ const treeshakeSafePreset = {
254
+ annotations: true,
255
+ invalidImportSideEffects: true,
256
+ manualPureFunctions: [],
257
+ moduleSideEffects: true,
258
+ propertyReadSideEffects: "always",
259
+ unknownGlobalSideEffects: true,
260
+ propertyWriteSideEffects: "always"
261
+ };
262
+ function getBuildOptions() {
263
+ if (shouldUseRollDown) return { rolldownOptions: {
264
+ shimMissingExports: true,
265
+ treeshake: treeshakeSafePreset,
266
+ plugins: [treeshakePlugin]
267
+ } };
268
+ return { rollupOptions: {
269
+ shimMissingExports: true,
270
+ treeshake: treeshakeSafePreset,
271
+ plugins: [treeshakePlugin]
272
+ } };
273
+ }
274
+ function getOptimizeDepsOptions(opts) {
275
+ if (shouldUseRollDown) return { rolldownOptions: {
276
+ resolve: { extensions },
277
+ transform: { jsx: {
278
+ importSource: opts.jsxImportSource,
279
+ runtime: opts.jsxRuntime
280
+ } },
281
+ moduleTypes: {
282
+ ".js": "jsx",
283
+ ".mjs": "jsx"
284
+ },
285
+ plugins: [rollDownFlowPlugin(/* @__PURE__ */ new RegExp(/\.(flow|jsx?)$/), (_path) => "jsx")]
286
+ } };
287
+ return { esbuildOptions: {
288
+ resolveExtensions: extensions,
289
+ jsx: getJsxOption(opts.jsxRuntime),
290
+ jsxImportSource: opts.jsxImportSource,
291
+ loader: {
292
+ ".js": "jsx",
293
+ ".mjs": "jsx"
294
+ },
295
+ plugins: [esbuildFlowPlugin(/* @__PURE__ */ new RegExp(/\.(flow|jsx?)$/), (_path) => "jsx")]
296
+ } };
297
+ }
163
298
  function rnw(opts = {}) {
164
299
  const include = opts.include ?? defaultIncludeRE;
165
300
  const exclude = opts.exclude ?? defaultExcludeRE;
@@ -183,25 +318,8 @@ function rnw(opts = {}) {
183
318
  "process.env.EXPO_OS": JSON.stringify("web"),
184
319
  "global.Error": "Error"
185
320
  },
186
- optimizeDeps: { esbuildOptions: {
187
- resolveExtensions: extensions,
188
- jsx: getJsxOption(opts.jsxRuntime),
189
- jsxImportSource: opts.jsxImportSource,
190
- loader: {
191
- ".js": "jsx",
192
- ".mjs": "jsx"
193
- },
194
- plugins: [esbuildFlowPlugin(/* @__PURE__ */ new RegExp(/\.(flow|jsx?)$/), (_path) => "jsx")]
195
- } },
196
- build: { rollupOptions: {
197
- treeshake: "safest",
198
- plugins: [{
199
- name: "treeshake-fix",
200
- async transform(_code, id) {
201
- if (id.includes("react-native-css-interop") || id.includes("react-native-css") || id.includes("expo-modules-core")) return { moduleSideEffects: "no-treeshake" };
202
- }
203
- }]
204
- } },
321
+ optimizeDeps: getOptimizeDepsOptions(opts),
322
+ build: getBuildOptions(),
205
323
  resolve: {
206
324
  extensions,
207
325
  alias: { "react-native": "react-native-web" }
@@ -240,6 +358,13 @@ function rnw(opts = {}) {
240
358
  async transform(code, id) {
241
359
  if (id.match(/\.js$/) || id.match(/\.mjs$/)) {
242
360
  const jsxOption = getJsxOption(opts.jsxRuntime);
361
+ if (shouldUseRollDown) return vite.transformWithOxc(code, id, {
362
+ lang: "jsx",
363
+ jsx: {
364
+ importSource: opts.jsxImportSource,
365
+ runtime: opts.jsxRuntime
366
+ }
367
+ });
243
368
  return vite.transformWithEsbuild(code, id, {
244
369
  loader: "jsx",
245
370
  jsx: jsxOption,
@@ -257,6 +382,5 @@ function rnw(opts = {}) {
257
382
  })
258
383
  ];
259
384
  }
260
-
261
385
  //#endregion
262
- export { rnw };
386
+ export { rnw };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.10",
2
+ "version": "0.0.11-next-0",
3
3
  "name": "vite-plugin-rnw",
4
4
  "type": "module",
5
5
  "author": "Daniel Williams",
@@ -15,8 +15,13 @@
15
15
  "LICENSE",
16
16
  "README.md"
17
17
  ],
18
+ "types": "./dist/index.d.mts",
18
19
  "exports": {
19
- ".": "./dist/index.js"
20
+ ".": {
21
+ "types": "./dist/index.d.mts",
22
+ "import": "./dist/index.mjs",
23
+ "default": "./dist/index.mjs"
24
+ }
20
25
  },
21
26
  "repository": {
22
27
  "type": "git",
@@ -37,18 +42,19 @@
37
42
  },
38
43
  "devDependencies": {
39
44
  "@types/node": "^22",
40
- "tsdown": "^0.15.12"
45
+ "tsdown": "^0.21.2",
46
+ "vite": "^8.0.0"
41
47
  },
42
48
  "peerDependencies": {
43
49
  "react-native-web": "*",
44
50
  "typescript": "^5",
45
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
51
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
46
52
  },
47
53
  "dependencies": {
48
- "@bunchtogether/vite-plugin-flow": "^1.0.2",
49
- "@rolldown/pluginutils": "1.0.0-beta.46",
50
- "@vitejs/plugin-react": "^5.1.0",
51
- "magic-string": "^0.30.11",
54
+ "flow-remove-types": "^2.305.0",
55
+ "@rolldown/pluginutils": "^1.0.0-rc.9",
56
+ "@vitejs/plugin-react": "^5.2.0",
57
+ "magic-string": "^0.30.21",
52
58
  "vite-plugin-commonjs": "^0.10.4"
53
59
  }
54
60
  }