vite-plugin-react-native 0.0.1

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/README.en.md ADDED
@@ -0,0 +1,103 @@
1
+ # vite-plugin-react-native
2
+
3
+ Vite plugin for using React Native code in web environments, providing React Native to Web compatibility support.
4
+
5
+ ## Features
6
+
7
+ - ✅ Automatically replaces `react-native` with `react-native-web`
8
+ - ✅ Supports React Native extension resolution (`.web.js`, `.native.js`, etc.)
9
+ - ✅ Provides web-compatible implementations for React Native libraries:
10
+ - `react-native-safe-area-context` - SafeArea components and Hooks
11
+ - `react-native-screens` - Screen components
12
+ - `use-latest-callback` - Callback Hook
13
+ - ✅ Supports both ESM and CommonJS modes
14
+ - ✅ Automatically configures Vite optimization options
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install vite-plugin-react-native
20
+ # or
21
+ yarn add vite-plugin-react-native
22
+ # or
23
+ pnpm add vite-plugin-react-native
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ### ESM Mode (Recommended)
29
+
30
+ ```javascript
31
+ // vite.config.js or vite.config.ts
32
+ import { defineConfig } from 'vite';
33
+ import { reactNative } from 'vite-plugin-react-native';
34
+
35
+ export default defineConfig({
36
+ plugins: [
37
+ reactNative(),
38
+ ],
39
+ });
40
+ ```
41
+
42
+ ### CommonJS Mode
43
+
44
+ ```javascript
45
+ // vite.config.js
46
+ const { defineConfig } = require('vite');
47
+ const { reactNative } = require('vite-plugin-react-native');
48
+
49
+ module.exports = defineConfig({
50
+ plugins: [
51
+ reactNative(),
52
+ ],
53
+ });
54
+ ```
55
+
56
+ ## Compatibility
57
+
58
+ ### Supported React Native Libraries
59
+
60
+ - ✅ `react-native` → Automatically replaced with `react-native-web`
61
+ - ✅ `react-native-safe-area-context` → Web-compatible implementation
62
+ - ✅ `react-native-screens` → Web-compatible implementation
63
+ - ✅ `use-latest-callback` → Web-compatible implementation
64
+
65
+ ### Vite Version Support
66
+
67
+ - Vite 4.x
68
+ - Vite 5.x
69
+ - Vite 6.x
70
+ - Vite 7.x
71
+
72
+ ## How It Works
73
+
74
+ This plugin:
75
+
76
+ 1. **Alias Replacement**: Automatically replaces `react-native` with `react-native-web`
77
+ 2. **Virtual Modules**: Provides web-compatible virtual implementations for React Native-specific libraries
78
+ 3. **Extension Resolution**: Supports React Native file extension conventions (`.web.js`, `.native.js`, etc.)
79
+ 4. **Dependency Optimization**: Automatically configures Vite's dependency pre-bundling options
80
+
81
+ ## Development
82
+
83
+ ```bash
84
+ # Install dependencies
85
+ npm install
86
+
87
+ # Build
88
+ npm run build
89
+
90
+ # Will automatically build before publishing
91
+ npm publish
92
+ ```
93
+
94
+ ## License
95
+
96
+ ISC
97
+
98
+ ## Contributing
99
+
100
+ 1. Fork the repository
101
+ 2. Create a Feat_xxx branch
102
+ 3. Commit your code
103
+ 4. Create a Pull Request
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # vite-plugin-react-native
2
+
3
+ Vite 插件,用于在 Web 环境中使用 React Native 代码,提供 React Native 到 Web 的兼容性支持。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ 自动将 `react-native` 替换为 `react-native-web`
8
+ - ✅ 支持 React Native 扩展名解析(`.web.js`, `.native.js` 等)
9
+ - ✅ 提供 React Native 库的 Web 兼容实现:
10
+ - `react-native-safe-area-context` - SafeArea 组件和 Hooks
11
+ - `react-native-screens` - Screen 组件
12
+ - `use-latest-callback` - 回调 Hook
13
+ - ✅ 支持 ESM 和 CommonJS 双模式
14
+ - ✅ 自动配置 Vite 优化选项
15
+
16
+ ## 安装
17
+
18
+ ```bash
19
+ npm install vite-plugin-react-native
20
+ # 或
21
+ yarn add vite-plugin-react-native
22
+ # 或
23
+ pnpm add vite-plugin-react-native
24
+ ```
25
+
26
+ ## 使用方法
27
+
28
+ ### ESM 模式(推荐)
29
+
30
+ ```javascript
31
+ // vite.config.js 或 vite.config.ts
32
+ import { defineConfig } from 'vite';
33
+ import { reactNative } from 'vite-plugin-react-native';
34
+
35
+ export default defineConfig({
36
+ plugins: [
37
+ reactNative(),
38
+ ],
39
+ });
40
+ ```
41
+
42
+ ### CommonJS 模式
43
+
44
+ ```javascript
45
+ // vite.config.js
46
+ const { defineConfig } = require('vite');
47
+ const { reactNative } = require('vite-plugin-react-native');
48
+
49
+ module.exports = defineConfig({
50
+ plugins: [
51
+ reactNative(),
52
+ ],
53
+ });
54
+ ```
55
+
56
+ ## 支持情况
57
+
58
+ ### 兼容的 React Native 库
59
+
60
+ - ✅ `react-native` → 自动替换为 `react-native-web`
61
+ - ✅ `react-native-safe-area-context` → Web 兼容实现
62
+ - ✅ `react-native-screens` → Web 兼容实现
63
+ - ✅ `use-latest-callback` → Web 兼容实现
64
+
65
+ ### Vite 版本支持
66
+
67
+ - Vite 4.x
68
+ - Vite 5.x
69
+ - Vite 6.x
70
+ - Vite 7.x
71
+
72
+ ## 工作原理
73
+
74
+ 该插件会:
75
+
76
+ 1. **别名替换**:将 `react-native` 自动替换为 `react-native-web`
77
+ 2. **虚拟模块**:为 React Native 特定库提供 Web 兼容的虚拟实现
78
+ 3. **扩展名解析**:支持 React Native 的文件扩展名约定(`.web.js`, `.native.js` 等)
79
+ 4. **依赖优化**:自动配置 Vite 的依赖预构建选项
80
+
81
+ ## 开发
82
+
83
+ ```bash
84
+ # 安装依赖
85
+ npm install
86
+
87
+ # 构建
88
+ npm run build
89
+
90
+ # 发布前会自动构建
91
+ npm publish
92
+ ```
93
+
94
+ ## 许可证
95
+
96
+ ISC
97
+
98
+ ## 参与贡献
99
+
100
+ 1. Fork 本仓库
101
+ 2. 新建 Feat_xxx 分支
102
+ 3. 提交代码
103
+ 4. 新建 Pull Request
package/dist/index.cjs ADDED
@@ -0,0 +1,191 @@
1
+ 'use strict';
2
+
3
+ // index.ts
4
+ function uniqueStrings(values) {
5
+ const out = [];
6
+ const seen = /* @__PURE__ */ new Set();
7
+ for (const v of values) {
8
+ if (!v) continue;
9
+ if (seen.has(v)) continue;
10
+ seen.add(v);
11
+ out.push(v);
12
+ }
13
+ return out;
14
+ }
15
+ var reactNativeResolveExtensions = [
16
+ ".web.mjs",
17
+ ".web.js",
18
+ ".web.ts",
19
+ ".web.tsx",
20
+ ".web.jsx",
21
+ ".native.mjs",
22
+ ".native.js",
23
+ ".native.ts",
24
+ ".native.tsx",
25
+ ".native.jsx",
26
+ ".mjs",
27
+ ".js",
28
+ ".ts",
29
+ ".tsx",
30
+ ".jsx",
31
+ ".json"
32
+ ];
33
+ var useLatestCallbackShimModule = `
34
+ import * as React from 'react';
35
+ const useClientLayoutEffect =
36
+ typeof document !== 'undefined' ||
37
+ (typeof navigator !== 'undefined' && navigator.product === 'ReactNative')
38
+ ? React.useLayoutEffect
39
+ : React.useEffect;
40
+ export default function useLatestCallback(callback) {
41
+ const ref = React.useRef(callback);
42
+ const latestCallback = React.useRef(function latestCallback() {
43
+ return ref.current.apply(this, arguments);
44
+ }).current;
45
+ useClientLayoutEffect(() => {
46
+ ref.current = callback;
47
+ });
48
+ return latestCallback;
49
+ }
50
+ `;
51
+ function latestCallbackEsbuildShim() {
52
+ const namespace = "virtual-use-latest-callback";
53
+ return {
54
+ name: "use-latest-callback-esbuild-shim",
55
+ setup(build) {
56
+ build.onResolve({ filter: /^use-latest-callback$/ }, () => {
57
+ return { path: "use-latest-callback", namespace };
58
+ });
59
+ build.onLoad({ filter: /.*/, namespace }, () => {
60
+ return { contents: useLatestCallbackShimModule, loader: "js" };
61
+ });
62
+ }
63
+ };
64
+ }
65
+ function reactNative() {
66
+ const safeAreaId = "virtual:rn-safe-area-context";
67
+ const resolvedSafeAreaId = "\0" + safeAreaId;
68
+ const screensId = "virtual:rn-screens";
69
+ const resolvedScreensId = "\0" + screensId;
70
+ const latestCallbackId = "virtual:use-latest-callback";
71
+ const resolvedLatestCallbackId = "\0" + latestCallbackId;
72
+ return {
73
+ name: "vite-plugin-react-native",
74
+ enforce: "pre",
75
+ config(userConfig, env) {
76
+ const mode = env.mode;
77
+ const isProd = mode === "production";
78
+ const userResolveExtensions = Array.isArray(userConfig.resolve?.extensions) ? userConfig.resolve?.extensions : null;
79
+ const userOptimizeDepsExclude = Array.isArray(userConfig.optimizeDeps?.exclude) ? userConfig.optimizeDeps?.exclude : [];
80
+ const userOptimizeDepsInclude = Array.isArray(userConfig.optimizeDeps?.include) ? userConfig.optimizeDeps?.include : [];
81
+ const userEsbuildPlugins = Array.isArray(userConfig.optimizeDeps?.esbuildOptions?.plugins) ? userConfig.optimizeDeps?.esbuildOptions?.plugins : [];
82
+ const config = {
83
+ resolve: {
84
+ alias: [{ find: /^react-native$/, replacement: "react-native-web" }],
85
+ dedupe: ["react", "react-dom"],
86
+ extensions: userResolveExtensions ? void 0 : reactNativeResolveExtensions
87
+ },
88
+ define: {
89
+ __DEV__: JSON.stringify(!isProd),
90
+ "process.env.NODE_ENV": JSON.stringify(mode),
91
+ global: "globalThis"
92
+ },
93
+ optimizeDeps: {
94
+ include: uniqueStrings([
95
+ ...userOptimizeDepsInclude,
96
+ "react",
97
+ "react-dom",
98
+ "react/jsx-runtime",
99
+ "react/jsx-dev-runtime"
100
+ ]),
101
+ exclude: uniqueStrings([
102
+ ...userOptimizeDepsExclude,
103
+ "react-native",
104
+ "react-native-gesture-handler",
105
+ "react-native-safe-area-context",
106
+ "react-native-screens"
107
+ ]),
108
+ esbuildOptions: {
109
+ plugins: [...userEsbuildPlugins, latestCallbackEsbuildShim()]
110
+ }
111
+ }
112
+ };
113
+ return config;
114
+ },
115
+ resolveId(source) {
116
+ if (source === "react-native-safe-area-context") return resolvedSafeAreaId;
117
+ if (source === "react-native-screens") return resolvedScreensId;
118
+ if (source === "use-latest-callback") return resolvedLatestCallbackId;
119
+ if (source === "use-latest-callback/esm.mjs") return resolvedLatestCallbackId;
120
+ if (source.endsWith("use-latest-callback/lib/src/index.js")) return resolvedLatestCallbackId;
121
+ if (source === "./lib/src/index.js") return resolvedLatestCallbackId;
122
+ return null;
123
+ },
124
+ load(id) {
125
+ const normalizedId = id.split("?")[0];
126
+ if (id === resolvedSafeAreaId) {
127
+ return `
128
+ import * as React from 'react';
129
+ import { View } from 'react-native';
130
+ export const SafeAreaInsetsContext = React.createContext(null);
131
+ export const SafeAreaFrameContext = React.createContext(null);
132
+ const zeroInsets = { top: 0, right: 0, bottom: 0, left: 0 };
133
+ const initialFrame = {
134
+ x: 0,
135
+ y: 0,
136
+ width: typeof window !== 'undefined' ? window.innerWidth : 0,
137
+ height: typeof window !== 'undefined' ? window.innerHeight : 0,
138
+ };
139
+ export const initialWindowMetrics = { frame: initialFrame, insets: zeroInsets };
140
+ export function SafeAreaProvider(props) {
141
+ const { children, initialMetrics, initialSafeAreaInsets, ...rest } = props ?? {};
142
+ const insets = (initialMetrics && initialMetrics.insets) || initialSafeAreaInsets || zeroInsets;
143
+ const frame = (initialMetrics && initialMetrics.frame) || initialFrame;
144
+ return React.createElement(
145
+ SafeAreaFrameContext.Provider,
146
+ { value: frame },
147
+ React.createElement(
148
+ SafeAreaInsetsContext.Provider,
149
+ { value: insets },
150
+ React.createElement(View, rest, children),
151
+ ),
152
+ );
153
+ }
154
+ export function useSafeAreaInsets() {
155
+ return React.useContext(SafeAreaInsetsContext) || zeroInsets;
156
+ }
157
+ export function useSafeAreaFrame() {
158
+ return React.useContext(SafeAreaFrameContext) || initialFrame;
159
+ }
160
+ export function SafeAreaView(props) {
161
+ return React.createElement(View, props);
162
+ }
163
+ `;
164
+ }
165
+ if (id === resolvedScreensId) {
166
+ return `
167
+ import * as React from 'react';
168
+ import { View } from 'react-native';
169
+ export function enableScreens() {}
170
+ export function screensEnabled() { return false; }
171
+ export function enableFreeze() {}
172
+ export function freezeEnabled() { return false; }
173
+ export function Screen(props) { return React.createElement(View, props); }
174
+ export function ScreenContainer(props) { return React.createElement(View, props); }
175
+ `;
176
+ }
177
+ if (id === resolvedLatestCallbackId) {
178
+ return useLatestCallbackShimModule;
179
+ }
180
+ if (normalizedId.includes("/node_modules/use-latest-callback/lib/src/index.js")) {
181
+ return useLatestCallbackShimModule;
182
+ }
183
+ if (normalizedId.includes("/node_modules/use-latest-callback/esm.mjs")) {
184
+ return useLatestCallbackShimModule;
185
+ }
186
+ return null;
187
+ }
188
+ };
189
+ }
190
+
191
+ exports.reactNative = reactNative;
@@ -0,0 +1,5 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ declare function reactNative(): Plugin;
4
+
5
+ export { reactNative };
@@ -0,0 +1,5 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ declare function reactNative(): Plugin;
4
+
5
+ export { reactNative };
package/dist/index.js ADDED
@@ -0,0 +1,189 @@
1
+ // index.ts
2
+ function uniqueStrings(values) {
3
+ const out = [];
4
+ const seen = /* @__PURE__ */ new Set();
5
+ for (const v of values) {
6
+ if (!v) continue;
7
+ if (seen.has(v)) continue;
8
+ seen.add(v);
9
+ out.push(v);
10
+ }
11
+ return out;
12
+ }
13
+ var reactNativeResolveExtensions = [
14
+ ".web.mjs",
15
+ ".web.js",
16
+ ".web.ts",
17
+ ".web.tsx",
18
+ ".web.jsx",
19
+ ".native.mjs",
20
+ ".native.js",
21
+ ".native.ts",
22
+ ".native.tsx",
23
+ ".native.jsx",
24
+ ".mjs",
25
+ ".js",
26
+ ".ts",
27
+ ".tsx",
28
+ ".jsx",
29
+ ".json"
30
+ ];
31
+ var useLatestCallbackShimModule = `
32
+ import * as React from 'react';
33
+ const useClientLayoutEffect =
34
+ typeof document !== 'undefined' ||
35
+ (typeof navigator !== 'undefined' && navigator.product === 'ReactNative')
36
+ ? React.useLayoutEffect
37
+ : React.useEffect;
38
+ export default function useLatestCallback(callback) {
39
+ const ref = React.useRef(callback);
40
+ const latestCallback = React.useRef(function latestCallback() {
41
+ return ref.current.apply(this, arguments);
42
+ }).current;
43
+ useClientLayoutEffect(() => {
44
+ ref.current = callback;
45
+ });
46
+ return latestCallback;
47
+ }
48
+ `;
49
+ function latestCallbackEsbuildShim() {
50
+ const namespace = "virtual-use-latest-callback";
51
+ return {
52
+ name: "use-latest-callback-esbuild-shim",
53
+ setup(build) {
54
+ build.onResolve({ filter: /^use-latest-callback$/ }, () => {
55
+ return { path: "use-latest-callback", namespace };
56
+ });
57
+ build.onLoad({ filter: /.*/, namespace }, () => {
58
+ return { contents: useLatestCallbackShimModule, loader: "js" };
59
+ });
60
+ }
61
+ };
62
+ }
63
+ function reactNative() {
64
+ const safeAreaId = "virtual:rn-safe-area-context";
65
+ const resolvedSafeAreaId = "\0" + safeAreaId;
66
+ const screensId = "virtual:rn-screens";
67
+ const resolvedScreensId = "\0" + screensId;
68
+ const latestCallbackId = "virtual:use-latest-callback";
69
+ const resolvedLatestCallbackId = "\0" + latestCallbackId;
70
+ return {
71
+ name: "vite-plugin-react-native",
72
+ enforce: "pre",
73
+ config(userConfig, env) {
74
+ const mode = env.mode;
75
+ const isProd = mode === "production";
76
+ const userResolveExtensions = Array.isArray(userConfig.resolve?.extensions) ? userConfig.resolve?.extensions : null;
77
+ const userOptimizeDepsExclude = Array.isArray(userConfig.optimizeDeps?.exclude) ? userConfig.optimizeDeps?.exclude : [];
78
+ const userOptimizeDepsInclude = Array.isArray(userConfig.optimizeDeps?.include) ? userConfig.optimizeDeps?.include : [];
79
+ const userEsbuildPlugins = Array.isArray(userConfig.optimizeDeps?.esbuildOptions?.plugins) ? userConfig.optimizeDeps?.esbuildOptions?.plugins : [];
80
+ const config = {
81
+ resolve: {
82
+ alias: [{ find: /^react-native$/, replacement: "react-native-web" }],
83
+ dedupe: ["react", "react-dom"],
84
+ extensions: userResolveExtensions ? void 0 : reactNativeResolveExtensions
85
+ },
86
+ define: {
87
+ __DEV__: JSON.stringify(!isProd),
88
+ "process.env.NODE_ENV": JSON.stringify(mode),
89
+ global: "globalThis"
90
+ },
91
+ optimizeDeps: {
92
+ include: uniqueStrings([
93
+ ...userOptimizeDepsInclude,
94
+ "react",
95
+ "react-dom",
96
+ "react/jsx-runtime",
97
+ "react/jsx-dev-runtime"
98
+ ]),
99
+ exclude: uniqueStrings([
100
+ ...userOptimizeDepsExclude,
101
+ "react-native",
102
+ "react-native-gesture-handler",
103
+ "react-native-safe-area-context",
104
+ "react-native-screens"
105
+ ]),
106
+ esbuildOptions: {
107
+ plugins: [...userEsbuildPlugins, latestCallbackEsbuildShim()]
108
+ }
109
+ }
110
+ };
111
+ return config;
112
+ },
113
+ resolveId(source) {
114
+ if (source === "react-native-safe-area-context") return resolvedSafeAreaId;
115
+ if (source === "react-native-screens") return resolvedScreensId;
116
+ if (source === "use-latest-callback") return resolvedLatestCallbackId;
117
+ if (source === "use-latest-callback/esm.mjs") return resolvedLatestCallbackId;
118
+ if (source.endsWith("use-latest-callback/lib/src/index.js")) return resolvedLatestCallbackId;
119
+ if (source === "./lib/src/index.js") return resolvedLatestCallbackId;
120
+ return null;
121
+ },
122
+ load(id) {
123
+ const normalizedId = id.split("?")[0];
124
+ if (id === resolvedSafeAreaId) {
125
+ return `
126
+ import * as React from 'react';
127
+ import { View } from 'react-native';
128
+ export const SafeAreaInsetsContext = React.createContext(null);
129
+ export const SafeAreaFrameContext = React.createContext(null);
130
+ const zeroInsets = { top: 0, right: 0, bottom: 0, left: 0 };
131
+ const initialFrame = {
132
+ x: 0,
133
+ y: 0,
134
+ width: typeof window !== 'undefined' ? window.innerWidth : 0,
135
+ height: typeof window !== 'undefined' ? window.innerHeight : 0,
136
+ };
137
+ export const initialWindowMetrics = { frame: initialFrame, insets: zeroInsets };
138
+ export function SafeAreaProvider(props) {
139
+ const { children, initialMetrics, initialSafeAreaInsets, ...rest } = props ?? {};
140
+ const insets = (initialMetrics && initialMetrics.insets) || initialSafeAreaInsets || zeroInsets;
141
+ const frame = (initialMetrics && initialMetrics.frame) || initialFrame;
142
+ return React.createElement(
143
+ SafeAreaFrameContext.Provider,
144
+ { value: frame },
145
+ React.createElement(
146
+ SafeAreaInsetsContext.Provider,
147
+ { value: insets },
148
+ React.createElement(View, rest, children),
149
+ ),
150
+ );
151
+ }
152
+ export function useSafeAreaInsets() {
153
+ return React.useContext(SafeAreaInsetsContext) || zeroInsets;
154
+ }
155
+ export function useSafeAreaFrame() {
156
+ return React.useContext(SafeAreaFrameContext) || initialFrame;
157
+ }
158
+ export function SafeAreaView(props) {
159
+ return React.createElement(View, props);
160
+ }
161
+ `;
162
+ }
163
+ if (id === resolvedScreensId) {
164
+ return `
165
+ import * as React from 'react';
166
+ import { View } from 'react-native';
167
+ export function enableScreens() {}
168
+ export function screensEnabled() { return false; }
169
+ export function enableFreeze() {}
170
+ export function freezeEnabled() { return false; }
171
+ export function Screen(props) { return React.createElement(View, props); }
172
+ export function ScreenContainer(props) { return React.createElement(View, props); }
173
+ `;
174
+ }
175
+ if (id === resolvedLatestCallbackId) {
176
+ return useLatestCallbackShimModule;
177
+ }
178
+ if (normalizedId.includes("/node_modules/use-latest-callback/lib/src/index.js")) {
179
+ return useLatestCallbackShimModule;
180
+ }
181
+ if (normalizedId.includes("/node_modules/use-latest-callback/esm.mjs")) {
182
+ return useLatestCallbackShimModule;
183
+ }
184
+ return null;
185
+ }
186
+ };
187
+ }
188
+
189
+ export { reactNative };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "vite-plugin-react-native",
3
+ "version": "0.0.1",
4
+ "description": "Vite plugin for React Native web compatibility",
5
+ "keywords": [
6
+ "vite",
7
+ "vite-plugin",
8
+ "react-native",
9
+ "react-native-web",
10
+ "web",
11
+ "compatibility"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://gitee.com/ws18250840411/vite-plugin-react-native.git"
16
+ },
17
+ "license": "ISC",
18
+ "author": "",
19
+ "type": "module",
20
+ "main": "./dist/index.cjs",
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "require": "./dist/index.cjs"
28
+ }
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsup",
36
+ "prepublishOnly": "npm run build",
37
+ "test": "echo \"Error: no test specified\" && exit 1"
38
+ },
39
+ "peerDependencies": {
40
+ "vite": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^20.0.0",
44
+ "tsup": "^8.5.1",
45
+ "typescript": "^5.0.0",
46
+ "vite": "^7.0.0"
47
+ }
48
+ }