From a299111915c32b25ce013bd9d478df824d9bca8f Mon Sep 17 00:00:00 2001 From: LongYinan Date: Wed, 10 Apr 2024 23:31:59 +0800 Subject: [PATCH] fix: canonicalize is not supported on wasi target (#124) --- .github/workflows/ci.yml | 4 ++++ napi/__test__/resolver.spec.mjs | 32 ++++++++++++++++++++++++++++++-- src/file_system.rs | 29 ++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b905684a..5ac3230d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,6 +84,10 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Install fixtures dependencies + working-directory: fixtures/pnpm8 + run: pnpm install --frozen-lockfile + - name: Build run: | rustup target add wasm32-wasi-preview1-threads diff --git a/napi/__test__/resolver.spec.mjs b/napi/__test__/resolver.spec.mjs index f17dd294..42bafba9 100644 --- a/napi/__test__/resolver.spec.mjs +++ b/napi/__test__/resolver.spec.mjs @@ -1,4 +1,4 @@ -import { join, sep } from 'node:path' +import { join } from 'node:path' import { fileURLToPath } from 'node:url' import test from 'ava' @@ -217,7 +217,7 @@ for (const [title, context, request, expected] of [ 'handle fragment escaping', enhancedResolveRoot, './no\0#fragment/\0#/\0##fragment', - join(enhancedResolveRoot, 'no#fragment','#', '#.js#fragment'), + join(enhancedResolveRoot, 'no#fragment', '#', '#.js#fragment'), ], ]) { test(title, (t) => { @@ -229,3 +229,31 @@ for (const [title, context, request, expected] of [ t.is(resolver.sync(context, request).path, expected) }) } + +test('resolve pnpm package', (t) => { + const pnpmProjectPath = join(currentDir, '..', '..', 'fixtures', 'pnpm8') + const resolver = new ResolverFactory({ + aliasFields: ['browser'], + }) + t.deepEqual(resolver.sync(pnpmProjectPath, 'styled-components'), { + path: join( + pnpmProjectPath, + 'node_modules/.pnpm/styled-components@6.1.1_react-dom@18.2.0_react@18.2.0/node_modules/styled-components/dist/styled-components.browser.cjs.js' + ), + }) + t.deepEqual( + resolver.sync( + join( + pnpmProjectPath, + 'node_modules/.pnpm/styled-components@6.1.1_react-dom@18.2.0_react@18.2.0/node_modules/styled-components' + ), + 'react' + ), + { + path: join( + pnpmProjectPath, + 'node_modules/.pnpm/react@18.2.0/node_modules/react/index.js' + ), + } + ) +}) diff --git a/src/file_system.rs b/src/file_system.rs index 95c504ef..2b9c15e3 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -91,6 +91,33 @@ impl FileSystem for FileSystemOs { } fn canonicalize(&self, path: &Path) -> io::Result { - dunce::canonicalize(path) + #[cfg(not(target_os = "wasi"))] + { + dunce::canonicalize(path) + } + #[cfg(target_os = "wasi")] + { + let meta = fs::symlink_metadata(path)?; + if meta.file_type().is_symlink() { + let link = fs::read_link(path)?; + let mut path_buf = path.to_path_buf(); + path_buf.pop(); + for segment in link.iter() { + match segment.to_str() { + Some("..") => { + path_buf.pop(); + } + Some(".") | None => {} + Some(seg) => { + // Need to trim the extra \0 introduces by rust std rust-lang/rust#123727 + path_buf.push(seg.trim_end_matches('\0')); + } + } + } + Ok(path_buf) + } else { + Ok(path.to_path_buf()) + } + } } }