Skip to content

Fix/919 css sourcemaps v3#921

Merged
robruiz merged 8 commits intowprig:developfrom
erdmann040:fix/919-css-sourcemaps-v3
Sep 15, 2025
Merged

Fix/919 css sourcemaps v3#921
robruiz merged 8 commits intowprig:developfrom
erdmann040:fix/919-css-sourcemaps-v3

Conversation

@erdmann040
Copy link
Contributor

@erdmann040 erdmann040 commented Sep 10, 2025

Description

Addresses issue #919

Sourcemaps for compiled CSS pointed to the top-level importer instead of the actual source files. In DevTools this made it hard to jump to the rule’s true origin. Additionally, configuration-driven preloads (custom media, etc.) had to be injected without breaking @import ordering.

What this PR does

  • Switches the CSS pipeline to LightningCSS bundleAsync() so @import trees are resolved correctly and sourcemaps retain original sources.
  • Introduces a virtual preload import that concatenates configured preload files once and inserts them after the top-level @import block. This preserves CSS ordering while keeping the preloads effective.
  • Derives LightningCSS targets from the project Browserslist (env-aware via BROWSERSLIST_ENV), ensuring output matches the supported browsers.
  • Renames dev.styles.importFromdev.styles.preload (clearer naming); keeps backward compatibility by still honoring importFrom with a deprecation warning.
  • Continues to read merged configuration via themeConfig so overrides from config.json / config.local.json are respected.

Why this works

  • Bundling with LightningCSS preserves file identity in the map; DevTools can now navigate to the correct original file & line.
  • The virtual preload avoids mutating real sources and prevents late @import violations while still applying project preloads consistently.
  • Browserslist-driven targets keep transpilation in sync with the project’s supported environments.

List of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Detailed changes

  • Switched from transform() to bundleAsync() to preserve file identity in sourcemaps.
  • Added virtual import mechanism so preloaded CSS files (e.g. _custom-media.css) appear correctly without breaking @import order.
  • Introduced dev.styles.preload in config. Old importFrom still works but triggers a deprecation warning.
  • Removed temporary debug logging.
  • Browser targets now pulled dynamically from Browserslist config instead of hardcoding.

How to test

  1. Build assets

    npm run build:css
    • Verify that assets/css/*.min.css and assets/css/editor/*.min.css are generated.
    • Check that each has a .map file and ends with a /*# sourceMappingURL=... */ comment.
  2. Verify sourcemaps in DevTools

    • Run npm run dev and open the site in a browser.
    • In DevTools, inspect a style (e.g. from global.css).
    • Expected: The “jump to definition” goes to the correct partial (_typography.css, _elements.css, etc.), not the top-level importer.
  3. Check preload handling

    • If the main menu works on both small and large viewports, the _custom-media.css is available in compiled outputs. Maybe check also, that the preload-config works with other files as well.
  4. Check Browserslist targets

    • Run two builds with different environments:
     //.browserslistrc
    > 1%
    last 2 versions
    
    [modern]
    last 1 chrome version
    last 1 firefox version
    last 1 safari version
    
    [legacy]
    ios_saf 12
    safari 12
     BROWSERSLIST_ENV=modern npm run build:css && cp assets/css/global.min.css global.modern.css
     BROWSERSLIST_ENV=legacy npm run build:css && cp assets/css/global.min.css global.legacy.css
     diff -u global.modern.css global.legacy.css | head -n 80
  • Expected: Differences in features like media query syntax (min-width vs. width>=), flexbox/grid prefixes, etc.
  1. Deprecated config key
    • Temporarily set dev.styles.importFrom in config.local.json (instead of preload).
    • Run the build.
    • Expected: It still works, but a warning is logged:
      ⚠️ dev.styles.importFrom is deprecated, please use dev.styles.preload instead.

Checklist:

…erated

This ensures that browsers can automatically locate the corresponding .map
file, improving debugging capabilities in development mode.
…n dev/build BROKEN

Migrate CSS pipeline to LightningCSS bundleAsync to properly resolve @import and generate accurate source maps. This is a conceptual shift away from transform().

⚠️ CURRENT STATUS: BROKEN ⚠️

- npm run dev: ❌ fails

- npm run build: ❌ fails

Reason: follow-up work is required to integrate config-driven custom-media preload (_custom-media.css) without violating CSS @import ordering. Until resolved, the parser may throw errors and DevTools may still reference the top-level importer.

Next steps:

1) Ensure @import ordering is preserved across all files.

2) Insert custom-media after the top-level import block (or use a virtual import solution).

3) Keep sourceMap + sourceMapIncludeSources; append sourceMappingURL at the end of CSS.

Note: This commit intentionally isolates the architectural change so that subsequent fixes can be reviewed independently.
…rcemaps

Use LightningCSS bundler with a virtual import (virtual:preload.css) that
concatenates all files listed in dev.styles.importFrom. This ensures that
custom media, properties, etc. are injected once at the correct position
without breaking @import ordering.

Also:
- Replace hardcoded _custom-media.css handling
- Keep strict dev guard to detect late @import usage
- Emit source maps with explicit sourceMappingURL comment
The old name "importFrom" was a leftover from PostCSS times and is now
deprecated. Use the clearer "preload" key instead. For backwards
compatibility, "importFrom" is still supported but will emit a warning.
Drop leftover console.log of sourcemap sources that was only useful
during debugging. Now only warnings are emitted on parse failure or
empty sources.
@erdmann040 erdmann040 requested a review from robruiz as a code owner September 10, 2025 11:16
@erdmann040 erdmann040 changed the base branch from master to develop September 10, 2025 11:18
@erdmann040
Copy link
Contributor Author

@robruiz ChatGPT was very helpful to me here. I believe there is still room for improvement in the code. A large part of the complexity seems to come from preloading _custom-media.css. Is this actually necessary? I vaguely remember that Custom Media Queries have some special role, but I can’t recall exactly what it was or why.

If preloading is not required, we might want to consider simply importing _custom-media.css where it’s needed. That could potentially simplify the code quite a bit.

I also find the non-minified *.min.css files and the separate maps a bit confusing, even though I’m sure there were good reasons for this setup. I wonder if it might make sense to make that configurable.

@erdmann040 erdmann040 force-pushed the fix/919-css-sourcemaps-v3 branch from 6089dab to 210aee2 Compare September 10, 2025 11:52
@erdmann040
Copy link
Contributor Author

erdmann040 commented Sep 12, 2025

While dogfooding my own PR, I noticed that it worked fine for a long time, but then suddenly got out of step and started linking incorrectly. In this case, deleting the *.min.css and *.min.css.map files helped.

# Conflicts:
#	package-lock.json
#	package.json
@robruiz robruiz merged commit 3d3760e into wprig:develop Sep 15, 2025
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