Skip to content

Add support for CSS preprocessors - #5

Merged
remcohaszing merged 15 commits into
remcohaszing:mainfrom
mrmckeb:monorepo
Oct 31, 2026
Merged

remcohaszing merged 15 commits into
remcohaszing:mainfrom
mrmckeb:monorepo

Conversation

@mrmckeb

@mrmckeb mrmckeb commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

This is a draft implementation for early feedback.

Notes and decisions:

  • Both sass and sass-embedded are supported, but the latter is preferred for performance reasons. Vite also recommends the embedded package.
  • This compiles with sass and maps classes back through source maps, rather than parsing statically. This allows us to handle nesting, &-suffix, #{}, loops and mixins the same way that a build does.
  • The adapter owns the source map, via originalPositionFor.
  • The adapter also owns the language's lexical rules, through a Syntax object.
  • Core owns the class lookup, previews and the protocol.
  • On a compiler failure, the mapper keeps the last good output, without mappings, and reports a diagnostic. Anything an adapter throws is handled the same way.
  • Classes from other files (partials and mixins) are typed but have no "Go to Definition" support, since a content mapper maps to a single file. I think this is fine for now.
  • I've added in a few strictness TypeScript strict checks - noUncheckedIndexedAccess, exactOptionalPropertyTypes and noImplicitOverride are on - but happy to remove those if you're not a fan.
  • Both packages declare Node 22, 24 and 26 in engines, and @types/node is set to 22 so that we don't accidentally use a newer API. CI tests Node 24 and 26.
  • Sass deprecations logs are suppressed, as the user should be seeing those in builds anyway.

Open questions:

  1. The tests harnesses are very similar. Should we extract this out now, and if so, should we ship it from the core package (i.e. ./testing)?
  2. The protocol's watchedFiles is set per project, so changes to partials don't refresh types in editors. Should we raise per-transform dependencies with the TypeScript team?
  3. Are you OK if we add tests using tsc --lsp in a follow-up?
  4. Did you want tests covering the minimum supported version of Sass? If so, any thoughts on the best way to approach that?
  5. When ready, how would you like to merge this? The first commit is the restructuring, to preserve history.

@mrmckeb
mrmckeb marked this pull request as draft October 27, 2026 12:49
@mrmckeb mrmckeb changed the title Monorepo Add support for CSS preprocessors Oct 27, 2026
Comment thread .github/workflows/ci.yaml Resolved
Comment thread packages/sass-content-mapper/LICENSE.md Resolved
@mrmckeb
mrmckeb marked this pull request as ready for review October 28, 2026 12:27

@remcohaszing remcohaszing left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added in a few strictness TypeScript strict checks - noUncheckedIndexedAccess, exactOptionalPropertyTypes and noImplicitOverride are on

I accidentally removed them while refactoring. We can discuss more TypeScript options in a follow-up. Let’s keep this focused for now.

The tests harnesses are very similar. Should we extract this out now, and if so, should we ship it from the core package

I extracted some things and made abstractions in content-mapper-test-utils. I did have some issues integrating them here though, because of the specific proc args you used. Please let me know if you can use that, and if there’s room for improvement.

The protocol's watchedFiles is set per project, so changes to partials don't refresh types in editors. Should we raise per-transform dependencies with the TypeScript team?

TBH I think this feature is stretching the scope of content mappers. You can raise the issue, but I wouldn’t be surprised if it gets closed.

If we really want to do this correctly, we could process Sass imports and convert them to TypeScript imports in the virtual files. Then we could even map class names to external files. This is a way more advanced feature though, as it requires more knowledge of parsing and resolving Sass.

Are you OK if we add tests using tsc --lsp in a follow-up?

Yep! But also let’s see how much that adds first. We don’t use the most advanced LSP features here, only definitions.

Did you want tests covering the minimum supported version of Sass? If so, any thoughts on the best way to approach that?

I haven’t thought of that. For now I think it’s fine to only test one version. Maybe stick with the oldest one supported?

When ready, how would you like to merge this? The first commit is the restructuring, to preserve history.

I already merged some changes into main. I think the PR is currently in pretty good shape when it comes to focus. So let’s merge this when ready. The PR does need a changeset now. 😉

Comment thread package.json Resolved
Comment thread .github/workflows/ci.yaml Outdated
node-version-file: package.json
- run: npm ci
- run: npx tsc
- run: npm --workspaces exec -- tsc --build

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted this specific line.

If you use npm --workspaces run / npm --workspaces exec, the command is run for each workspace. This has a couple of downsides.

  • A command is spawned for every workspace.
  • The CWD is set to the workspace, which often affects logging of relative paths.

A lot of tools support a monorepo setup, including TypeScript. TypeScript supports this using project references, which is configured in the root tsconfig.json.

If you configure tools like that, you typically get:

  • Better performance (TypeScript 7 can even parallelize builds now)
  • Better third party tooling integration (editor integration for some tooling picks up a config file in the repo root)
  • Correct relative paths (which VSCode and my terminal emulator turn into links)

@mrmckeb mrmckeb Oct 31, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I think I missed that you'd added project references. I've used them before and agree that they're a great way to keep monorepos fast - thanks for picking that up!

@remcohaszing
remcohaszing merged commit fe8dcfa into remcohaszing:main Oct 31, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants