vite-plugin-rnw 0.0.4 → 0.0.6
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/dist/index.cjs +80 -12
- package/dist/index.js +80 -12
- package/package.json +6 -2
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,7 @@ const node_path = __toESM(require("node:path"));
|
|
|
25
25
|
const node_url = __toESM(require("node:url"));
|
|
26
26
|
const node_fs = __toESM(require("node:fs"));
|
|
27
27
|
const vite = __toESM(require("vite"));
|
|
28
|
+
const __bunchtogether_vite_plugin_flow = __toESM(require("@bunchtogether/vite-plugin-flow"));
|
|
28
29
|
const vite_plugin_commonjs = __toESM(require("vite-plugin-commonjs"));
|
|
29
30
|
const __rolldown_pluginutils = __toESM(require("@rolldown/pluginutils"));
|
|
30
31
|
|
|
@@ -103,6 +104,70 @@ function removeLineBreaksIfNeeded(code, enabled) {
|
|
|
103
104
|
return enabled ? code.replace(/\n/g, "") : code;
|
|
104
105
|
}
|
|
105
106
|
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/transforms.ts
|
|
109
|
+
/**
|
|
110
|
+
* Code transformation utilities for fixing React Native package compatibility issues
|
|
111
|
+
*/
|
|
112
|
+
/**
|
|
113
|
+
* Analyzes require statements in code and maps them to module imports.
|
|
114
|
+
* Handles patterns like: varName = require('path').prop or require('path').default
|
|
115
|
+
*/
|
|
116
|
+
function analyzeRequireStatements(originalCode, exportedVars) {
|
|
117
|
+
const importMap = /* @__PURE__ */ new Map();
|
|
118
|
+
for (const varName of exportedVars) {
|
|
119
|
+
const requirePattern = new RegExp(`${varName}\\s*=\\s*[\\s\\S]*?require\\(['"]([^'"]+)['"]\\)(?:\\.([\\w]+))?`, "g");
|
|
120
|
+
const requireMatch = requirePattern.exec(originalCode);
|
|
121
|
+
if (requireMatch) {
|
|
122
|
+
const [, modulePath, prop] = requireMatch;
|
|
123
|
+
const key = `${modulePath}:${prop || "default"}`;
|
|
124
|
+
if (!importMap.has(key)) importMap.set(key, []);
|
|
125
|
+
importMap.get(key).push(varName);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return importMap;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Removes try/catch blocks that contain require statements and export let declarations.
|
|
132
|
+
* This cleans up the problematic CommonJS patterns.
|
|
133
|
+
*/
|
|
134
|
+
function removeTryCatchRequireBlocks(code) {
|
|
135
|
+
let transformed = code.replace(/try\s*\{[^{}]*?require\([^)]+\)[^{}]*?\}\s*catch[^{}]*?\{[^{}]*?\}/gs, "");
|
|
136
|
+
transformed = transformed.replace(/export let \w+;/g, "");
|
|
137
|
+
return transformed;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Generates direct export statements from the import map.
|
|
141
|
+
* Creates modern ESM exports like: export { default as varName } from 'module';
|
|
142
|
+
*/
|
|
143
|
+
function generateDirectExports(importMap) {
|
|
144
|
+
let exports$1 = "";
|
|
145
|
+
for (const [key, vars] of importMap) {
|
|
146
|
+
const [modulePath, prop] = key.split(":");
|
|
147
|
+
if (prop === "default") for (const varName of vars) exports$1 += `export { default as ${varName} } from '${modulePath}';\n`;
|
|
148
|
+
else for (const varName of vars) exports$1 += `export { ${prop} as ${varName} } from '${modulePath}';\n`;
|
|
149
|
+
}
|
|
150
|
+
return exports$1;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Transforms React Native Reanimated webUtils files to fix problematic
|
|
154
|
+
* export let + try/catch + require patterns by converting them to proper ESM.
|
|
155
|
+
*
|
|
156
|
+
* This transformation handles the incompatible module patterns in React Native Reanimated
|
|
157
|
+
* that cause build errors in Vite due to mixing CommonJS require() with ESM exports.
|
|
158
|
+
*/
|
|
159
|
+
function transformReanimatedWebUtils(toTransform, originalCode, id, isProduction) {
|
|
160
|
+
if (!isProduction || !id.includes("node_modules/react-native-reanimated") || !id.includes("ReanimatedModule/js-reanimated/webUtils") || !originalCode.includes("export let") || !originalCode.includes("try") || !originalCode.includes("require")) return toTransform;
|
|
161
|
+
const exportLetMatches = Array.from(originalCode.matchAll(/export let (\w+);/g));
|
|
162
|
+
const exportedVars = exportLetMatches.map((match) => match[1]);
|
|
163
|
+
if (exportedVars.length === 0) return toTransform;
|
|
164
|
+
const importMap = analyzeRequireStatements(originalCode, exportedVars);
|
|
165
|
+
toTransform = removeTryCatchRequireBlocks(toTransform);
|
|
166
|
+
const exports$1 = generateDirectExports(importMap);
|
|
167
|
+
if (exports$1) toTransform = `${toTransform}\n${exports$1}`;
|
|
168
|
+
return toTransform;
|
|
169
|
+
}
|
|
170
|
+
|
|
106
171
|
//#endregion
|
|
107
172
|
//#region src/index.ts
|
|
108
173
|
const silenceUseClientWarning = (userConfig) => ({ rollupOptions: { onwarn(warning, defaultHandler) {
|
|
@@ -182,17 +247,28 @@ function rnw(opts = {}) {
|
|
|
182
247
|
_WORKLET: false,
|
|
183
248
|
__DEV__: JSON.stringify(development),
|
|
184
249
|
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || env.mode),
|
|
250
|
+
EXPO_OS: JSON.stringify("web"),
|
|
251
|
+
"process.env.EXPO_OS": JSON.stringify("web"),
|
|
185
252
|
"global.Error": "Error"
|
|
186
253
|
},
|
|
187
254
|
optimizeDeps: {
|
|
188
255
|
...initialOptions.optimizeDeps,
|
|
189
|
-
include: ["react-native-reanimated"],
|
|
190
256
|
esbuildOptions: {
|
|
191
257
|
...(_initialOptions$optim = initialOptions.optimizeDeps) === null || _initialOptions$optim === void 0 ? void 0 : _initialOptions$optim.esbuildOptions,
|
|
192
258
|
resolveExtensions: extensions,
|
|
193
|
-
loader: { ".js": "jsx" }
|
|
259
|
+
loader: { ".js": "jsx" },
|
|
260
|
+
plugins: [(0, __bunchtogether_vite_plugin_flow.esbuildFlowPlugin)(/* @__PURE__ */ new RegExp(/\.(flow|jsx?)$/), (_path) => "jsx")]
|
|
194
261
|
}
|
|
195
262
|
},
|
|
263
|
+
build: { rollupOptions: {
|
|
264
|
+
treeshake: "safest",
|
|
265
|
+
plugins: [{
|
|
266
|
+
name: "nativewind-fix",
|
|
267
|
+
async transform(code, id) {
|
|
268
|
+
if (id.includes("react-native-css-interop")) return { moduleSideEffects: "no-treeshake" };
|
|
269
|
+
}
|
|
270
|
+
}]
|
|
271
|
+
} },
|
|
196
272
|
resolve: {
|
|
197
273
|
extensions,
|
|
198
274
|
alias: { "react-native": "react-native-web" }
|
|
@@ -253,16 +329,7 @@ function rnw(opts = {}) {
|
|
|
253
329
|
if (tsRE.test(filepath)) parserPlugins.push("typescript");
|
|
254
330
|
const babel$1 = await loadBabel();
|
|
255
331
|
let toTransform = code;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
import createReactDOMStyle from 'react-native-web/dist/exports/StyleSheet/compiler/createReactDOMStyle';
|
|
259
|
-
import {
|
|
260
|
-
createTextShadowValue,
|
|
261
|
-
createTransformValue,
|
|
262
|
-
} from 'react-native-web/dist/exports/StyleSheet/preprocess';
|
|
263
|
-
|
|
264
|
-
export { createReactDOMStyle, createTextShadowValue, createTransformValue };
|
|
265
|
-
`;
|
|
332
|
+
toTransform = transformReanimatedWebUtils(toTransform, code, id, isProduction);
|
|
266
333
|
const result = await babel$1.transformAsync(toTransform, {
|
|
267
334
|
...babelOptions,
|
|
268
335
|
root: projectRoot,
|
|
@@ -334,6 +401,7 @@ function rnw(opts = {}) {
|
|
|
334
401
|
}
|
|
335
402
|
};
|
|
336
403
|
return [
|
|
404
|
+
(0, __bunchtogether_vite_plugin_flow.flowPlugin)({ exclude }),
|
|
337
405
|
{
|
|
338
406
|
name: "treat-js-files-as-jsx",
|
|
339
407
|
async transform(code, id) {
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { fileURLToPath } from "node:url";
|
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import * as vite from "vite";
|
|
5
5
|
import { createFilter } from "vite";
|
|
6
|
+
import { esbuildFlowPlugin, flowPlugin } from "@bunchtogether/vite-plugin-flow";
|
|
6
7
|
import commonjs from "vite-plugin-commonjs";
|
|
7
8
|
import { exactRegex, makeIdFiltersToMatchWithQuery } from "@rolldown/pluginutils";
|
|
8
9
|
|
|
@@ -81,6 +82,70 @@ function removeLineBreaksIfNeeded(code, enabled) {
|
|
|
81
82
|
return enabled ? code.replace(/\n/g, "") : code;
|
|
82
83
|
}
|
|
83
84
|
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/transforms.ts
|
|
87
|
+
/**
|
|
88
|
+
* Code transformation utilities for fixing React Native package compatibility issues
|
|
89
|
+
*/
|
|
90
|
+
/**
|
|
91
|
+
* Analyzes require statements in code and maps them to module imports.
|
|
92
|
+
* Handles patterns like: varName = require('path').prop or require('path').default
|
|
93
|
+
*/
|
|
94
|
+
function analyzeRequireStatements(originalCode, exportedVars) {
|
|
95
|
+
const importMap = /* @__PURE__ */ new Map();
|
|
96
|
+
for (const varName of exportedVars) {
|
|
97
|
+
const requirePattern = new RegExp(`${varName}\\s*=\\s*[\\s\\S]*?require\\(['"]([^'"]+)['"]\\)(?:\\.([\\w]+))?`, "g");
|
|
98
|
+
const requireMatch = requirePattern.exec(originalCode);
|
|
99
|
+
if (requireMatch) {
|
|
100
|
+
const [, modulePath, prop] = requireMatch;
|
|
101
|
+
const key = `${modulePath}:${prop || "default"}`;
|
|
102
|
+
if (!importMap.has(key)) importMap.set(key, []);
|
|
103
|
+
importMap.get(key).push(varName);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return importMap;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Removes try/catch blocks that contain require statements and export let declarations.
|
|
110
|
+
* This cleans up the problematic CommonJS patterns.
|
|
111
|
+
*/
|
|
112
|
+
function removeTryCatchRequireBlocks(code) {
|
|
113
|
+
let transformed = code.replace(/try\s*\{[^{}]*?require\([^)]+\)[^{}]*?\}\s*catch[^{}]*?\{[^{}]*?\}/gs, "");
|
|
114
|
+
transformed = transformed.replace(/export let \w+;/g, "");
|
|
115
|
+
return transformed;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Generates direct export statements from the import map.
|
|
119
|
+
* Creates modern ESM exports like: export { default as varName } from 'module';
|
|
120
|
+
*/
|
|
121
|
+
function generateDirectExports(importMap) {
|
|
122
|
+
let exports = "";
|
|
123
|
+
for (const [key, vars] of importMap) {
|
|
124
|
+
const [modulePath, prop] = key.split(":");
|
|
125
|
+
if (prop === "default") for (const varName of vars) exports += `export { default as ${varName} } from '${modulePath}';\n`;
|
|
126
|
+
else for (const varName of vars) exports += `export { ${prop} as ${varName} } from '${modulePath}';\n`;
|
|
127
|
+
}
|
|
128
|
+
return exports;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Transforms React Native Reanimated webUtils files to fix problematic
|
|
132
|
+
* export let + try/catch + require patterns by converting them to proper ESM.
|
|
133
|
+
*
|
|
134
|
+
* This transformation handles the incompatible module patterns in React Native Reanimated
|
|
135
|
+
* that cause build errors in Vite due to mixing CommonJS require() with ESM exports.
|
|
136
|
+
*/
|
|
137
|
+
function transformReanimatedWebUtils(toTransform, originalCode, id, isProduction) {
|
|
138
|
+
if (!isProduction || !id.includes("node_modules/react-native-reanimated") || !id.includes("ReanimatedModule/js-reanimated/webUtils") || !originalCode.includes("export let") || !originalCode.includes("try") || !originalCode.includes("require")) return toTransform;
|
|
139
|
+
const exportLetMatches = Array.from(originalCode.matchAll(/export let (\w+);/g));
|
|
140
|
+
const exportedVars = exportLetMatches.map((match) => match[1]);
|
|
141
|
+
if (exportedVars.length === 0) return toTransform;
|
|
142
|
+
const importMap = analyzeRequireStatements(originalCode, exportedVars);
|
|
143
|
+
toTransform = removeTryCatchRequireBlocks(toTransform);
|
|
144
|
+
const exports = generateDirectExports(importMap);
|
|
145
|
+
if (exports) toTransform = `${toTransform}\n${exports}`;
|
|
146
|
+
return toTransform;
|
|
147
|
+
}
|
|
148
|
+
|
|
84
149
|
//#endregion
|
|
85
150
|
//#region src/index.ts
|
|
86
151
|
const silenceUseClientWarning = (userConfig) => ({ rollupOptions: { onwarn(warning, defaultHandler) {
|
|
@@ -160,17 +225,28 @@ function rnw(opts = {}) {
|
|
|
160
225
|
_WORKLET: false,
|
|
161
226
|
__DEV__: JSON.stringify(development),
|
|
162
227
|
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || env.mode),
|
|
228
|
+
EXPO_OS: JSON.stringify("web"),
|
|
229
|
+
"process.env.EXPO_OS": JSON.stringify("web"),
|
|
163
230
|
"global.Error": "Error"
|
|
164
231
|
},
|
|
165
232
|
optimizeDeps: {
|
|
166
233
|
...initialOptions.optimizeDeps,
|
|
167
|
-
include: ["react-native-reanimated"],
|
|
168
234
|
esbuildOptions: {
|
|
169
235
|
...(_initialOptions$optim = initialOptions.optimizeDeps) === null || _initialOptions$optim === void 0 ? void 0 : _initialOptions$optim.esbuildOptions,
|
|
170
236
|
resolveExtensions: extensions,
|
|
171
|
-
loader: { ".js": "jsx" }
|
|
237
|
+
loader: { ".js": "jsx" },
|
|
238
|
+
plugins: [esbuildFlowPlugin(/* @__PURE__ */ new RegExp(/\.(flow|jsx?)$/), (_path) => "jsx")]
|
|
172
239
|
}
|
|
173
240
|
},
|
|
241
|
+
build: { rollupOptions: {
|
|
242
|
+
treeshake: "safest",
|
|
243
|
+
plugins: [{
|
|
244
|
+
name: "nativewind-fix",
|
|
245
|
+
async transform(code, id) {
|
|
246
|
+
if (id.includes("react-native-css-interop")) return { moduleSideEffects: "no-treeshake" };
|
|
247
|
+
}
|
|
248
|
+
}]
|
|
249
|
+
} },
|
|
174
250
|
resolve: {
|
|
175
251
|
extensions,
|
|
176
252
|
alias: { "react-native": "react-native-web" }
|
|
@@ -231,16 +307,7 @@ function rnw(opts = {}) {
|
|
|
231
307
|
if (tsRE.test(filepath)) parserPlugins.push("typescript");
|
|
232
308
|
const babel$1 = await loadBabel();
|
|
233
309
|
let toTransform = code;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
import createReactDOMStyle from 'react-native-web/dist/exports/StyleSheet/compiler/createReactDOMStyle';
|
|
237
|
-
import {
|
|
238
|
-
createTextShadowValue,
|
|
239
|
-
createTransformValue,
|
|
240
|
-
} from 'react-native-web/dist/exports/StyleSheet/preprocess';
|
|
241
|
-
|
|
242
|
-
export { createReactDOMStyle, createTextShadowValue, createTransformValue };
|
|
243
|
-
`;
|
|
310
|
+
toTransform = transformReanimatedWebUtils(toTransform, code, id, isProduction);
|
|
244
311
|
const result = await babel$1.transformAsync(toTransform, {
|
|
245
312
|
...babelOptions,
|
|
246
313
|
root: projectRoot,
|
|
@@ -312,6 +379,7 @@ function rnw(opts = {}) {
|
|
|
312
379
|
}
|
|
313
380
|
};
|
|
314
381
|
return [
|
|
382
|
+
flowPlugin({ exclude }),
|
|
315
383
|
{
|
|
316
384
|
name: "treat-js-files-as-jsx",
|
|
317
385
|
async transform(code, id) {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.0.
|
|
2
|
+
"version": "0.0.6",
|
|
3
3
|
"name": "vite-plugin-rnw",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
"scripts": {
|
|
33
33
|
"dev": "tsdown --watch",
|
|
34
34
|
"build": "tsdown",
|
|
35
|
-
"prepublishOnly": "npm run build"
|
|
35
|
+
"prepublishOnly": "npm run build",
|
|
36
|
+
"test": "node --no-warnings --experimental-strip-types --test --experimental-test-coverage src/**/*.test.ts",
|
|
37
|
+
"test:watch": "node --no-warnings --experimental-strip-types --test --watch src/**/*.test.ts"
|
|
36
38
|
},
|
|
37
39
|
"engines": {
|
|
38
40
|
"node": "^14.18.0 || >=16.0.0"
|
|
@@ -53,9 +55,11 @@
|
|
|
53
55
|
},
|
|
54
56
|
"dependencies": {
|
|
55
57
|
"@babel/core": "^7.28.0",
|
|
58
|
+
"@babel/plugin-transform-flow-strip-types": "^7.27.1",
|
|
56
59
|
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
|
|
57
60
|
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
|
|
58
61
|
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
|
|
62
|
+
"@bunchtogether/vite-plugin-flow": "^1.0.2",
|
|
59
63
|
"@rolldown/pluginutils": "1.0.0-beta.24",
|
|
60
64
|
"@types/babel__core": "^7.20.5",
|
|
61
65
|
"react-refresh": "^0.17.0",
|