Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

babel-preset-expo

Package Overview
Dependencies
Maintainers
28
Versions
123
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-preset-expo - npm Package Compare versions

Comparing version 11.1.0-canary-20241008-90b13ad to 11.1.0-canary-20241018-4f8243a

build/server-actions-plugin.d.ts

6

build/client-module-proxy-plugin.d.ts

@@ -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;

199

build/client-module-proxy-plugin.js

@@ -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"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc