From 9616417cb5c78ef3eae234b831c6aa425979f34b Mon Sep 17 00:00:00 2001 From: LongYinan Date: Sat, 13 Jul 2024 14:42:56 +0800 Subject: [PATCH] fix(core): resolve .cjs/.cts file in esm pacakge (#7) --- packages/core/index.d.ts | 2 +- packages/integrate-ava/package.json | 3 + packages/integrate-ava/tsconfig.json | 2 + .../integrate-module-bundler/src/common.cjs | 1 + .../integrate-module-bundler/src/common.d.cts | 1 + .../integrate-module-bundler/src/index.ts | 5 ++ .../integrate-module-bundler/tsconfig.json | 1 + src/lib.rs | 76 ++++++++++++++----- 8 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 packages/integrate-module-bundler/src/common.cjs create mode 100644 packages/integrate-module-bundler/src/common.d.cts diff --git a/packages/core/index.d.ts b/packages/core/index.d.ts index 6d1b155..c6817a8 100644 --- a/packages/core/index.d.ts +++ b/packages/core/index.d.ts @@ -49,5 +49,5 @@ export interface ResolveFnOutput { importAttributes?: Record | null } -export declare function transform(path: string, code: string): Output +export declare function transform(path: string, code: string | Uint8Array): Output diff --git a/packages/integrate-ava/package.json b/packages/integrate-ava/package.json index 7c3a171..171dc19 100644 --- a/packages/integrate-ava/package.json +++ b/packages/integrate-ava/package.json @@ -17,6 +17,9 @@ "nodeArguments": [ "--import", "@oxc-node/core/register" + ], + "files": [ + "__tests__/**/*.spec.ts" ] } } diff --git a/packages/integrate-ava/tsconfig.json b/packages/integrate-ava/tsconfig.json index 834557e..85c8e50 100644 --- a/packages/integrate-ava/tsconfig.json +++ b/packages/integrate-ava/tsconfig.json @@ -6,5 +6,7 @@ "module": "ESNext", "moduleResolution": "Bundler" }, + "include": ["__tests__/**/*.ts"], + "exclude": ["__tests__/fixtures/**/*"], "references": [{ "path": "../core" }] } diff --git a/packages/integrate-module-bundler/src/common.cjs b/packages/integrate-module-bundler/src/common.cjs new file mode 100644 index 0000000..5dfaa55 --- /dev/null +++ b/packages/integrate-module-bundler/src/common.cjs @@ -0,0 +1 @@ +module.exports.common = 'common' diff --git a/packages/integrate-module-bundler/src/common.d.cts b/packages/integrate-module-bundler/src/common.d.cts new file mode 100644 index 0000000..530ee49 --- /dev/null +++ b/packages/integrate-module-bundler/src/common.d.cts @@ -0,0 +1 @@ +export const common: string diff --git a/packages/integrate-module-bundler/src/index.ts b/packages/integrate-module-bundler/src/index.ts index 6eb0ea7..5a4ae86 100644 --- a/packages/integrate-module-bundler/src/index.ts +++ b/packages/integrate-module-bundler/src/index.ts @@ -8,6 +8,7 @@ import { renderToString } from 'react-dom/server' import { simpleGit } from 'simple-git' import { CompiledClass } from './compiled' +import { common } from './common.cjs' import { foo } from './foo' import { bar } from './subdirectory/bar' import { baz } from './subdirectory/index' @@ -61,3 +62,7 @@ await test('resolve simple-git', () => { await test('import default from babel-generated cjs file', () => { assert.equal(babelGeneratedDoubleDefault.default(), 'default.default') }) + +await test('resolve cjs in type module package', () => { + assert.equal(common, 'common') +}) diff --git a/packages/integrate-module-bundler/tsconfig.json b/packages/integrate-module-bundler/tsconfig.json index 47490ad..57344cb 100644 --- a/packages/integrate-module-bundler/tsconfig.json +++ b/packages/integrate-module-bundler/tsconfig.json @@ -4,6 +4,7 @@ "target": "ESNext", "module": "ESNext", "moduleResolution": "Bundler", + "allowJs": true, "composite": true, "jsx": "react-jsx", "outDir": "dist", diff --git a/src/lib.rs b/src/lib.rs index 5ec8d41..459d84b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -160,16 +160,17 @@ impl Output { } #[napi] -pub fn transform(path: String, code: String) -> Result { +pub fn transform(path: String, code: Either) -> Result { let allocator = Allocator::default(); let src_path = Path::new(&path); let source_type = SourceType::from_path(src_path).unwrap_or_default(); + let source_str = code.try_as_str()?; let ParserReturn { trivias, mut program, errors, .. - } = Parser::new(&allocator, &code, source_type).parse(); + } = Parser::new(&allocator, source_str, source_type).parse(); if !errors.is_empty() { for error in &errors { eprintln!("{}", error); @@ -183,7 +184,7 @@ pub fn transform(path: String, code: String) -> Result { &allocator, src_path, source_type, - &code, + source_str, trivias, Default::default(), ) @@ -352,16 +353,27 @@ pub fn resolve( return Ok(Either::A(ResolveFnOutput { short_circuit: Some(true), format: { - let format = if resolution - .package_json() - .and_then(|p| p.r#type.as_ref()) - .and_then(|t| t.as_str()) - .is_some_and(|t| t == "module") - { - "module".to_owned() - } else { - "commonjs".to_owned() - }; + let format = p + .extension() + .and_then(|ext| ext.to_str()) + .and_then(|ext| { + if ext == "cjs" || ext == "cts" { + None + } else { + resolution + .package_json() + .and_then(|p| p.r#type.as_ref()) + .and_then(|t| t.as_str()) + .and_then(|format| { + if format == "module" { + Some("module".to_owned()) + } else { + None + } + }) + } + }) + .unwrap_or_else(|| "commonjs".to_owned()); tracing::debug!(path = ?p, format = ?format); Either3::A(format) }, @@ -437,15 +449,20 @@ fn oxc_transform(url: String, output: LoadFnOutput) -> Result { let source = output.source.as_ref().unwrap().try_as_str()?; let allocator = Allocator::default(); let src_path = Path::new(&url); - let jsx = src_path - .extension() - .and_then(|ext| ext.to_str()) + let ext = src_path.extension().and_then(|ext| ext.to_str()); + let jsx = ext .map(|ext| ext == "tsx" || ext == "jsx") .unwrap_or_default(); - tracing::debug!(url = ?url, jsx = ?jsx, src_path = ?src_path, "running oxc transform"); + let ts = ext.map(|ext| ext.contains("ts")).unwrap_or_default(); let source_type = match output.format.as_str() { - "commonjs" => SourceType::default().with_script(true).with_jsx(jsx), - "module" => SourceType::default().with_module(true).with_jsx(jsx), + "commonjs" => SourceType::default() + .with_script(true) + .with_typescript(ts) + .with_jsx(jsx), + "module" => SourceType::default() + .with_module(true) + .with_typescript(ts) + .with_jsx(jsx), _ => { return Err(Error::new( Status::InvalidArg, @@ -453,6 +470,7 @@ fn oxc_transform(url: String, output: LoadFnOutput) -> Result { )) } }; + tracing::debug!(url = ?url, jsx = ?jsx, src_path = ?src_path, source_type = ?source_type, "running oxc transform"); let ParserReturn { trivias, mut program, @@ -504,6 +522,20 @@ trait TryAsStr { fn try_as_str(&self) -> Result<&str>; } +impl TryAsStr for Either { + fn try_as_str(&self) -> Result<&str> { + match self { + Either::A(s) => Ok(s), + Either::B(b) => std::str::from_utf8(b).map_err(|err| { + Error::new( + Status::GenericFailure, + format!("Failed to convert &[u8] to &str: {}", err), + ) + }), + } + } +} + impl TryAsStr for Either4 { fn try_as_str(&self) -> Result<&str> { match self { @@ -546,7 +578,11 @@ fn init_resolver() -> Resolver { config_file: tsconfig_full_path, references: TsconfigReferences::Auto, }), - condition_names: vec!["node".to_owned(), "import".to_owned()], + condition_names: vec![ + "node".to_owned(), + "import".to_owned(), + "node-addons".to_owned(), + ], extension_alias: vec![ ( ".js".to_owned(),