Skip to content

feat: support custom source map implemetation - #1289

Open
intellild wants to merge 5 commits into
parcel-bundler:masterfrom
intellild:codex/perf-minify
Open

feat: support custom source map implemetation#1289
intellild wants to merge 5 commits into
parcel-bundler:masterfrom
intellild:codex/perf-minify

Conversation

@intellild

Copy link
Copy Markdown

Summary

This refactors CSS printing so ToCss depends on a sealed printer trait instead of the concrete Printer<W, S> type. It also splits source map writing behind custom_sourcemap, while keeping the existing sourcemap feature backed by Parcel source maps for current users.

Why

Bundlers such as Rspack already have their own source map representation. Previously, they had to generate a Parcel source map from Lightning CSS output and then translate it back into their own source map type.

With this change, those consumers can provide a custom source map writer directly.

This has two benefits:

  • Reduces binary size by avoiding the built-in Parcel source map implementation when it is not needed.
  • Improves CSS printing performance by avoid source map translation.

In Rspack CI, this reduced the binary by about 400 KB:
https://github.com/web-infra-dev/rspack/actions/runs/28227945651/job/83627257783?pr=14581

Release builds are estimated to save around 300 KB.

Compatibility

The default sourcemap feature still uses Parcel source maps, so existing Lightning CSS users should keep the same public behavior.

Consumers that want to avoid the built-in Parcel implementation can enable custom_sourcemap and provide their own writer.

Validation

Checked the library with and without custom source maps, including no-default-feature and serde-only configurations.

@intellild
intellild force-pushed the codex/perf-minify branch from 4555289 to f20d60e Compare June 29, 2026 07:51
@devongovett

Copy link
Copy Markdown
Member

Sounds like a good idea. I'll look more in depth soon.

@intellild

Copy link
Copy Markdown
Author

@devongovett Should we maintain rust API compatibility across the 1.0.0 beta releases?

@devongovett

Copy link
Copy Markdown
Member

no don't worry about that.

@intellild
intellild marked this pull request as ready for review September 7, 2026 02:42
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-07T02:47:23.464685Z 59cfeb7 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59cfeb7caf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/rules/style.rs Outdated
Comment on lines 323 to 325
dest.write_char('\n')?;
}
dest.newline()?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore the selector context before propagating errors

When writing a hoisted nested rule fails, either through the destination writer or a custom at-rule's ToCss implementation, these ? operators return directly from to_css_base before line 332 restores parent. The printer is therefore left holding a raw pointer to the stack-local ctx; reusing it after the recoverable error can dereference a dangling pointer during selector serialization. Run this block inside a closure or use a guard so the context is restored on every error path.

Useful? React with 👍 / 👎.

Comment thread src/printer.rs Outdated
Comment on lines +579 to +580
let content = sm.get_source_content(orig.source).unwrap().to_owned();
map.set_source_content(source_index, &content);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Cache remapped source content instead of copying per mapping

When an inline input source map is present, add_mapping now clones and sets the complete original source content for every generated mapping. The previous implementation guarded this operation so it happened only when the source was newly added; with a large Sass/Less source and thousands of mappings, the new path performs roughly mapping_count × source_size copying and can cause extreme allocation and runtime growth. Track which output source indices have already received content and set each only once.

Useful? React with 👍 / 👎.

Comment thread src/printer.rs Outdated
original.source = source_index;
original.name = name;

let content = sm.get_source_content(orig.source).unwrap().to_owned();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Handle input maps that omit embedded source content

For a custom SourceMap whose from_data_url accepts a map without embedded source content, find_closest_mapping can validly return a location while get_source_content returns None, as allowed by the new trait's Option return type. This unwrap then panics while serializing otherwise valid mapped CSS. Skip setting the content when it is absent rather than requiring every custom input map to contain it.

Useful? React with 👍 / 👎.

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