diff --git a/packages/react-native-builder-bob/src/__fixtures__/project/code/$alias-input.ts b/packages/react-native-builder-bob/src/__fixtures__/project/code/$alias-input.ts deleted file mode 100644 index 567ff58b1..000000000 --- a/packages/react-native-builder-bob/src/__fixtures__/project/code/$alias-input.ts +++ /dev/null @@ -1,7 +0,0 @@ -import "@"; -import f from "@/f"; -import "@something"; -import "./@"; -import "file"; -import { something } from "something"; -import "something/somefile"; diff --git a/packages/react-native-builder-bob/src/__fixtures__/project/code/$alias-output.ts b/packages/react-native-builder-bob/src/__fixtures__/project/code/$alias-output.ts deleted file mode 100644 index 9382b660d..000000000 --- a/packages/react-native-builder-bob/src/__fixtures__/project/code/$alias-output.ts +++ /dev/null @@ -1,7 +0,0 @@ -import ".."; -import f from "../f"; -import "@something"; -import "./@"; -import "../f"; -import { something } from "another"; -import "another/somefile"; diff --git a/packages/react-native-builder-bob/src/__fixtures__/project/code/$exports-input.ts b/packages/react-native-builder-bob/src/__fixtures__/project/code/$exports-input.ts index e489c8d26..edc97fdaf 100644 --- a/packages/react-native-builder-bob/src/__fixtures__/project/code/$exports-input.ts +++ b/packages/react-native-builder-bob/src/__fixtures__/project/code/$exports-input.ts @@ -18,3 +18,25 @@ export const foo = "foo"; const bar = "bar"; export { bar }; + +export * as NativeLibA from "./MyNativeLib"; +export * as NativeLibB from "../MyNativeLib"; +export * as NativeLibC from "./MyNativeLib.ts"; +export * as NativeLibD from "../MyNativeLib.ts"; +export * as NativeLibE from "./MyNativeLib.tsx"; +export * as NativeLibF from "../MyNativeLib.tsx"; +export * as NativeLibG from "./MyNativeLib.js"; +export * as NativeLibH from "../MyNativeLib.js"; +export * as NativeLibI from "./MyNativeLib.jsx"; +export * as NativeLibJ from "../MyNativeLib.jsx"; + +export * as NativeViewA from "./MyNativeComponent"; +export * as NativeViewB from "../MyNativeComponent"; +export * as NativeViewC from "./MyNativeComponent.ts"; +export * as NativeViewD from "../MyNativeComponent.ts"; +export * as NativeViewE from "./MyNativeComponent.tsx"; +export * as NativeViewF from "../MyNativeComponent.tsx"; +export * as NativeViewG from "./MyNativeComponent.js"; +export * as NativeViewH from "../MyNativeComponent.js"; +export * as NativeViewI from "./MyNativeComponent.jsx"; +export * as NativeViewJ from "../MyNativeComponent.jsx"; diff --git a/packages/react-native-builder-bob/src/__fixtures__/project/code/$exports-output.ts b/packages/react-native-builder-bob/src/__fixtures__/project/code/$exports-output.ts index d923ac3ec..9f7dad834 100644 --- a/packages/react-native-builder-bob/src/__fixtures__/project/code/$exports-output.ts +++ b/packages/react-native-builder-bob/src/__fixtures__/project/code/$exports-output.ts @@ -13,3 +13,23 @@ export type { A } from "./a"; export const foo = "foo"; const bar = "bar"; export { bar }; +export * as NativeLibA from "./MyNativeLib"; +export * as NativeLibB from "../MyNativeLib"; +export * as NativeLibC from "./MyNativeLib.ts"; +export * as NativeLibD from "../MyNativeLib.ts"; +export * as NativeLibE from "./MyNativeLib.tsx"; +export * as NativeLibF from "../MyNativeLib.tsx"; +export * as NativeLibG from "./MyNativeLib.js"; +export * as NativeLibH from "../MyNativeLib.js"; +export * as NativeLibI from "./MyNativeLib.jsx"; +export * as NativeLibJ from "../MyNativeLib.jsx"; +export * as NativeViewA from "./MyNativeComponent"; +export * as NativeViewB from "../MyNativeComponent"; +export * as NativeViewC from "./MyNativeComponent.ts"; +export * as NativeViewD from "../MyNativeComponent.ts"; +export * as NativeViewE from "./MyNativeComponent.tsx"; +export * as NativeViewF from "../MyNativeComponent.tsx"; +export * as NativeViewG from "./MyNativeComponent.js"; +export * as NativeViewH from "../MyNativeComponent.js"; +export * as NativeViewI from "./MyNativeComponent.jsx"; +export * as NativeViewJ from "../MyNativeComponent.jsx"; diff --git a/packages/react-native-builder-bob/src/__fixtures__/project/code/$imports-input.ts b/packages/react-native-builder-bob/src/__fixtures__/project/code/$imports-input.ts index bc1c23d79..6658587ac 100644 --- a/packages/react-native-builder-bob/src/__fixtures__/project/code/$imports-input.ts +++ b/packages/react-native-builder-bob/src/__fixtures__/project/code/$imports-input.ts @@ -14,3 +14,25 @@ import * as b1 from "./b"; import something, { c as c1 } from "./c"; import type { A } from "./a"; + +import "./MyNativeLib"; +import "../MyNativeLib"; +import "./MyNativeLib.ts"; +import "../MyNativeLib.ts"; +import "./MyNativeLib.tsx"; +import "../MyNativeLib.tsx"; +import "./MyNativeLib.js"; +import "../MyNativeLib.js"; +import "./MyNativeLib.jsx"; +import "../MyNativeLib.jsx"; + +import "./MyNativeComponent"; +import "../MyNativeComponent"; +import "./MyNativeComponent.ts"; +import "../MyNativeComponent.ts"; +import "./MyNativeComponent.tsx"; +import "../MyNativeComponent.tsx"; +import "./MyNativeComponent.js"; +import "../MyNativeComponent.js"; +import "./MyNativeComponent.jsx"; +import "../MyNativeComponent.jsx"; diff --git a/packages/react-native-builder-bob/src/__fixtures__/project/code/$imports-output.ts b/packages/react-native-builder-bob/src/__fixtures__/project/code/$imports-output.ts index 029bf9492..d9f287e10 100644 --- a/packages/react-native-builder-bob/src/__fixtures__/project/code/$imports-output.ts +++ b/packages/react-native-builder-bob/src/__fixtures__/project/code/$imports-output.ts @@ -12,3 +12,23 @@ import { a as a1 } from "./a.mjs"; import * as b1 from "./b.mjs"; import something, { c as c1 } from "./c.mjs"; import type { A } from "./a"; +import "./MyNativeLib"; +import "../MyNativeLib"; +import "./MyNativeLib.ts"; +import "../MyNativeLib.ts"; +import "./MyNativeLib.tsx"; +import "../MyNativeLib.tsx"; +import "./MyNativeLib.js"; +import "../MyNativeLib.js"; +import "./MyNativeLib.jsx"; +import "../MyNativeLib.jsx"; +import "./MyNativeComponent"; +import "../MyNativeComponent"; +import "./MyNativeComponent.ts"; +import "../MyNativeComponent.ts"; +import "./MyNativeComponent.tsx"; +import "../MyNativeComponent.tsx"; +import "./MyNativeComponent.js"; +import "../MyNativeComponent.js"; +import "./MyNativeComponent.jsx"; +import "../MyNativeComponent.jsx"; diff --git a/packages/react-native-builder-bob/src/babel.ts b/packages/react-native-builder-bob/src/babel.ts index 6e75acf73..4abf45a90 100644 --- a/packages/react-native-builder-bob/src/babel.ts +++ b/packages/react-native-builder-bob/src/babel.ts @@ -6,6 +6,7 @@ import type { ExportAllDeclaration, ExportNamedDeclaration, } from '@babel/types'; +import { isCodegenSpec } from './utils/isCodegenSpec'; type Options = { /** @@ -24,6 +25,8 @@ type Options = { platforms?: string[]; }; +const extensions = ['ts', 'tsx', 'js', 'jsx']; + const isFile = (filename: string): boolean => { const exists = fs.lstatSync(filename, { throwIfNoEntry: false })?.isFile() ?? false; @@ -38,12 +41,12 @@ const isDirectory = (filename: string): boolean => { return exists; }; -const isModule = ( +const isModuleWithoutPlatform = ( filename: string, extension: string, platforms: string[] ): boolean => { - const exts = ['js', 'ts', 'jsx', 'tsx', extension]; + const exts = [...extensions, extension]; return exts.some( (ext) => @@ -86,6 +89,8 @@ export default function ( ): PluginObj { api.assertVersion(7); + const codegenEnabled = api.caller((caller) => caller?.codegenEnabled); + function addExtension( { node, @@ -106,12 +111,20 @@ export default function ( assertFilename(state.filename); - // Skip folder imports const filename = path.resolve( path.dirname(state.filename), node.source.value ); + // Skip imports for codegen spec if codegen is enabled + if ( + codegenEnabled && + (isCodegenSpec(filename) || + extensions.some((ext) => isCodegenSpec(`${filename}.${ext}`))) + ) { + return; + } + // Replace .ts extension with .js if file with extension is explicitly imported if (isFile(filename)) { node.source.value = node.source.value.replace(/\.tsx?$/, `.${extension}`); @@ -119,7 +132,8 @@ export default function ( } // Add extension if .ts file or file with extension exists - if (isModule(filename, extension, platforms)) { + // And no platform specific file exists + if (isModuleWithoutPlatform(filename, extension, platforms)) { node.source.value += `.${extension}`; return; } @@ -127,7 +141,11 @@ export default function ( // Expand folder imports to index and add extension if ( isDirectory(filename) && - isModule(path.join(filename, 'index'), extension, platforms) + isModuleWithoutPlatform( + path.join(filename, 'index'), + extension, + platforms + ) ) { node.source.value = node.source.value.replace( /\/?$/, diff --git a/packages/react-native-builder-bob/src/types.ts b/packages/react-native-builder-bob/src/types.ts index 9a8b7419e..4a6ac6d8a 100644 --- a/packages/react-native-builder-bob/src/types.ts +++ b/packages/react-native-builder-bob/src/types.ts @@ -31,5 +31,6 @@ declare module '@babel/core' { export interface TransformCaller { rewriteImportExtensions: boolean; jsxRuntime: 'automatic' | 'classic'; + codegenEnabled: boolean; } } diff --git a/packages/react-native-builder-bob/src/utils/compile.ts b/packages/react-native-builder-bob/src/utils/compile.ts index 0f4df9a91..5b4a0b90b 100644 --- a/packages/react-native-builder-bob/src/utils/compile.ts +++ b/packages/react-native-builder-bob/src/utils/compile.ts @@ -4,6 +4,7 @@ import kleur from 'kleur'; import * as babel from '@babel/core'; import glob from 'glob'; import type { Input } from '../types'; +import { isCodegenSpec } from './isCodegenSpec'; type Options = Input & { esm?: boolean; @@ -98,6 +99,14 @@ export default async function compile({ } const content = await fs.readFile(filepath, 'utf-8'); + + // If codegen is used in the app, then we need to preserve TypeScript source + // So we copy the file as is instead of transforming it + if (isCodegenSpec(filepath)) { + fs.copy(filepath, path.join(output, path.relative(source, filepath))); + return; + } + const result = await babel.transformAsync(content, { caller: { name: 'react-native-builder-bob', @@ -108,6 +117,7 @@ export default async function compile({ : false, rewriteImportExtensions: esm, jsxRuntime, + codegenEnabled: 'codegenConfig' in pkg, }, cwd: root, babelrc: babelrc, diff --git a/packages/react-native-builder-bob/src/utils/isCodegenSpec.ts b/packages/react-native-builder-bob/src/utils/isCodegenSpec.ts new file mode 100644 index 000000000..1291e5042 --- /dev/null +++ b/packages/react-native-builder-bob/src/utils/isCodegenSpec.ts @@ -0,0 +1,5 @@ +export const isCodegenSpec = (filepath: string) => { + return /(?:^|[\\/])(?:Native\w+|(\w+)NativeComponent)\.[jt]sx?$/i.test( + filepath + ); +};