@vxrn/vite-plugin-metro 1.2.6 → 1.2.8

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.
Files changed (36) hide show
  1. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.cjs +67 -35
  2. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.js +32 -8
  3. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.js.map +2 -2
  4. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.native.js +45 -11
  5. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.native.js.map +1 -1
  6. package/dist/cjs/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.cjs +25 -5
  7. package/dist/cjs/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.js +27 -5
  8. package/dist/cjs/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.js.map +1 -1
  9. package/dist/cjs/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.native.js +41 -6
  10. package/dist/cjs/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.native.js.map +1 -1
  11. package/dist/cjs/plugins/metroPlugin.js.map +1 -1
  12. package/dist/cjs/plugins/metroPlugin.native.js.map +1 -1
  13. package/dist/esm/metro-config/getMetroConfigFromViteConfig.js +22 -5
  14. package/dist/esm/metro-config/getMetroConfigFromViteConfig.js.map +1 -1
  15. package/dist/esm/metro-config/getMetroConfigFromViteConfig.mjs +51 -30
  16. package/dist/esm/metro-config/getMetroConfigFromViteConfig.mjs.map +1 -1
  17. package/dist/esm/metro-config/getMetroConfigFromViteConfig.native.js +29 -6
  18. package/dist/esm/metro-config/getMetroConfigFromViteConfig.native.js.map +1 -1
  19. package/dist/esm/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.js +27 -5
  20. package/dist/esm/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.js.map +1 -1
  21. package/dist/esm/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.mjs +25 -5
  22. package/dist/esm/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.mjs.map +1 -1
  23. package/dist/esm/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.native.js +41 -6
  24. package/dist/esm/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.native.js.map +1 -1
  25. package/dist/esm/plugins/metroPlugin.js.map +1 -1
  26. package/dist/esm/plugins/metroPlugin.mjs.map +1 -1
  27. package/dist/esm/plugins/metroPlugin.native.js.map +1 -1
  28. package/package.json +3 -2
  29. package/src/metro-config/getMetroConfigFromViteConfig.ts +51 -7
  30. package/src/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.ts +65 -5
  31. package/src/plugins/metroPlugin.ts +22 -1
  32. package/types/metro-config/getMetroConfigFromViteConfig.d.ts.map +1 -1
  33. package/types/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.d.ts.map +1 -1
  34. package/types/plugins/metroPlugin.d.ts +22 -1
  35. package/types/plugins/metroPlugin.d.ts.map +1 -1
  36. package/types/transformer/loadBabelConfig.d.ts +1 -1
@@ -1,4 +1,5 @@
1
1
  import type { ResolvedConfig } from 'vite'
2
+ import micromatch from 'micromatch'
2
3
 
3
4
  // For Metro and Expo, we only import types here.
4
5
  // We use `projectImport` to dynamically import the actual modules
@@ -20,7 +21,8 @@ export async function getMetroConfigFromViteConfig(
20
21
  ): Promise<MetroConfigExtended> {
21
22
  const extraConfig: ExtraConfig = {}
22
23
  const { root: projectRoot } = config
23
- const { mainModuleName, argv, defaultConfigOverrides } = metroPluginOptions
24
+ const { mainModuleName, argv, defaultConfigOverrides, watchman, excludeModules } =
25
+ metroPluginOptions
24
26
 
25
27
  const { loadConfig } = await projectImport<{
26
28
  loadConfig: typeof loadConfigT
@@ -83,11 +85,19 @@ export async function getMetroConfigFromViteConfig(
83
85
  ..._defaultConfig,
84
86
  resolver: {
85
87
  ..._defaultConfig?.resolver,
88
+ ...(watchman !== undefined ? { useWatchman: watchman } : {}),
86
89
  sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'mjs', 'cjs'], // `one` related packages are using `.mjs` extensions. This somehow fixes `.native` files not being resolved correctly when `.mjs` files are present.
87
90
  resolveRequest: (context, moduleName, platform) => {
88
91
  const origResolveRequestFn =
89
92
  _defaultConfig?.resolver?.resolveRequest || context.resolveRequest
90
93
 
94
+ // Handle excludeModules - resolve excluded modules to empty module using glob patterns
95
+ if (excludeModules && excludeModules.length > 0) {
96
+ if (micromatch.isMatch(moduleName, excludeModules)) {
97
+ return origResolveRequestFn(context, '@vxrn/vite-plugin-metro/empty', platform)
98
+ }
99
+ }
100
+
91
101
  // HACK: Do not assert the "import" condition for `@babel/runtime`. This
92
102
  // is a workaround for ESM <-> CJS interop, as we need the CJS versions of
93
103
  // `@babel/runtime` helpers.
@@ -122,6 +132,45 @@ export async function getMetroConfigFromViteConfig(
122
132
  reporter: await getTerminalReporter(projectRoot),
123
133
  }
124
134
 
135
+ // Apply user's defaultConfigOverrides to get the final config with user's custom resolveRequest
136
+ const userConfig =
137
+ typeof defaultConfigOverrides === 'function'
138
+ ? defaultConfigOverrides(defaultConfig)
139
+ : defaultConfigOverrides
140
+
141
+ // Get the user's custom resolveRequest if they provided one
142
+ const userResolveRequest = userConfig?.resolver?.resolveRequest
143
+
144
+ // Build the final config, wrapping resolveRequest to handle excludeModules
145
+ const finalConfig: MetroInputConfig = {
146
+ ...defaultConfig,
147
+ ...userConfig,
148
+ resolver: {
149
+ ...defaultConfig.resolver,
150
+ ...userConfig?.resolver,
151
+ resolveRequest: (context, moduleName, platform) => {
152
+ const origResolveRequestFn =
153
+ _defaultConfig?.resolver?.resolveRequest || context.resolveRequest
154
+
155
+ // Handle excludeModules first - resolve excluded modules to empty module using glob patterns
156
+ if (excludeModules && excludeModules.length > 0) {
157
+ if (micromatch.isMatch(moduleName, excludeModules)) {
158
+ return origResolveRequestFn(context, '@vxrn/vite-plugin-metro/empty', platform)
159
+ }
160
+ }
161
+
162
+ // If user provided their own resolveRequest, use it
163
+ if (userResolveRequest) {
164
+ return userResolveRequest(context, moduleName, platform)
165
+ }
166
+
167
+ // Otherwise use the default logic
168
+ const defaultResolveRequestFn = defaultConfig.resolver!.resolveRequest!
169
+ return defaultResolveRequestFn(context, moduleName, platform)
170
+ },
171
+ },
172
+ }
173
+
125
174
  const metroConfig = await loadConfig(
126
175
  {
127
176
  cwd: projectRoot,
@@ -129,12 +178,7 @@ export async function getMetroConfigFromViteConfig(
129
178
  'reset-cache': !!process.env.METRO_RESET_CACHE, // TODO: `--clean`
130
179
  ...argv,
131
180
  },
132
- {
133
- ...defaultConfig,
134
- ...(typeof defaultConfigOverrides === 'function'
135
- ? defaultConfigOverrides(defaultConfig)
136
- : defaultConfigOverrides),
137
- }
181
+ finalConfig
138
182
  )
139
183
 
140
184
  // @ts-expect-error TODO
@@ -5,6 +5,68 @@ import type { MetroPluginOptions } from '../plugins/metroPlugin'
5
5
  import type { ViteCustomTransformOptions } from '../transformer/types'
6
6
  import { getMetroBabelConfigFromViteConfig } from './getMetroBabelConfigFromViteConfig'
7
7
 
8
+ /**
9
+ * Deep merges babel configs, properly handling arrays like plugins and presets
10
+ */
11
+ function deepMergeBabelConfig(
12
+ base: TransformOptions,
13
+ override: TransformOptions | undefined
14
+ ): TransformOptions {
15
+ if (!override) return base
16
+
17
+ const merged: TransformOptions = {
18
+ ...base,
19
+ ...override,
20
+ }
21
+
22
+ // Deep merge plugins - concatenate arrays
23
+ if (base.plugins || override.plugins) {
24
+ merged.plugins = [...(base.plugins || []), ...(override.plugins || [])]
25
+ }
26
+
27
+ // Deep merge presets - concatenate arrays
28
+ if (base.presets || override.presets) {
29
+ merged.presets = [...(base.presets || []), ...(override.presets || [])]
30
+ }
31
+
32
+ // Deep merge env if both exist
33
+ if (base.env && override.env) {
34
+ merged.env = { ...base.env }
35
+ for (const [key, value] of Object.entries(override.env)) {
36
+ if (value) {
37
+ merged.env[key] = deepMergeBabelConfig(base.env[key] || {}, value)
38
+ }
39
+ }
40
+ }
41
+
42
+ // Deep merge parserOpts if both exist
43
+ if (base.parserOpts && override.parserOpts) {
44
+ merged.parserOpts = {
45
+ ...base.parserOpts,
46
+ ...override.parserOpts,
47
+ // Merge plugins arrays if both exist
48
+ ...(base.parserOpts.plugins || override.parserOpts.plugins
49
+ ? {
50
+ plugins: [
51
+ ...(base.parserOpts.plugins || []),
52
+ ...(override.parserOpts.plugins || []),
53
+ ],
54
+ }
55
+ : {}),
56
+ }
57
+ }
58
+
59
+ // Deep merge generatorOpts if both exist
60
+ if (base.generatorOpts && override.generatorOpts) {
61
+ merged.generatorOpts = {
62
+ ...base.generatorOpts,
63
+ ...override.generatorOpts,
64
+ }
65
+ }
66
+
67
+ return merged
68
+ }
69
+
8
70
  export function patchMetroServerWithViteConfigAndMetroPluginOptions(
9
71
  metroServer: Server,
10
72
  config: ResolvedConfig,
@@ -23,12 +85,10 @@ export function patchMetroServerWithViteConfigAndMetroPluginOptions(
23
85
  transformOptions: Parameters<typeof originalTransformFile>[1],
24
86
  fileBuffer?: Parameters<typeof originalTransformFile>[2]
25
87
  ) => {
26
- let babelConfig: TransformOptions = {
27
- ...defaultBabelConfig,
28
- ...options.babelConfig,
29
- plugins: [...(defaultBabelConfig.plugins || []), ...(options.babelConfig?.plugins || [])],
30
- }
88
+ // Deep merge babelConfig if provided
89
+ let babelConfig: TransformOptions = deepMergeBabelConfig(defaultBabelConfig, options.babelConfig)
31
90
 
91
+ // Apply babelConfigOverrides for full control
32
92
  if (options.babelConfigOverrides) {
33
93
  babelConfig = options.babelConfigOverrides(babelConfig)
34
94
  }
@@ -26,8 +26,29 @@ export type MetroPluginOptions = {
26
26
  defaultConfigOverrides?:
27
27
  | MetroInputConfig
28
28
  | ((defaultConfig: MetroInputConfig) => MetroInputConfig)
29
- /** Consider using babelConfigOverrides instead */
29
+ /**
30
+ * Shorthand for setting `useWatchman` in Metro's resolver config.
31
+ * When true, enables Watchman for file watching. When false, disables it.
32
+ */
33
+ watchman?: boolean
34
+ /**
35
+ * Array of module names or glob patterns that should be resolved to an empty module.
36
+ * This is useful for excluding modules that break the React Native build.
37
+ *
38
+ * Supports glob patterns via micromatch:
39
+ * - Exact match: `'jsonwebtoken'`
40
+ * - Wildcard: `'@aws-sdk/*'`
41
+ * - Multiple wildcards: `'@aws-sdk/**'`
42
+ *
43
+ * Example: `['node:http2', 'jsonwebtoken', '@aws-sdk/*']`
44
+ */
45
+ excludeModules?: string[]
46
+ /**
47
+ * Babel configuration that will be deep merged with the default config.
48
+ * This is a more convenient alternative to babelConfigOverrides.
49
+ */
30
50
  babelConfig?: TransformOptions
51
+ /** Advanced: Use this for full control over babel config merging */
31
52
  babelConfigOverrides?: (defaultConfig: TransformOptions) => TransformOptions
32
53
  /**
33
54
  * Overrides the main module name which is normally defined as the `main` field in `package.json`.
@@ -1 +1 @@
1
- {"version":3,"file":"getMetroConfigFromViteConfig.d.ts","sourceRoot":"","sources":["../../src/metro-config/getMetroConfigFromViteConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAW1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAI/D,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,cAAc,EACtB,kBAAkB,EAAE,kBAAkB,GACrC,OAAO,CAAC,mBAAmB,CAAC,CA6H9B"}
1
+ {"version":3,"file":"getMetroConfigFromViteConfig.d.ts","sourceRoot":"","sources":["../../src/metro-config/getMetroConfigFromViteConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAY1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAI/D,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,cAAc,EACtB,kBAAkB,EAAE,kBAAkB,GACrC,OAAO,CAAC,mBAAmB,CAAC,CAwK9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"patchMetroServerWithViteConfigAndMetroPluginOptions.d.ts","sourceRoot":"","sources":["../../src/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,sBAAsB,CAAA;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAIhE,wBAAgB,mDAAmD,CACjE,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,kBAAkB,QA0C5B"}
1
+ {"version":3,"file":"patchMetroServerWithViteConfigAndMetroPluginOptions.d.ts","sourceRoot":"","sources":["../../src/metro-config/patchMetroServerWithViteConfigAndMetroPluginOptions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,sBAAsB,CAAA;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAkEhE,wBAAgB,mDAAmD,CACjE,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,kBAAkB,QAwC5B"}
@@ -6,8 +6,29 @@ type MetroInputConfig = Parameters<typeof loadConfigT>[1];
6
6
  export type MetroPluginOptions = {
7
7
  argv?: MetroYargArguments;
8
8
  defaultConfigOverrides?: MetroInputConfig | ((defaultConfig: MetroInputConfig) => MetroInputConfig);
9
- /** Consider using babelConfigOverrides instead */
9
+ /**
10
+ * Shorthand for setting `useWatchman` in Metro's resolver config.
11
+ * When true, enables Watchman for file watching. When false, disables it.
12
+ */
13
+ watchman?: boolean;
14
+ /**
15
+ * Array of module names or glob patterns that should be resolved to an empty module.
16
+ * This is useful for excluding modules that break the React Native build.
17
+ *
18
+ * Supports glob patterns via micromatch:
19
+ * - Exact match: `'jsonwebtoken'`
20
+ * - Wildcard: `'@aws-sdk/*'`
21
+ * - Multiple wildcards: `'@aws-sdk/**'`
22
+ *
23
+ * Example: `['node:http2', 'jsonwebtoken', '@aws-sdk/*']`
24
+ */
25
+ excludeModules?: string[];
26
+ /**
27
+ * Babel configuration that will be deep merged with the default config.
28
+ * This is a more convenient alternative to babelConfigOverrides.
29
+ */
10
30
  babelConfig?: TransformOptions;
31
+ /** Advanced: Use this for full control over babel config merging */
11
32
  babelConfigOverrides?: (defaultConfig: TransformOptions) => TransformOptions;
12
33
  /**
13
34
  * Overrides the main module name which is normally defined as the `main` field in `package.json`.
@@ -1 +1 @@
1
- {"version":3,"file":"metroPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/metroPlugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAOxC,OAAO,KAAK,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,OAAO,CAAA;AAMtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAIjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAC3D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAEzD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,sBAAsB,CAAC,EACnB,gBAAgB,GAChB,CAAC,CAAC,aAAa,EAAE,gBAAgB,KAAK,gBAAgB,CAAC,CAAA;IAC3D,kDAAkD;IAClD,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,oBAAoB,CAAC,EAAE,CAAC,aAAa,EAAE,gBAAgB,KAAK,gBAAgB,CAAA;IAC5E;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,YAAY,CAgJ1E"}
1
+ {"version":3,"file":"metroPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/metroPlugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAOxC,OAAO,KAAK,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,OAAO,CAAA;AAMtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAIjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAC3D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAEzD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,sBAAsB,CAAC,EACnB,gBAAgB,GAChB,CAAC,CAAC,aAAa,EAAE,gBAAgB,KAAK,gBAAgB,CAAC,CAAA;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,CAAC,aAAa,EAAE,gBAAgB,KAAK,gBAAgB,CAAA;IAC5E;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,YAAY,CAgJ1E"}
@@ -6,5 +6,5 @@ import type { TransformOptions } from './babel-core';
6
6
  */
7
7
  export declare const loadBabelConfig: ({ projectRoot }: {
8
8
  projectRoot: string;
9
- }) => Pick<TransformOptions, "extends" | "presets">;
9
+ }) => Pick<TransformOptions, "presets" | "extends">;
10
10
  //# sourceMappingURL=loadBabelConfig.d.ts.map