babel-preset-expo
Advanced tools
Comparing version 11.1.0-canary-20241008-90b13ad to 11.1.0-canary-20241018-4f8243a
@@ -1,1 +0,5 @@ | ||
export declare function reactClientReferencesPlugin(): babel.PluginObj; | ||
/** | ||
* Copyright © 2024 650 Industries. | ||
*/ | ||
import { ConfigAPI } from '@babel/core'; | ||
export declare function reactClientReferencesPlugin(api: ConfigAPI): babel.PluginObj; |
@@ -12,3 +12,5 @@ "use strict"; | ||
const url_1 = __importDefault(require("url")); | ||
function reactClientReferencesPlugin() { | ||
const common_1 = require("./common"); | ||
function reactClientReferencesPlugin(api) { | ||
const isReactServer = api.caller(common_1.getIsReactServer); | ||
return { | ||
@@ -26,2 +28,5 @@ name: 'expo-client-references', | ||
} | ||
if (!isUseClient && !isUseServer) { | ||
return; | ||
} | ||
const filePath = state.file.opts.filename; | ||
@@ -32,81 +37,133 @@ if (!filePath) { | ||
} | ||
// File starts with "use client" directive. | ||
if (!isUseClient) { | ||
// Do nothing for code that isn't marked as a client component. | ||
return; | ||
} | ||
const outputKey = url_1.default.pathToFileURL(filePath).href; | ||
// We need to add all of the exports to support `export * from './module'` which iterates the keys of the module. | ||
const proxyModule = [ | ||
`const proxy = /*@__PURE__*/ require("react-server-dom-webpack/server").createClientModuleProxy(${JSON.stringify(outputKey)});`, | ||
`module.exports = proxy;`, | ||
]; | ||
const getProxy = (exportName) => { | ||
return `(/*@__PURE__*/ proxy[${JSON.stringify(exportName)}])`; | ||
}; | ||
const proxyExports = new Set(); | ||
const pushProxy = (exportName) => { | ||
proxyExports.add(exportName); | ||
if (exportName === 'default') { | ||
proxyModule.push(`export default ${getProxy(exportName)};`); | ||
} | ||
else { | ||
proxyModule.push(`export const ${exportName} = ${getProxy(exportName)};`); | ||
} | ||
}; | ||
// Collect all of the exports | ||
path.traverse({ | ||
ExportNamedDeclaration(exportPath) { | ||
if (exportPath.node.declaration) { | ||
if (exportPath.node.declaration.type === 'VariableDeclaration') { | ||
exportPath.node.declaration.declarations.forEach((declaration) => { | ||
if (declaration.id.type === 'Identifier') { | ||
const exportName = declaration.id.name; | ||
pushProxy(exportName); | ||
function iterateExports(callback, type) { | ||
const exportNames = new Set(); | ||
// Collect all of the exports | ||
path.traverse({ | ||
ExportNamedDeclaration(exportPath) { | ||
if (exportPath.node.declaration) { | ||
if (exportPath.node.declaration.type === 'VariableDeclaration') { | ||
exportPath.node.declaration.declarations.forEach((declaration) => { | ||
if (declaration.id.type === 'Identifier') { | ||
const exportName = declaration.id.name; | ||
exportNames.add(exportName); | ||
callback(exportName); | ||
} | ||
}); | ||
} | ||
else if (exportPath.node.declaration.type === 'FunctionDeclaration') { | ||
const exportName = exportPath.node.declaration.id?.name; | ||
if (exportName) { | ||
exportNames.add(exportName); | ||
callback(exportName); | ||
} | ||
}); | ||
} | ||
else if (exportPath.node.declaration.type === 'FunctionDeclaration') { | ||
const exportName = exportPath.node.declaration.id?.name; | ||
if (exportName) { | ||
pushProxy(exportName); | ||
} | ||
} | ||
else if (exportPath.node.declaration.type === 'ClassDeclaration') { | ||
const exportName = exportPath.node.declaration.id?.name; | ||
if (exportName) { | ||
pushProxy(exportName); | ||
else if (exportPath.node.declaration.type === 'ClassDeclaration') { | ||
const exportName = exportPath.node.declaration.id?.name; | ||
if (exportName) { | ||
exportNames.add(exportName); | ||
callback(exportName); | ||
} | ||
} | ||
else if (!['InterfaceDeclaration', 'TSTypeAliasDeclaration', 'TypeAlias'].includes(exportPath.node.declaration.type)) { | ||
// TODO: What is this type? | ||
console.warn(`[babel-preset-expo] Unsupported export specifier for "use ${type}":`, exportPath.node.declaration.type); | ||
} | ||
} | ||
else if (!['InterfaceDeclaration', 'TSTypeAliasDeclaration', 'TypeAlias'].includes(exportPath.node.declaration.type)) { | ||
// TODO: What is this type? | ||
console.warn('[babel-preset-expo] Unsupported export specifier for "use client":', exportPath.node.declaration.type); | ||
else { | ||
exportPath.node.specifiers.forEach((specifier) => { | ||
if (core_1.types.isIdentifier(specifier.exported)) { | ||
const exportName = specifier.exported.name; | ||
exportNames.add(exportName); | ||
callback(exportName); | ||
} | ||
else { | ||
// TODO: What is this type? | ||
console.warn(`[babel-preset-expo] Unsupported export specifier for "use ${type}":`, specifier); | ||
} | ||
}); | ||
} | ||
}, | ||
ExportDefaultDeclaration() { | ||
exportNames.add('default'); | ||
callback('default'); | ||
}, | ||
}); | ||
return exportNames; | ||
} | ||
// File starts with "use client" directive. | ||
if (isUseServer) { | ||
if (isReactServer) { | ||
// The "use server" transform for react-server is in a different plugin. | ||
return; | ||
} | ||
// Handle "use server" in the client. | ||
const proxyModule = [ | ||
`import { createServerReference } from 'react-server-dom-webpack/client';`, | ||
`import { callServerRSC } from 'expo-router/rsc/internal';`, | ||
]; | ||
const getProxy = (exportName) => { | ||
return `createServerReference(${JSON.stringify(`${outputKey}#${exportName}`)}, callServerRSC)`; | ||
}; | ||
const pushProxy = (exportName) => { | ||
if (exportName === 'default') { | ||
proxyModule.push(`export default ${getProxy(exportName)};`); | ||
} | ||
else { | ||
exportPath.node.specifiers.forEach((specifier) => { | ||
if (core_1.types.isIdentifier(specifier.exported)) { | ||
const exportName = specifier.exported.name; | ||
pushProxy(exportName); | ||
} | ||
else { | ||
// TODO: What is this type? | ||
console.warn('[babel-preset-expo] Unsupported export specifier for "use client":', specifier); | ||
} | ||
}); | ||
proxyModule.push(`export const ${exportName} = ${getProxy(exportName)};`); | ||
} | ||
}, | ||
ExportDefaultDeclaration() { | ||
pushProxy('default'); | ||
}, | ||
}); | ||
// Clear the body | ||
path.node.body = []; | ||
path.node.directives = []; | ||
path.pushContainer('body', core_1.template.ast(proxyModule.join('\n'))); | ||
assertExpoMetadata(state.file.metadata); | ||
// Save the client reference in the metadata. | ||
state.file.metadata.reactClientReference = outputKey; | ||
// Store the proxy export names for testing purposes. | ||
state.file.metadata.proxyExports = [...proxyExports]; | ||
}; | ||
// We need to add all of the exports to support `export * from './module'` which iterates the keys of the module. | ||
// Collect all of the exports | ||
const proxyExports = iterateExports(pushProxy, 'client'); | ||
// Clear the body | ||
path.node.body = []; | ||
path.node.directives = []; | ||
path.pushContainer('body', core_1.template.ast(proxyModule.join('\n'))); | ||
assertExpoMetadata(state.file.metadata); | ||
// Store the proxy export names for testing purposes. | ||
state.file.metadata.proxyExports = [...proxyExports]; | ||
// Save the server action reference in the metadata. | ||
state.file.metadata.reactServerReference = outputKey; | ||
} | ||
else if (isUseClient) { | ||
if (!isReactServer) { | ||
// Do nothing for "use client" on the client. | ||
return; | ||
} | ||
// HACK: Mock out the polyfill that doesn't run through the normal bundler pipeline. | ||
if (filePath.endsWith('@react-native/js-polyfills/console.js')) { | ||
// Clear the body | ||
path.node.body = []; | ||
path.node.directives = []; | ||
return; | ||
} | ||
// We need to add all of the exports to support `export * from './module'` which iterates the keys of the module. | ||
const proxyModule = [ | ||
`const proxy = /*@__PURE__*/ require("react-server-dom-webpack/server").createClientModuleProxy(${JSON.stringify(outputKey)});`, | ||
`module.exports = proxy;`, | ||
]; | ||
const getProxy = (exportName) => { | ||
return `(/*@__PURE__*/ proxy[${JSON.stringify(exportName)}])`; | ||
}; | ||
const pushProxy = (exportName) => { | ||
if (exportName === 'default') { | ||
proxyModule.push(`export default ${getProxy(exportName)};`); | ||
} | ||
else { | ||
proxyModule.push(`export const ${exportName} = ${getProxy(exportName)};`); | ||
} | ||
}; | ||
// Collect all of the exports | ||
const proxyExports = iterateExports(pushProxy, 'client'); | ||
// Clear the body | ||
path.node.body = []; | ||
path.node.directives = []; | ||
path.pushContainer('body', core_1.template.ast(proxyModule.join('\n'))); | ||
assertExpoMetadata(state.file.metadata); | ||
// Store the proxy export names for testing purposes. | ||
state.file.metadata.proxyExports = [...proxyExports]; | ||
// Save the client reference in the metadata. | ||
state.file.metadata.reactClientReference = outputKey; | ||
} | ||
}, | ||
@@ -113,0 +170,0 @@ }, |
@@ -11,2 +11,3 @@ "use strict"; | ||
const restricted_react_api_plugin_1 = require("./restricted-react-api-plugin"); | ||
const server_actions_plugin_1 = require("./server-actions-plugin"); | ||
const use_dom_directive_plugin_1 = require("./use-dom-directive-plugin"); | ||
@@ -43,2 +44,4 @@ function getOptions(options, platform) { | ||
} | ||
// Use the simpler babel preset for web and server environments (both web and native SSR). | ||
const isModernEngine = platform === 'web' || isServerEnv; | ||
const platformOptions = getOptions(options, platform); | ||
@@ -102,9 +105,7 @@ if (platformOptions.useTransformReactJSXExperimental != null) { | ||
} | ||
else { | ||
if (platform !== 'web' && !isServerEnv) { | ||
// This is added back on hermes to ensure the react-jsx-dev plugin (`@babel/preset-react`) works as expected when | ||
// JSX is used in a function body. This is technically not required in production, but we | ||
// should retain the same behavior since it's hard to debug the differences. | ||
extraPlugins.push(require('@babel/plugin-transform-parameters')); | ||
} | ||
else if (!isModernEngine) { | ||
// This is added back on hermes to ensure the react-jsx-dev plugin (`@babel/preset-react`) works as expected when | ||
// JSX is used in a function body. This is technically not required in production, but we | ||
// should retain the same behavior since it's hard to debug the differences. | ||
extraPlugins.push(require('@babel/plugin-transform-parameters')); | ||
} | ||
@@ -162,6 +163,7 @@ const inlines = { | ||
} | ||
extraPlugins.push(client_module_proxy_plugin_1.reactClientReferencesPlugin); | ||
// Ensure these only run when the user opts-in to bundling for a react server to prevent unexpected behavior for | ||
// users who are bundling using the client-only system. | ||
if (isReactServer) { | ||
extraPlugins.push(client_module_proxy_plugin_1.reactClientReferencesPlugin); | ||
extraPlugins.push(server_actions_plugin_1.reactServerActionsPlugin); | ||
extraPlugins.push(restricted_react_api_plugin_1.environmentRestrictedReactAPIsPlugin); | ||
@@ -187,4 +189,2 @@ } | ||
} | ||
// Use the simpler babel preset for web and server environments (both web and native SSR). | ||
const isModernEngine = platform === 'web' || isServerEnv; | ||
return { | ||
@@ -191,0 +191,0 @@ presets: [ |
/** | ||
* Copyright © 2024 650 Industries. | ||
*/ | ||
import { ConfigAPI } from '@babel/core'; | ||
export declare function expoUseDomDirectivePlugin(api: ConfigAPI): babel.PluginObj; | ||
import { ConfigAPI, types } from '@babel/core'; | ||
export declare function expoUseDomDirectivePlugin(api: ConfigAPI & { | ||
types: typeof types; | ||
}): babel.PluginObj; |
@@ -16,2 +16,3 @@ "use strict"; | ||
function expoUseDomDirectivePlugin(api) { | ||
const { types: t } = api; | ||
// TODO: Is exporting | ||
@@ -45,2 +46,10 @@ const isProduction = api.caller(common_1.getIsProd); | ||
ExportNamedDeclaration(path) { | ||
const declaration = path.node.declaration; | ||
if (t.isTypeAlias(declaration) || | ||
t.isInterfaceDeclaration(declaration) || | ||
t.isTSTypeAliasDeclaration(declaration) || | ||
t.isTSInterfaceDeclaration(declaration)) { | ||
// Allows type exports | ||
return; | ||
} | ||
throw path.buildCodeFrameError('Modules with the "use dom" directive only support a single default export.'); | ||
@@ -47,0 +56,0 @@ }, |
{ | ||
"name": "babel-preset-expo", | ||
"version": "11.1.0-canary-20241008-90b13ad", | ||
"version": "11.1.0-canary-20241018-4f8243a", | ||
"description": "The Babel preset for Expo projects", | ||
@@ -51,4 +51,4 @@ "main": "build/index.js", | ||
"@babel/preset-typescript": "^7.23.0", | ||
"@react-native/babel-preset": "0.75.2", | ||
"babel-plugin-react-native-web": "~0.19.10", | ||
"@react-native/babel-preset": "0.76.0-rc.6", | ||
"babel-plugin-react-native-web": "~0.19.13", | ||
"react-refresh": "^0.14.2" | ||
@@ -67,6 +67,6 @@ }, | ||
"babel-plugin-react-compiler": "0.0.0-experimental-334f00b-20240725", | ||
"expo-module-scripts": "3.6.0-canary-20241008-90b13ad", | ||
"expo-module-scripts": "3.6.0-canary-20241018-4f8243a", | ||
"jest": "^29.2.1" | ||
}, | ||
"gitHead": "90b13ad9d0dd3469556ac776d8b74643375b1d97" | ||
"gitHead": "4f8243a009855c0cb389307401fb6b1fc9ce03b9" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
117745
34
2259
+ Added@react-native/babel-plugin-codegen@0.76.0-rc.6(transitive)
+ Added@react-native/babel-preset@0.76.0-rc.6(transitive)
+ Added@react-native/codegen@0.76.0-rc.6(transitive)
+ Addedbabel-plugin-syntax-hermes-parser@0.23.1(transitive)
+ Addedhermes-estree@0.23.1(transitive)
+ Addedhermes-parser@0.23.1(transitive)
- Removed@react-native/babel-plugin-codegen@0.75.2(transitive)
- Removed@react-native/babel-preset@0.75.2(transitive)
- Removed@react-native/codegen@0.75.2(transitive)
- Removedhermes-estree@0.22.0(transitive)
- Removedhermes-parser@0.22.0(transitive)