Skip to content

Conversation

@686f6c61
Copy link

What?

Adds support for TypeScript/JavaScript path aliases in Sass @use and @import statements.

Why?

Fixes #87161

Path aliases starting with # (Node.js package imports convention) or @ were not recognized by Sass, causing build failures with error: "The default namespace '' is not a valid Sass identifier"

The issue occurs because Sass processes imports before webpack's module resolution, so it does not have access to path mappings defined in tsconfig.json or jsconfig.json.

How?

Implemented a custom Sass importer that:

  1. Reads path alias mappings from tsconfig.json/jsconfig.json via ConfigurationContext
  2. Intercepts import URLs in Sass files before the Sass compiler processes them
  3. Matches import URLs against configured patterns (exact and wildcard)
  4. Resolves aliases to absolute file system paths using the same logic as webpack
  5. Handles Sass conventions (file extensions, partial files with _)
  6. Returns file:// URLs that Sass can process

The solution works for both Webpack and Turbopack builds.

Test Plan

Added comprehensive e2e test in test/e2e/app-dir/sass-path-aliases/ that verifies:

  • Build succeeds with path aliases starting with #
  • Sass compilation completes without errors
  • Generated CSS is correctly applied

Manual testing with reproduction repository: https://github.com/porada/next-sass-path-alias-issue

Sass was unable to resolve TypeScript path aliases that start with
special characters like # (Node.js imports convention) or @ in @use
and @import statements. This caused build failures with the error:
'The default namespace "" is not a valid Sass identifier'

The root cause is that Sass processes imports before webpack's module
resolution, so it does not have access to the path mappings defined
in tsconfig.json or jsconfig.json. When Sass encounters an import like
@use "#stylesheets/variables", it tries to interpret the # as part
of a Sass identifier, which is invalid syntax.

This commit adds a custom Sass importer that:

1. Reads the path alias mappings from tsconfig.json/jsconfig.json
   through the existing ConfigurationContext

2. Intercepts import URLs in Sass files before they reach the Sass
   compiler

3. Matches import URLs against configured path patterns, supporting
   both exact matches and wildcard patterns (e.g., "#styles/*")

4. Resolves aliases to absolute file system paths using the same
   pattern matching logic as webpack (jsconfig-paths-plugin)

5. Handles Sass-specific conventions like file extensions (.scss,
   .sass, .css) and partial files (files prefixed with _)

6. Returns file:// URLs that Sass can process directly

Implementation details:

- Created packages/next/src/build/webpack/loaders/sass-importer.ts
  with the custom Sass importer implementation

- Modified packages/next/src/build/webpack/config/blocks/css/index.ts
  to instantiate and integrate the importer into sass-loader options

- Updated packages/next/src/build/webpack/config/utils.ts to add
  jsConfig and resolvedBaseUrl to the ConfigurationContext type

- Modified packages/next/src/build/webpack/config/index.ts to accept
  and pass jsConfig and resolvedBaseUrl parameters

- Updated packages/next/src/build/webpack-config.ts to pass the
  jsConfig and resolvedBaseUrl from loadJsConfig to buildConfiguration

The solution works for both Webpack and Turbopack builds since both
execute webpack loaders through Node.js.

Added comprehensive e2e test in test/e2e/app-dir/sass-path-aliases/
that verifies:
- Build succeeds with path aliases starting with #
- Sass compilation completes without errors
- Generated CSS is correctly applied to elements

Fixes #87161
@nextjs-bot
Copy link
Collaborator

Allow CI Workflow Run

  • approve CI run for commit: 5d51e90

Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer

1 similar comment
@nextjs-bot
Copy link
Collaborator

Allow CI Workflow Run

  • approve CI run for commit: 5d51e90

Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer

@porada
Copy link

porada commented Dec 16, 2025

Thanks for handling this!

@686f6c61 686f6c61 closed this by deleting the head repository Dec 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sass breaks when path aliases start with #

3 participants