Skip to content

CSS @import doesn't resolve via package.json exports field (e.g. shadcn style condition) #261

@VidhyaKumar

Description

@VidhyaKumar

What happened?

When a .css file does a bare-package @import whose target requires package.json#exports resolution (instead of mapping to node_modules/<pkg>/<file> directly), fallow reports it in unresolved_imports even though the file exists and bundlers resolve it correctly.

Concretely, on fallow 2.62.0 and the published shadcn@4.6.0:

/* apps/web/src/index.css */
@import "shadcn/tailwind.css";

is reported as:

{
  "path": "apps/web/src/index.css",
  "specifier": "shadcn/tailwind.css",
  "line": 1
}

The actual file lives at node_modules/shadcn/dist/tailwind.css and is exposed only via the package's exports map under the style condition:

{
  "exports": {
    "./tailwind.css": { "style": "./dist/tailwind.css" }
  }
}

Tailwind v4 / Vite / PostCSS resolve this correctly. Fallow's CSS resolver appears to look up node_modules/shadcn/tailwind.css directly without consulting exports, so it can't find the file.

This is distinct from #252 (closed v2.60.0), which fixed bare-package CSS imports whose target sits at node_modules/<pkg>/<file> with no exports indirection.

Reproduction

mkdir repro-css-exports && cd repro-css-exports
cat > package.json <<'PKG'
{ "name": "repro", "private": true, "dependencies": { "shadcn": "4.6.0" } }
PKG
npm install
mkdir src
echo '@import "shadcn/tailwind.css";' > src/index.css
cat > src/entry.ts <<'TS'
import "./index.css";
export const main = () => {};
TS
cat > tsconfig.json <<'TSC'
{ "compilerOptions": { "module": "esnext", "moduleResolution": "bundler" }, "include": ["src"] }
TSC
fallow dead-code --format json --quiet

Output contains:

"unresolved_imports": [
  { "path": "src/index.css", "specifier": "shadcn/tailwind.css", "line": 1, "col": 0, "specifier_col": 0 }
]

Verify the file is real:

ls node_modules/shadcn/dist/tailwind.css   # exists
node -e 'console.log(require("shadcn/package.json").exports["./tailwind.css"])'
# { style: './dist/tailwind.css' }

Expected behavior

CSS resolver follows package.json#exports (honoring the style condition, falling back to default) the same way Vite / Tailwind v4 do. Specifier should resolve to node_modules/shadcn/dist/tailwind.css and not surface in unresolved_imports.

Secondary bug (same repro)

When shadcn is added to ignoreDependencies to silence the cascading "unused dep" finding, the dependency is correctly filtered from the unused_dependencies array but the summary.unused_dependencies count is not decremented. total_issues and the array contents disagree:

"total_issues": 2,
"summary": { "unused_dependencies": 1, "unresolved_imports": 1, ... },
"unused_dependencies": [],         // empty
"unresolved_imports": [ ... ]      // 1 entry

Happy to split into two issues if preferred.

Fallow version

2.62.0

Operating system

macOS

Configuration

{
  "ignorePatterns": ["apps/web/src/components/ui/**"],
  "entry": ["apps/web/src/start.ts", "packages/backend/tests/**/*.test.ts"],
  "ignoreDependencies": ["shadcn", "input-otp", "next-themes", "react-day-picker"]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions