Skip to content

chore: update test of @lynx-js/css-extract-webpack-plugin to use real LynxTemplatePlugin#1488

Merged
colinaaa merged 2 commits intolynx-family:mainfrom
upupming:feat/css-extract-test
Aug 12, 2025
Merged

chore: update test of @lynx-js/css-extract-webpack-plugin to use real LynxTemplatePlugin#1488
colinaaa merged 2 commits intolynx-family:mainfrom
upupming:feat/css-extract-test

Conversation

@upupming
Copy link
Collaborator

@upupming upupming commented Aug 11, 2025

In #1033, we used a mocked LynxTemplatePlugin for testing. But it cannot reproduce bugs in complex situation (eg. #1481).

We migrated to use real LynxTemplatePlugin for testing now, it will help add more complex testing cases.

Summary by CodeRabbit

  • Tests

    • Updated CSS hot-update snapshots to reflect larger payloads and new encoded content.
    • Switched test configs to use an absolute dev-server public URL (http://localhost:3000/) for asset resolution.
    • Reworked test plugin provisioning to a getPlugins helper returning configured plugins and aligning with Webpack types.
    • Improved module stubbing to resolve HTTP-style paths to local relative paths in tests.
  • Chores

    • Added a placeholder changeset file.

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (or not required).

@upupming upupming requested a review from colinaaa as a code owner August 11, 2025 12:45
@changeset-bot
Copy link

changeset-bot bot commented Aug 11, 2025

🦋 Changeset detected

Latest commit: 6c76eb0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 11, 2025

📝 Walkthrough

Walkthrough

Updated test infra and snapshots: switched many test configs' output.publicPath to an absolute dev-server URL, remapped HTTP-style require paths to local paths in a helper, refactored test plugin exports to a getPlugins API, and refreshed numerous CSS HMR snapshots with larger payloads.

Changes

Cohort / File(s) Summary of changes
Changeset metadata
./.changeset/cruel-shrimps-say.md
Added empty front-matter file; no code impact.
Require-path remap helper
packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js
In createStubLynx, require() now rewrites paths matching http://<host>:<port>/... to ./... before requiring, altering how remote-style test paths are resolved.
Test plugin refactor
packages/webpack/css-extract-webpack-plugin/test/plugins.js
Replaced mockLynxTemplatePlugin with mockLynxEncodePlugin(), added new export getPlugins({ lynxTemplatePluginOptions }) returning an array of Webpack plugins, adjusted types/exports and removed prior processAssets encoding logic.
Configs switching to getPlugins and publicPath
packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/{rspack.config.js,webpack.config.js}, .../css/basic/{rspack.config.js,webpack.config.js}, .../css/scoped/{rspack.config.js,webpack.config.js}, .../hot-update-json/{default,filename,nested}/{rspack.config.js,webpack.config.js}, .../modules/{basic,export-default}/{rspack.config.js,webpack.config.js}
Updated plugin usage to spread ...getPlugins(...) (option shape changed to lynxTemplatePluginOptions) where applicable; changed output.publicPath from './' to 'http://localhost:3000/' across many test configs.
Snapshot updates (CSS HMR payloads)
packages/webpack/css-extract-webpack-plugin/test/**/__snapshot__/rspack/{0.snap.txt,1.snap.txt,2.snap.txt} (cases: css/basic, css/enable-css-selector, css/scoped, hot-update-json/{default,filename,nested}, modules/{basic,export-default})
Refreshed many rspack snapshots: CSS hot-update JSON sizes increased and base64-encoded content payloads were replaced (deps/order minor differences in some), with surrounding snapshot structures unchanged.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • Sherry-hue
  • hzy

I nibble at localhost’s string,
Hot updates make my whiskers sing,
Plugins gather, neat and spry,
Snapshots bloom and bytes run by,
A rabbit cheers the HMR spring. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link

codecov bot commented Aug 11, 2025

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
3619 1 3618 98
View the full list of 1 ❄️ flaky tests
packages/rspeedy/plugin-qrcode/test/index.test.ts > Plugins - Terminal > schema > custom schema object

Flake rate in main: 20.51% (Passed 31 times, Failed 8 times)

Stack Traces | 3.9s run time
Error: Matcher did not succeed in time.
 ❯ test/index.test.ts:212:53

Caused by: Caused by: Caused by: AssertionError: expected "renderUnicodeCompact" to be called 2 times, but got 1 times

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@codspeed-hq
Copy link

codspeed-hq bot commented Aug 11, 2025

CodSpeed Performance Report

Merging #1488 will not alter performance

Comparing upupming:feat/css-extract-test (6c76eb0) with main (214898b)

Summary

✅ 10 untouched benchmarks

@relativeci
Copy link

relativeci bot commented Aug 11, 2025

React Example

#4055 Bundle Size — 236.88KiB (0%).

6c76eb0(current) vs 214898b main#4047(baseline)

Bundle metrics  no changes
                 Current
#4055
     Baseline
#4047
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 158 158
No change  Duplicate Modules 64 64
No change  Duplicate Code 45.85% 45.85%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#4055
     Baseline
#4047
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.12KiB 91.12KiB

Bundle analysis reportBranch upupming:feat/css-extract-testProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link

relativeci bot commented Aug 11, 2025

Web Explorer

#4050 Bundle Size — 344.11KiB (0%).

6c76eb0(current) vs 214898b main#4042(baseline)

Bundle metrics  Change 1 change
                 Current
#4050
     Baseline
#4042
No change  Initial JS 143.27KiB 143.27KiB
No change  Initial CSS 31.84KiB 31.84KiB
Change  Cache Invalidation 0% 6.71%
No change  Chunks 7 7
No change  Assets 7 7
Change  Modules 211(-0.47%) 212
No change  Duplicate Modules 17 17
No change  Duplicate Code 3.96% 3.96%
No change  Packages 4 4
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#4050
     Baseline
#4042
No change  JS 229.31KiB 229.31KiB
No change  Other 82.95KiB 82.95KiB
No change  CSS 31.84KiB 31.84KiB

Bundle analysis reportBranch upupming:feat/css-extract-testProject dashboard


Generated by RelativeCIDocumentationReport issue

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🔭 Outside diff range comments (1)
packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js (1)

1-1: Ensure webpack patch applies across all 5.100.x+ versions

Per our team learnings, the patch fixes issues present in webpack 5.99.9 but only takes effect on webpack 5.100.0 and later. The current patchedDependencies entry only matches exactly version 5.101.0, which risks CI flakiness when webpack rolls forward. Please update the workspace config in pnpm-workspace.yaml:

 patchedDependencies:
   "@napi-rs/cli@2.18.4": "patches/@napi-rs__cli@2.18.4.patch"
   "@rollup/plugin-typescript": "patches/@rollup__plugin-typescript.patch"
-  "webpack@5.101.0": patches/webpack@5.101.0.patch
+  "webpack@^5.100.0": patches/webpack@5.101.0.patch

 strictDepBuilds: true

This ensures the patch applies to webpack 5.100.0 and any subsequent 5.x releases.

♻️ Duplicate comments (1)
packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/2.snap.txt (1)

17-18: deps ordering and structural assertions

Echoing prior comment on Step 1: ensure deps ordering is deterministic or normalize before asserting. Apply the same “decode-and-assert-structure” approach here.

🧹 Nitpick comments (18)
packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/1.snap.txt (1)

17-17: Stabilize snapshot by decoding and normalizing the base64 “content” before asserting

The base64 payload grew and likely now embeds compiler/config details from the real plugin. This can cause frequent, noisy snapshot churn. Consider normalizing before snapshotting:

  • Decode base64 to JSON
  • Drop or redact volatile fields (e.g., full compilerOptions, debug/diagnostics, source maps, scheduler seeds)
  • Sort keys for deterministic output
  • Re-encode (or snapshot the structured JSON instead of the opaque base64)

Example normalization helper used in tests (Node/JS):

const { Buffer } = require("node:buffer");

function normalizeCssHotUpdateManifest(manifest) {
  try {
    const decoded = JSON.parse(Buffer.from(manifest.content, "base64").toString("utf-8"));

    // Redact/strip volatile sections (adjust to actual shape)
    if (decoded.compilerOptions) {
      const { enableFiberArch, useLepusNG, enableReuseContext, bundleModuleMode, defaultDisplayLinear, /* keep stable opts */ } = decoded.compilerOptions;
      decoded.compilerOptions = {
        enableFiberArch,
        useLepusNG,
        enableReuseContext,
        bundleModuleMode,
        defaultDisplayLinear
        // omit transient/debug flags
      };
    }
    delete decoded.sourceContent;           // if present and large/variable
    delete decoded.lepusCode?.lepusChunk;   // if present and nondeterministic
    // Ensure deterministic key order
    const stable = JSON.parse(JSON.stringify(decoded));

    // Option A: snapshot the decoded, stable JSON (preferred)
    return { ...manifest, content: stable };

    // Option B: re-encode if caller expects base64
    // return { ...manifest, content: Buffer.from(JSON.stringify(stable)).toString("base64") };
  } catch {
    return manifest; // fallback, don't break tests
  }
}

Then in the test assertion, compare against the normalized structure (or override the snapshot serializer) to reduce flakiness while still validating semantics (e.g., that deps remain {"0": []}, CSS rules/classes are present).

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/2.snap.txt (1)

17-17: Snapshot brittleness: consider decoding/redacting manifest content before asserting.

You’re snapshotting a base64-encoded JSON blob that now includes many compile options. This will likely change across toolchain updates and inflate snapshot noise. Prefer decoding and normalizing to a stable subset (e.g., css map, deps), then snapshot that.

Example normalization (Node):

function normalizeLynxCssManifest(rawJson) {
  const obj = JSON.parse(rawJson);
  if (obj.content) {
    try {
      const decoded = JSON.parse(Buffer.from(obj.content, 'base64').toString('utf8'));
      const stable = {
        css: decoded.css,       // keep selectors/mapping
        deps: decoded.deps || {}// keep dependency graph
      };
      obj.content = Buffer.from(JSON.stringify(stable)).toString('base64');
    } catch {
      // ignore if content isn’t decodable
    }
  }
  return JSON.stringify(obj);
}

Wire this in the snapshot harness before writing/printing the manifest to reduce churn while preserving the signal we care about.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/rspack.config.js (1)

14-14: Using absolute dev-server publicPath is fine; consider centralizing the origin

Switching to 'http://localhost:3000/' aligns with real-plugin behavior. Optionally, read this origin from a single test constant or env (e.g., TEST_DEV_SERVER_ORIGIN) to avoid scattering literals across configs.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/webpack.config.js (1)

14-14: Mirror change approved; consider centralizing the origin

Matching the dev-server publicPath between webpack/rspack is good. Optionally centralize the origin for consistency across tests.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/0.snap.txt (1)

8-8: Snapshot payload grew significantly — expected with real LynxTemplatePlugin

The larger manifest size is expected after switching from the mock to the real plugin. Consider making assertions resilient to payload growth to avoid brittle snapshots.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/2.snap.txt (1)

9-9: Path now nested under “main/…” — verify HMR runtime and stub mapping

cssHotUpdateList references "main/main.LAST_HASH.css.hot-update.json" (nested). Confirm:

  • Lynx runtime resolves this path relative to publicPath as intended.
  • The stub that remaps http://localhost:3000/ URLs to local paths handles nested asset paths.

I can script-check the suite for consistent “main/…” usage if you’d like.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/0.snap.txt (1)

15-16: deps includes cssId=100 entry — ensure order stability or normalize

deps shows entries for "1" and "100". If upstream generation order can vary, sort before snapshot.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/1.snap.txt (1)

25-26: Consider reducing snapshot brittleness of the base64-encoded content.

The content embeds compile options and source metadata. Minor config or Node version tweaks can churn these snapshots. If possible, decode and assert on the JSON schema/essential fields (e.g., css map, deps) instead of the full blob, or normalize volatile keys in the test harness before snapshotting.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/rspack.config.js (1)

18-20: Use an env-driven publicPath to keep tests portable.

Align with other configs by allowing override without editing multiple files.

-    publicPath: 'http://localhost:3000/',
+    publicPath: process.env.DEV_SERVER_PUBLIC_PATH || 'http://localhost:3000/',
packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/webpack.config.js (1)

14-16: Avoid scattering the dev origin; prefer an env fallback.

-    publicPath: 'http://localhost:3000/',
+    publicPath: process.env.DEV_SERVER_PUBLIC_PATH || 'http://localhost:3000/',
packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/webpack.config.js (1)

14-16: Parametrize publicPath; current value assumes http and fixed port.

If tests ever run against https or a different port, this will churn snapshots. Use an env fallback.

-    publicPath: 'http://localhost:3000/',
+    publicPath: process.env.DEV_SERVER_PUBLIC_PATH || 'http://localhost:3000/',
packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/rspack.config.js (1)

14-16: Make publicPath configurable for test stability.

-    publicPath: 'http://localhost:3000/',
+    publicPath: process.env.DEV_SERVER_PUBLIC_PATH || 'http://localhost:3000/',
packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/webpack.config.js (1)

14-16: Prefer an environment-driven publicPath to reduce duplication.

-    publicPath: 'http://localhost:3000/',
+    publicPath: process.env.DEV_SERVER_PUBLIC_PATH || 'http://localhost:3000/',
packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/rspack.config.js (1)

14-16: Configurable publicPath will make future test maintenance easier.

-    publicPath: 'http://localhost:3000/',
+    publicPath: process.env.DEV_SERVER_PUBLIC_PATH || 'http://localhost:3000/',
packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/webpack.config.js (1)

14-16: publicPath change looks fine; consider centralizing

Optional: define a single DEV_PUBLIC_PATH constant in test helpers to avoid duplicating 'http://localhost:3000/' across many configs.

packages/webpack/css-extract-webpack-plugin/test/plugins.js (3)

11-36: Guard against undefined encodeOptions and clarify no-op access

Minor robustness and clarity improvements:

  • Default encodeOptions to {} to avoid Buffer.from(undefined) if args.encodeOptions is missing.
  • Replace the bare compiler.options.entry expression with a clear no-op.

Apply:

 export const mockLynxEncodePlugin = () => {
   return {
     name: 'MockLynxEncodePlugin',
     apply(compiler) {
-      compiler.options.entry;
+      // Touch entry to ensure the field is accessed during compilation (intentional no-op)
+      void compiler.options.entry;
       compiler.hooks.thisCompilation.tap(
         'MockLynxEncodePlugin',
         (compilation) => {
           const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks(
             compilation,
           );
           hooks.encode.tapPromise(
             'MockLynxEncodePlugin',
             (args) => {
-              const buffer = Buffer.from(JSON.stringify(args.encodeOptions));
+              const buffer = Buffer.from(
+                JSON.stringify(args?.encodeOptions ?? {}),
+                'utf8'
+              );
               return Promise.resolve({
                 buffer,
                 debugInfo: '',
               });
             },
           );
         },
       );
     },
   };
 };

39-54: Tighten JSDoc types and avoid redundant defaultOptions spread

  • JSDoc: LynxTemplatePlugin['options'] may not resolve as intended in JS; prefer the explicit exported type from the package.
  • The plugin itself merges defaults; no need to spread defaultOptions here.

Apply:

-/**
- * @param {{
- *  lynxTemplatePluginOptions?: Partial<LynxTemplatePlugin['options']>
- * }} options
- * @returns {import('webpack').WebpackPluginInstance[]}
- */
-export function getPlugins({
-  lynxTemplatePluginOptions,
-}) {
-  return [
-    mockLynxEncodePlugin(),
-    new LynxTemplatePlugin({
-      ...LynxTemplatePlugin.defaultOptions,
-      ...lynxTemplatePluginOptions,
-    }),
-  ];
-}
+/**
+ * @param {{
+ *  lynxTemplatePluginOptions?: Partial<import('@lynx-js/template-webpack-plugin').LynxTemplatePluginOptions>
+ * }} options
+ * @returns {import('webpack').WebpackPluginInstance[]}
+ */
+export function getPlugins({ lynxTemplatePluginOptions } = {}) {
+  return [
+    mockLynxEncodePlugin(),
+    new LynxTemplatePlugin(lynxTemplatePluginOptions),
+  ];
+}

56-62: Optional: reuse getPlugins to keep exports in sync

To avoid two sources of truth, consider exporting plugins via getPlugins().

Apply:

-export const plugins = [
-  mockLynxEncodePlugin(),
-  new LynxTemplatePlugin(),
-];
+export const plugins = getPlugins();
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 05b0096 and 18fb4e7.

📒 Files selected for processing (42)
  • .changeset/cruel-shrimps-say.md (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/rspack.config.js (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/webpack.config.js (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/plugins.js (2 hunks)
🔥 Files not summarized due to errors (1)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/snapshot/rspack/2.snap.txt: Error: Server error: no LLM provider could handle the message
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1454
File: pnpm-workspace.yaml:46-46
Timestamp: 2025-08-07T04:00:59.627Z
Learning: In the lynx-family/lynx-stack repository, the webpack patch (patches/webpack5.101.0.patch) was created to fix issues with webpack5.99.9 but only takes effect on webpack5.100.0 and later versions. The patchedDependencies entry should use "webpack@^5.100.0" to ensure the patch applies to the correct version range.
📚 Learning: 2025-08-07T04:00:59.627Z
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1454
File: pnpm-workspace.yaml:46-46
Timestamp: 2025-08-07T04:00:59.627Z
Learning: In the lynx-family/lynx-stack repository, the webpack patch (patches/webpack5.101.0.patch) was created to fix issues with webpack5.99.9 but only takes effect on webpack5.100.0 and later versions. The patchedDependencies entry should use "webpack@^5.100.0" to ensure the patch applies to the correct version range.

Applied to files:

  • packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js
🧬 Code Graph Analysis (3)
packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/webpack.config.js (1)
packages/webpack/css-extract-webpack-plugin/test/plugins.js (1)
  • getPlugins (44-54)
packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/rspack.config.js (1)
packages/webpack/css-extract-webpack-plugin/test/plugins.js (1)
  • getPlugins (44-54)
packages/webpack/css-extract-webpack-plugin/test/plugins.js (2)
packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts (6)
  • compilation (641-662)
  • compilation (673-728)
  • compilation (730-937)
  • compilation (968-990)
  • compilation (992-1039)
  • LynxTemplatePlugin (351-460)
packages/webpack/template-webpack-plugin/src/index.ts (1)
  • LynxTemplatePlugin (11-11)
🔇 Additional comments (38)
packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/1.snap.txt (1)

8-8: Manifest size bump acknowledged; please verify determinism across environments

The snapshot now records main.LAST_HASH.css.hot-update.json as size 1790. Given the switch to the real LynxTemplatePlugin, the increase is expected. Please double-check this size is stable across local/CI, Node versions, and platforms to avoid flaky snapshots. Also noting: the AI summary mentions 1786, but the file shows 1790—treat the file as source of truth.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/2.snap.txt (1)

8-8: Manifest size jump — check for non-deterministic inputs.

The manifest grew (size: 1778). Given the switch to the real LynxTemplatePlugin, this is expected, but please verify the payload doesn’t include environment-dependent data (absolute URLs, timestamps, machine paths) that will cause flaky snapshot churn. Also confirm the new publicPath remapping covers rspack outputs consistently.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/2.snap.txt (2)

17-17: Snapshot payload update looks correct given the switch to the real plugin.

The new base64 content reflects a richer CSS HMR manifest; accepting this snapshot aligns with the PR’s goal to cover complex cases.


8-8: Verify stability and environment-agnostic snapshot
The bump to 1790 bytes in packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/2.snap.txt is expected with the real plugin, but we need to ensure the embedded update manifest is deterministic and free of host-specific data. Automated decode attempts failed in this sandbox, so please manually:

  • Decode the Base64 string in the "content" field to JSON (using your local base64 CLI or a quick Node/Python script).
  • Confirm it parses without errors.
  • Scan the decoded JSON for any of the following unstable patterns:
    • Absolute UNIX paths (/Users/, /home/, /var/folders/)
    • Windows drive letters ([A-Za-z]:\\)
    • HTTP(S) URLs (http://, https://)

If any env-specific data is found, strip or normalize it so tests remain stable across machines. Otherwise, the snapshot update can be approved.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/0.snap.txt (2)

8-8: Snapshot size change looks expected after switching to real plugin

The manifest size bump aligns with richer payloads from the real LynxTemplatePlugin.


15-15: Manual verification: hot-update payload determinism unresolved

Our automated decode of the base64-encoded “content” fields in all __snapshot__/rspack/*.snap.txt files failed (invalid UTF-8 or padding errors), so we can’t confirm the stability of the decoded JSON. Please manually verify that the plugin’s hot-update payload:

  • decodes to valid UTF-8 JSON
  • uses a deterministic key order with no runtime-generated IDs
  • produces identical base64 strings across test runs

Key snapshot locations to check:
• packages/webpack/css-extract-webpack-plugin/test/hotCases/**/snapshot/rspack/*.snap.txt

If necessary, adjust the plugin to serialize JSON deterministically or update the tests to handle any binary/compressed payload consistently.

.changeset/cruel-shrimps-say.md (1)

1-3: Empty changeset is invalid; either remove it or declare a “none” change

An empty front matter block will break/derail Changesets. If this PR is tests-only, mark “none” for the affected package; otherwise set the proper bump.

Example (no release intent):

---- 
-
----
+---
+"@lynx-js/css-extract-webpack-plugin": none
+---
+
+chore: tests use real LynxTemplatePlugin to improve coverage; no release.

If a release is desired, replace “none” with the correct semver bump and add a short description.

⛔ Skipped due to learnings
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:26:16.722Z
Learning: In the lynx-family/lynx-stack repository, CI checks require changesets when files matching the pattern "src/**" are modified (as configured in .changeset/config.json). For internal changes that don't need meaningful changesets, an empty changeset file is used to satisfy the CI requirement while not generating any release notes.
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:23:07.797Z
Learning: In the lynx-family/lynx-stack repository, changesets are only required for meaningful changes to end-users such as bugfixes and features. Internal/development changes like chores, refactoring, or removing debug info do not need changeset entries.
packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/0.snap.txt (2)

8-8: Snapshot size bump acknowledged

The larger manifest is consistent with richer metadata from the real plugin.


15-15: Sanity-check decoded JSON content across runs

Please verify the new base64 blob decodes consistently (no run-to-run diffs unrelated to code changes).

Use the decoding script shared in a sibling comment to check determinism.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/0.snap.txt (2)

8-8: Manifest size change OK

The increase is consistent with other updated hot-update snapshots.


15-15: Check nested payload determinism as well

Nested paths often surface edge cases; please ensure the decoded content is stable across runs.

Re-use the decoding script provided earlier to include nested snapshots.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/1.snap.txt (2)

8-8: Size increase acknowledged for CSS hot-update manifest

Expected with richer JSON produced by the real plugin.


17-17: Decoded payload and cssHotUpdateList are correct
The Base64-encoded content decodes to an object with the expected top-level keys (compilerOptions, sourceContent, css, cssSource, deps), and the HMR runtime’s
__webpack_require__.cssHotUpdateList = [["main","main.LAST_HASH.css.hot-update.json"]]
matches the snapshot manifest naming exactly. No further changes required.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/0.snap.txt (2)

8-8: Manifest size change is consistent across module tests

Looks good.


15-15: Determinism check recommendation

Please verify that the decoded JSON structure is stable; modules cases sometimes embed identifiers that can drift.

Use the shared decoding script to validate.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/1.snap.txt (1)

8-8: Increased manifest size acknowledged

Change aligns with using the real plugin and absolute publicPath. No action required, but see note below on stabilizing expectations.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/2.snap.txt (1)

8-8: Manifest growth expected; keep assertions resilient

Size growth is consistent with real plugin output. No blockers.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/2.snap.txt (1)

8-8: Manifest size increase acknowledged

Consistent with other scoped snapshots after switching to the real plugin.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/0.snap.txt (1)

8-8: Initial step manifest growth OK

The switch to an absolute publicPath and real plugin explains the increase; approved.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/0.snap.txt (1)

8-8: Manifest size change acknowledged

Expected due to using real LynxTemplatePlugin and absolute publicPath.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/0.snap.txt (1)

8-8: Manifest growth OK for Step 0

No issues; consistent with the broader refactor.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/2.snap.txt (1)

8-8: Snapshot payload grew; confirm determinism with absolute publicPath

The CSS hot-update manifest size and base64 content changed. Expected with real plugin and http publicPath, but please ensure the output is deterministic across environments (port, host, path) to avoid flaky snapshots.

Also applies to: 17-17

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/1.snap.txt (1)

8-8: Updated CSS hot-update manifest; verify stability

The manifest size and content changed. Given the move to real plugin + absolute publicPath, validate that these values are stable on CI and do not depend on machine-specific paths.

Also applies to: 17-17

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/1.snap.txt (1)

8-8: Snapshot refresh looks correct; ensure deterministic base64 payload

With real plugin and http publicPath, the base64 "content" changed and grew. Confirm no env-dependent inputs (e.g., absolute file paths, hostname, port) affect the hashing used here.

Also applies to: 17-17

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/1.snap.txt (1)

8-8: Hot-update JSON content changed; validate reproducibility

The CSS hot-update JSON content and size increased. Ensure class name hashing and payload generation are deterministic across runs now that the real plugin is used.

Also applies to: 17-17

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/1.snap.txt (1)

9-9: Nested CSS hot-update manifest changed; confirm path resolution in tests

The nested manifest grew and path is pages/main/pages/main.LAST_HASH.css.hot-update.json. Verify the stub remap resolves this nested path correctly and that outputs remain deterministic.

Also applies to: 25-25

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/2.snap.txt (1)

9-9: Nested snapshot payload updated; check determinism and remap compatibility

Ensure these nested CSS hot-update JSON paths and contents are stable on CI and compatible with the URL→local remap in stubLynx.

Also applies to: 25-25

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/2.snap.txt (1)

8-8: Manifest/base64 updated; ensure no env-sensitive inputs affect snapshots

Double-check that absolute publicPath and real plugin do not introduce environment-sensitive inputs into the manifest content, which could cause snapshot churn.

Also applies to: 17-17

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/1.snap.txt (1)

9-9: Snapshot manifest growth looks expected after switching to the real plugin and absolute publicPath.

The larger css hot-update manifest is consistent with the change in test setup. No issues spotted.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/webpack.config.js (1)

14-16: stubLynx rewrite for publicPath verified

The regex in packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js (around line 17) replaces any http://<host>:<port>/ prefix—including http://localhost:3000/—with ./, ensuring CI tests remain hermetic.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/rspack.config.js (1)

14-16: LGTM: publicPath updated to absolute URL

Good consistency with other hot-case configs.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/rspack.config.js (1)

14-16: LGTM: publicPath -> absolute URL

Matches the broader test harness change; snapshots being larger is expected.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/webpack.config.js (1)

14-16: LGTM: absolute publicPath aligns with HMR tests

No further changes needed here.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/webpack.config.js (2)

8-8: Migration to getPlugins correct

Switching to getPlugins removes the mock and wires the real LynxTemplatePlugin plus the encode mock. Good step toward realistic coverage.


31-36: Options are correctly consumed by LynxTemplatePlugin
Both enableCSSSelector and enableRemoveCSSScope are declared on LynxTemplatePluginOptions, passed through to encodeRawData.compilerOptions, and show up in the generated tasm.json (snapshots confirm their values). No further changes needed.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/rspack.config.js (3)

8-8: getPlugins import/use is correct for Rspack tests

Consistent with the Webpack variant; ensures parity across runners.


14-16: LGTM: absolute publicPath

Consistent with broader suite.


37-42: Verify option names are recognized (RSpack path as well)

Same concern as the Webpack config: please confirm the plugin reads enableCSSSelector/enableRemoveCSSScope as provided.

Use the same search as suggested in the Webpack config review to validate usage.

@upupming upupming force-pushed the feat/css-extract-test branch from 18fb4e7 to 1a68b02 Compare August 11, 2025 13:31
@upupming upupming requested a review from luhc228 August 11, 2025 13:33
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (6)
packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/2.snap.txt (1)

16-18: Base64-encoded manifest content now embeds absolute dev-server URL; normalize or snapshot structure instead of full payload

The content includes a base64 JSON blob whose decoded form contains fields like compilerOptions and templateDebugUrl pointing to http://localhost:3000/.rspeedy/debug-info.json. This hard-coded absolute URL and the expanded option set will make snapshots noisy and fragile.

Recommendations:

  • Normalize volatile fields (URLs, flags) before snapshotting, or
  • Decode and snapshot a stable subset (keys, critical flags), not the entire blob.

Example approach (apply in the test harness that generates snapshot text):

- // current: snapshot raw base64 content field verbatim
+ // proposed: decode, sanitize, and re-encode or snapshot a stable projection
+ const decoded = JSON.parse(Buffer.from(json.content, 'base64').toString('utf8'));
+ // mask URL and any env-specific toggles
+ if (decoded.compilerOptions?.templateDebugUrl) {
+   decoded.compilerOptions.templateDebugUrl = '<DEV_SERVER_URL>/.rspeedy/debug-info.json';
+ }
+ // optionally pick stable keys only:
+ const projection = {
+   compilerOptions: {
+     enableFiberArch: decoded.compilerOptions.enableFiberArch,
+     enableReusContext: decoded.compilerOptions.enableReuseContext ?? decoded.compilerOptions.enableReusContext,
+     // ...add only the flags the tests actually care about
+   },
+   css: {
+     cssMap: Object.keys(decoded.css?.cssMap ?? {}),
+   },
+   deps: decoded.deps,
+ };
+ // snapshot projection (JSON.stringify with stable sort) or re-encode if format must stay base64

If keeping absolute URLs is necessary, ensure the dev server port is fixed in CI; otherwise replace with a placeholder as above.

I can draft a small normalizer module and wire it into your snapshot generation so only stable fields are asserted. Want me to open a follow-up PR?

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/1.snap.txt (1)

17-18: Reduce snapshot brittleness by normalizing dynamic fields in content

The base64-encoded JSON now embeds absolute URLs (e.g., http://localhost:3000/...) and many flags that may change over time, causing snapshot churn. Consider decoding the content JSON in test helpers and normalizing dynamic fields (e.g., publicPath host/port, hashes, optional flags) before snapshotting or comparing.

Example approach (in test helper):

  • Base64-decode content
  • JSON.parse
  • Replace volatile fields (e.g., templateDebugUrl host/port) with placeholders
  • JSON.stringify with stable key ordering
  • Base64-encode back for comparison

This will keep assertions strong while reducing noise from environment-specific values.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/1.snap.txt (1)

25-26: Normalize dynamic JSON before snapshotting to avoid churn

Same note as other hot-update cases: the base64-encoded content embeds environment-dependent values (absolute URLs, plugin option flags). Normalize these fields in the test harness before writing/expecting the snapshot to reduce fragility, while still validating structure and critical fields.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/2.snap.txt (1)

17-18: Stabilize content snapshot by masking volatile fields

As with other snapshots in this PR, consider normalizing dynamic values inside the base64-encoded content (URLs, flags, hashes) to reduce unnecessary snapshot updates while preserving meaningful assertions.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/1.snap.txt (1)

25-26: Optional: decode and sanitize content JSON before snapshotting

To keep snapshots resilient, consider decoding and sanitizing dynamic fields (absolute URLs, hashes) in content before asserting. This will make diffs more signal, less noise.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/2.snap.txt (1)

8-8: Snapshot payload size doubled — confirm determinism and consider normalizing non-stable fields.

The hot-update manifest grew from ~978 to 1830 bytes. With the real LynxTemplatePlugin, this is likely due to extra fields (e.g., compilerOptions, source content, debug URLs). If any of those contain environment-dependent data (absolute URLs, machine paths, timestamps, randomized ordering), the snapshot may become flaky.

  • Action: Verify the decoded JSON doesn't include non-deterministic fields beyond what you intend to lock in.
  • Optional: Normalize or strip volatile fields in the test harness before snapshotting (e.g., clamp templateDebugUrl to a fixed value, drop transient sections) to reduce churn.

Would you like me to provide a small utility that decodes the manifest content, sanitizes fields (URL/path/timestamps), and re-encodes it before snapshot output?

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 18fb4e7 and 6c76eb0.

📒 Files selected for processing (42)
  • .changeset/cruel-shrimps-say.md (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/rspack.config.js (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/webpack.config.js (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/0.snap.txt (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/1.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/2.snap.txt (2 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/rspack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/webpack.config.js (1 hunks)
  • packages/webpack/css-extract-webpack-plugin/test/plugins.js (2 hunks)
✅ Files skipped from review due to trivial changes (3)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/snapshot/rspack/2.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/snapshot/rspack/1.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/snapshot/rspack/1.snap.txt
🚧 Files skipped from review as they are similar to previous changes (29)
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/rspack.config.js
  • .changeset/cruel-shrimps-say.md
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/snapshot/rspack/0.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/snapshot/rspack/2.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/snapshot/rspack/0.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/snapshot/rspack/0.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/snapshot/rspack/0.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/snapshot/rspack/1.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/snapshot/rspack/0.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/snapshot/rspack/0.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/snapshot/rspack/2.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/snapshot/rspack/0.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/snapshot/rspack/2.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/snapshot/rspack/0.snap.txt
  • packages/webpack/css-extract-webpack-plugin/test/plugins.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/snapshot/rspack/1.snap.txt
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1454
File: pnpm-workspace.yaml:46-46
Timestamp: 2025-08-07T04:00:59.627Z
Learning: In the lynx-family/lynx-stack repository, the webpack patch (patches/webpack5.101.0.patch) was created to fix issues with webpack5.99.9 but only takes effect on webpack5.100.0 and later versions. The patchedDependencies entry should use "webpack@^5.100.0" to ensure the patch applies to the correct version range.
🔇 Additional comments (10)
packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/2.snap.txt (1)

9-9: Nested manifest path duplication is expected

The double-prefixed path arises because the chunk name itself includes a directory segment (pages/main), and the plugin uses that as both the directory prefix and the base file name. This produces entries like

pages/main/pages/main.LAST_HASH.css.hot-update.json

consistently across all nested snapshots. No changes are required here.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/1.snap.txt (1)

8-8: LGTM: manifest size increase is expected with real plugin output

The larger CSS hot-update manifest aligns with switching to the real LynxTemplatePlugin (more metadata emitted). Snapshot update looks correct.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/1.snap.txt (2)

86-86: Confirm runtime path resolution for nested hot-update manifests

cssHotUpdateList references ["pages/main","pages/main/pages/main.LAST_HASH.css.hot-update.json"]. With absolute dev-server publicPath, ensure HMR’s runtime correctly resolves this nested relative path (no double-prefixing with publicPath). If there’s any risk of 404s at runtime, consider normalizing to an absolute URL or ensuring the runtime join logic is unambiguous.


9-9: No action needed: duplicated path is intentional in nested tests
The “pages/main/pages/main.…css.hot-update.json” pattern comes directly from the nested test setup, where publicPath = "pages/main" is applied to a filename that already starts with pages/main. The snapshots and the test in
packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/index.js
explicitly expect:

  • cssHotUpdateList = [["pages/main","pages/main/pages/main.LAST_HASH.css.hot-update.json"]]
  • fs.existsSync(path.join(__dirname, 'pages/main', \pages/main.${prevHash}.css.hot-update.json`))`

All other hot-update tests follow the same filename+publicPath pattern (e.g. main/main.…css.hot-update.json), so this duplication is by design and consistent across snapshots.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/__snapshot__/rspack/2.snap.txt (1)

8-8: LGTM: manifest size alignment with new plugin behavior

The increased size is consistent with the switch to real plugin output. Snapshot update looks correct.

packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/__snapshot__/rspack/1.snap.txt (2)

9-9: LGTM: filename-scoped manifest path and size look consistent

The main/main.LAST_HASH.css.hot-update.json path matches the “filename” scenario semantics and the larger manifest size is expected with the real plugin. No issues spotted.


86-86: Confirm HMR runtime path composition with dev-server publicPath

cssHotUpdateList = [["main","main/main.LAST_HASH.css.hot-update.json"]] should resolve correctly under absolute publicPath. Please verify no double-prefixing or missing slashes in the loader that consumes this list, especially across both webpack and rspack test matrices.

packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/1.snap.txt (2)

8-8: LGTM: CSS hot-update manifest size bump aligns with real plugin payloads

The larger main.LAST_HASH.css.hot-update.json is expected after switching to the real LynxTemplatePlugin and richer HMR metadata. No action needed here.


9-10: AI summary inconsistency: non-CSS hot-update entries are still present

The snapshot still contains main.LAST_HASH.hot-update.json and main.LAST_HASH.hot-update.js, contrary to the AI summary that said these were removed.

packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/__snapshot__/rspack/2.snap.txt (1)

17-17: Snapshot is plain-text, not JSON—no Base64 content to decode
The file at
packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/snapshot/rspack/2.snap.txt
is a human-readable test snapshot (plain text), not a JSON blob with a content field. There is no Base64-encoded payload or templateDebugUrl to extract or normalize, so the original decoding request does not apply.

Likely an incorrect or invalid review comment.

export default {
output: {
publicPath: './',
publicPath: 'http://localhost:3000/',
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Use a shared constant for publicPath to keep snapshots and stub rewrites in sync

Same rationale as the Rspack config: centralizing the origin reduces duplication and avoids accidental mismatches with the stub’s rewrite logic.

Apply this diff in this file:

-    publicPath: 'http://localhost:3000/',
+    publicPath: DEV_SERVER_ORIGIN,

And add the import at the top:

import { DEV_SERVER_ORIGIN } from '../../../../test/helper/constants.js'

Quick consistency check across webpack configs:

Happy to batch the refactor across all affected hotCases if you’d like.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Webpack configs hardcoding publicPath to 3000:"
rg -n -S "publicPath:\s*['\"]http://localhost:3000/['\"]" packages/webpack/css-extract-webpack-plugin/test | rg webpack.config.js || true

Length of output: 1236


Centralize publicPath using DEV_SERVER_ORIGIN constant

To avoid hard-coding the same origin string in multiple test configs and keep snapshots/stub rewrites in sync, please replace every occurrence of

publicPath: 'http://localhost:3000/',

with

publicPath: DEV_SERVER_ORIGIN,

and import the shared constant at the top of each file.

Files to update:

  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/webpack.config.js

Example diff (apply identically in each file):

--- a/.../webpack.config.js
+++ b/.../webpack.config.js
@@ 1,5c1,6
-import path from 'path';
+import path from 'path';
+import { DEV_SERVER_ORIGIN } from '../../../../test/helper/constants.js';

 module.exports = {
   // …
-  publicPath: 'http://localhost:3000/',
+  publicPath: DEV_SERVER_ORIGIN,
   // …
 };
🤖 Prompt for AI Agents
packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/webpack.config.js
lines 14-14: replace the hard-coded publicPath string with the shared
DEV_SERVER_ORIGIN constant and add an import for DEV_SERVER_ORIGIN at the top of
the file; specifically, change publicPath: 'http://localhost:3000/' to
publicPath: DEV_SERVER_ORIGIN and add an import statement for DEV_SERVER_ORIGIN
from the shared test constants module (use the correct relative path in this
repo) so snapshots and stubs stay in sync.


```json
{"content":"eyJjb21waWxlck9wdGlvbnMiOnsiZW5hYmxlUmVtb3ZlQ1NTU2NvcGUiOmZhbHNlfSwic291cmNlQ29udGVudCI6eyJkc2wiOiJyZWFjdF9ub2RpZmYiLCJhcHBUeXBlIjoiY2FyZCIsImNvbmZpZyI6eyJsZXB1c1N0cmljdCI6dHJ1ZX19LCJtYW5pZmVzdCI6eXsImxlcHVzQ29kZSI6eyJsZXB1c0NodW5rIjp7fXXsImN1c3RvbVNlY3Rpb25zIjp7fSwiY3NzIjp7ImNzc01hcCI6eyIwIjpbeyJ0eXBlIjoiU3R5bGVSdWxlIiwic3R5bGUiOlt7Im5hbWUiOiJjb2xvciIsInZhbHVlIjoiXCJibHVlXCIiLCJrZXlMb2MiOnsibGluZSI6MSwiYXsdW1uIjoyNHXsInZhbExvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjMyfX1dLCJzZWxlY3RvclRleHQiOnsidmFsdWUiOiIudmprSEs4ZzlnTHk5MWN0RCIsImxvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjE4fXXsInZhcmlhYmxlcyI6e319LHsidHlwZSI6IlN0eWxlUnVsZSIsInN0eWxlIjpbeyJuYW1lIjoiYmFja2dyb3VuZC1jb2xvciIsInZhbHVlIjoiYmxhYXsiLCJrZXlMb2MiOnsibGluZSI6MSwiYXsdW1uIjo2NnXsInZhbExvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjczfX1dLCJzZWxlY3RvclRleHQiOnsidmFsdWUiOiIuRWFBR2JDODdMQTBOQ0lJUiIsImxvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjQ5fXXsInZhcmlhYmxlcyI6e319XXXsImNzc1NvdXJjZSI6eyIwIjoiL2Nzc0lkLzAuY3NzInXsImNvbnRlbnRNYXAiOnt9fX0=","deps":{"0":[]}}
{"content":"eyJjb21waWxlck9wdGlvbnMiOnsiZW5hYmxlRmliZXJBcmNoIjp0cnVlLCJ1c2VMZXB1c05HIjp0cnVlLCJlbmFibGVSZXVzZUNvbnRleHQiOnRydWUsImJ1bmRsZU1vZHVsZU1vZGUiOiJSZXR1cm5CeUZ1bmN0aW9uIiwidGVtcGxhdGVEZWJ1Z1VybCI6Imh0dHA6LyXsb2NhbGhvc3Q6MzAwMC8ucnNwZWVkeS9kZWJ1Zy1pbmZvLmpzb24iLCJkZWJ1Z0luZm9PdXRzaWRlIjp0cnVlLCJkZWZhdWx0RGlzcGxheUxpbmVhciI6dHJ1ZSwiZW5hYmxlQ1NTSW52YWxpZGF0aW9uIjpmYWxzZSwiZW5hYmxlQ1NTU2VsZWN0b3IiOnRydWUsImVuYWJsZUxlcHVzRGVidWciOnRydWUsImVuYWJsZVBhcmFsbGVsRWxlbWVudCI6dHJ1ZSwiZW5hYmxlUmVtb3ZlQ1NTU2NvcGUiOmZhbHNlLCJ0YXJnZXRTZGtWZXJzaW9uIjoiMy4yIiwiZGVmYXVsdE92ZXJmbG93VmlzaWJsZSI6dHJ1ZXXsInNvdXJjZUNvbnRlbnQiOnsiZHNsIjoicmVhY3Rfbm9kaWZmIiwiYXBwVHlwZSI6ImNhcmQiLCJjb25maWciOnsibGVwdXNTdHJpY3QiOnRydWUsInVzZU5ld1N3aXBlciI6dHJ1ZSwiZW5hYmxlSUNVIjpmYWxzZSwiZW5hYmxlTmV3SW50ZXJzZWN0aW9uT2JzZXJ2ZXIiOnRydWUsImVuYWJsZU5hdGl2ZUxpc3QiOnRydWUsImVuYWJsZUExMXkiOnRydWUsImVuYWJsZUFjY2Vzc2liaWxpdHlFbGVtZW50IjpmYWxzZSwiZW5hYmxlQ1NTSW5oZXJpdGFuY2UiOmZhbHNlLCJlbmFibGVOZXdHZXN0dXJlIjpmYWxzZSwicGlwZWxpbmVTY2hlZHVsZXJDb25maWciOjY1NTM2LCJyZW1vdmVEZXNjZW5kYW50U2VsZWN0b3JTY29wZSI6ZmFsc2V9fSwiY3NzIjp7ImNzc01hcCI6eyIwIjpbeyJ0eXBlIjoiU3R5bGVSdWxlIiwic3R5bGUiOlt7Im5hbWUiOiJjb2xvciIsInZhbHVlIjoiXCJibHVlXCIiLCJrZXlMb2MiOnsibGluZSI6MSwiYXsdW1uIjoyNHXsInZhbExvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjMyfX1dLCJzZWxlY3RvclRleHQiOnsidmFsdWUiOiIudmprSEs4ZzlnTHk5MWN0RCIsImxvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjE4fXXsInZhcmlhYmxlcyI6e319LHsidHlwZSI6IlN0eWxlUnVsZSIsInN0eWxlIjpbeyJuYW1lIjoiYmFja2dyb3VuZC1jb2xvciIsInZhbHVlIjoiYmxhYXsiLCJrZXlMb2MiOnsibGluZSI6MSwiYXsdW1uIjo2NnXsInZhbExvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjczfX1dLCJzZWxlY3RvclRleHQiOnsidmFsdWUiOiIuRWFBR2JDODdMQTBOQ0lJUiIsImxvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjQ5fXXsInZhcmlhYmxlcyI6e319XXXsImNzc1NvdXJjZSI6eyIwIjoiL2Nzc0lkLzAuY3NzInXsImNvbnRlbnRNYXAiOnt9fSwibGVwdXNDb2RlIjp7ImxlcHVzQ2h1bmsiOnt9fSwibWFuaWZlc3QiOnt9LCJjdXN0b21TZWN0aW9ucyI6e319","deps":{"0":[]}}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Stabilize snapshot by normalizing environment-specific data embedded in base64 content.

The base64-encoded JSON includes a dev-server URL (e.g., http://localhost:3000) and numerous compiler/test flags. These environment-specific values will churn snapshots if ports or flags differ across environments. Decode → normalize → re-encode before asserting.

You can add a normalizer in the test harness that post-processes the JSON:

// Example helper to normalize css hot-update JSON payloads
import { Buffer } from "node:buffer";

export function normalizeCssHotUpdateJson(jsonString) {
  try {
    const obj = JSON.parse(jsonString);
    if (typeof obj.content === "string") {
      const raw = Buffer.from(obj.content, "base64").toString("utf8");

      // Replace dev-server origin with a stable placeholder
      const normalizedRaw = raw.replace(
        /https?:\/\/localhost:\d+/g,
        "http://localhost:__PORT__"
      );

      // Optionally strip fields that are noisy across environments
      // e.g., feature toggles or debug URLs if not required by the assertion
      // const stripped = JSON.stringify(JSON.parse(normalizedRaw), (k, v) => {
      //   if (k === "templateDebugUrl") return "__DEBUG_URL__";
      //   return v;
      // });

      obj.content = Buffer.from(normalizedRaw).toString("base64");
    }
    return JSON.stringify(obj);
  } catch {
    return jsonString; // fallback if parsing fails
  }
}

Then ensure snapshots compare against the normalized string to avoid flakiness from port/publicPath or debug toggles.

🤖 Prompt for AI Agents
In
packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/__snapshot__/rspack/2.snap.txt
around line 25 the snapshot contains a base64-encoded JSON payload with
environment-specific values (dev-server origin, ports and feature flags) that
cause flaky diffs; add a test-harness normalizer that decodes the JSON content
field, replaces any http(s)://localhost:<port> origins with a stable placeholder
(e.g., http://localhost:__PORT__), optionally removes or replaces noisy
feature/debug fields, then re-encodes the normalized payload to base64 and use
that normalized string for snapshot comparison so the snapshots are stable
across environments.

},
output: {
publicPath: './',
publicPath: 'http://localhost:3000/',
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Centralize dev-server origin to avoid drift with the stub and other configs

Hardcoding 'http://localhost:3000/' is fine for this test, but since the stub rewrites that origin to local paths, a single shared constant will prevent accidental mismatches and ease future changes.

Apply this diff in this file:

-    publicPath: 'http://localhost:3000/',
+    publicPath: DEV_SERVER_ORIGIN,

Also add this import at the top of the file (outside the selected lines):

import { DEV_SERVER_ORIGIN } from '../../../../test/helper/constants.js'

Create a shared constant for test infra (new file):

// packages/webpack/css-extract-webpack-plugin/test/helper/constants.js
export const DEV_SERVER_ORIGIN = 'http://localhost:3000/'

Optionally, update the stub to reuse the same constant (outside this file):

// packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js
import { DEV_SERVER_ORIGIN } from './constants.js'
// ... use DEV_SERVER_ORIGIN in the rewrite mapping

To verify consistency across the suite and the stub mapping:

If you want, I can open a follow-up to introduce the constants module and update all configs and the stub.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Configs still hardcoding publicPath to 3000:"
rg -n -S "publicPath:\s*['\"]http://localhost:3000/['\"]" packages/webpack/css-extract-webpack-plugin/test || true

echo
echo "Occurrences of localhost:3000 in the stub:"
rg -n -S "localhost:3000" packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js || true

Length of output: 2569


Centralize dev-server origin across all test configs and stub

We’ve identified 16 occurrences of the hard-coded 'http://localhost:3000/' in your test configs and one in the stub. Let’s extract it into a single constant so updates stay in sync.

• Create a new shared constant:
File:
packages/webpack/css-extract-webpack-plugin/test/helper/constants.js

// packages/webpack/css-extract-webpack-plugin/test/helper/constants.js
export const DEV_SERVER_ORIGIN = 'http://localhost:3000/';

• Update every publicPath in your hot-case configs (paths relative to each file—adjust ../ depth as needed):

-    publicPath: 'http://localhost:3000/',
+    publicPath: DEV_SERVER_ORIGIN,

Add at the top of each file:

import { DEV_SERVER_ORIGIN } from '../../helper/constants.js';

Impacts:

  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/scoped/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/basic/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/enable-css-selector/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/css/basic/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/default/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/webpack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/filename/rspack.config.js
  • packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/rspack.config.js

• Update the stub mapping to use the constant:

// packages/webpack/css-extract-webpack-plugin/test/helper/stubLynx.js
- // 'http://localhost:3000/' -> './'
+ import { DEV_SERVER_ORIGIN } from './constants.js';
+ // `${DEV_SERVER_ORIGIN}` -> './'

This ensures a single source of truth for your dev-server origin and prevents drift as tests or ports change.

🤖 Prompt for AI Agents
packages/webpack/css-extract-webpack-plugin/test/hotCases/hot-update-json/nested/rspack.config.js
around line 18: publicPath is hard-coded to 'http://localhost:3000/' — create a
single shared constant file at
packages/webpack/css-extract-webpack-plugin/test/helper/constants.js exporting
DEV_SERVER_ORIGIN = 'http://localhost:3000/'; update this file and all listed
hot-case configs (and the stub mapping) to import DEV_SERVER_ORIGIN with the
correct relative path and replace their publicPath literals with
DEV_SERVER_ORIGIN so all tests use the centralized origin.


```json
{"content":"eyJjb21waWxlck9wdGlvbnMiOnsiZW5hYmxlUmVtb3ZlQ1NTU2NvcGUiOmZhbHNlfSwic291cmNlQ29udGVudCI6eyJkc2wiOiJyZWFjdF9ub2RpZmYiLCJhcHBUeXBlIjoiY2FyZCIsImNvbmZpZyI6eyJsZXB1c1N0cmljdCI6dHJ1ZX19LCJtYW5pZmVzdCI6eXsImxlcHVzQ29kZSI6eyJsZXB1c0NodW5rIjp7fXXsImN1c3RvbVNlY3Rpb25zIjp7fSwiY3NzIjp7ImNzc01hcCI6eyIwIjpbeyJ0eXBlIjoiU3R5bGVSdWxlIiwic3R5bGUiOlt7Im5hbWUiOiJjb2xvciIsInZhbHVlIjoiXCJibHVlXCIiLCJrZXlMb2MiOnsibGluZSI6MSwiYXsdW1uIjoyNHXsInZhbExvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjMyfX1dLCJzZWxlY3RvclRleHQiOnsidmFsdWUiOiIucHN1VDFqWTE4eGdUOHlxYSIsImxvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjE4fXXsInZhcmlhYmxlcyI6e319LHsidHlwZSI6IlN0eWxlUnVsZSIsInN0eWxlIjpbeyJuYW1lIjoiYmFja2dyb3VuZC1jb2xvciIsInZhbHVlIjoiYmxhYXsiLCJrZXlMb2MiOnsibGluZSI6MSwiYXsdW1uIjo1OXXsInZhbExvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjY2fX1dLCJzZWxlY3RvclRleHQiOnsidmFsdWUiOiIubm8tY2hhbmdlIiwibG9jIjp7ImxpbmUiOjEsImNvbHVtbiI6NDJ9fSwidmFyaWFibGVzIjp7fX1dfSwiY3NzU291cmNlIjp7IjAiOiIvY3NzSWQvMC5jc3MifSwiY29udGVudE1hcCI6e319fQ==","deps":{"0":[]}}
{"content":"eyJjb21waWxlck9wdGlvbnMiOnsiZW5hYmxlRmliZXJBcmNoIjp0cnVlLCJ1c2VMZXB1c05HIjp0cnVlLCJlbmFibGVSZXVzZUNvbnRleHQiOnRydWUsImJ1bmRsZU1vZHVsZU1vZGUiOiJSZXR1cm5CeUZ1bmN0aW9uIiwidGVtcGxhdGVEZWJ1Z1VybCI6Imh0dHA6LyXsb2NhbGhvc3Q6MzAwMC8ucnNwZWVkeS9kZWJ1Zy1pbmZvLmpzb24iLCJkZWJ1Z0luZm9PdXRzaWRlIjp0cnVlLCJkZWZhdWx0RGlzcGxheUxpbmVhciI6dHJ1ZSwiZW5hYmxlQ1NTSW52YWxpZGF0aW9uIjpmYWxzZSwiZW5hYmxlQ1NTU2VsZWN0b3IiOnRydWUsImVuYWJsZUxlcHVzRGVidWciOnRydWUsImVuYWJsZVBhcmFsbGVsRWxlbWVudCI6dHJ1ZSwiZW5hYmxlUmVtb3ZlQ1NTU2NvcGUiOmZhbHNlLCJ0YXJnZXRTZGtWZXJzaW9uIjoiMy4yIiwiZGVmYXVsdE92ZXJmbG93VmlzaWJsZSI6dHJ1ZXXsInNvdXJjZUNvbnRlbnQiOnsiZHNsIjoicmVhY3Rfbm9kaWZmIiwiYXBwVHlwZSI6ImNhcmQiLCJjb25maWciOnsibGVwdXNTdHJpY3QiOnRydWUsInVzZU5ld1N3aXBlciI6dHJ1ZSwiZW5hYmxlSUNVIjpmYWxzZSwiZW5hYmxlTmV3SW50ZXJzZWN0aW9uT2JzZXJ2ZXIiOnRydWUsImVuYWJsZU5hdGl2ZUxpc3QiOnRydWUsImVuYWJsZUExMXkiOnRydWUsImVuYWJsZUFjY2Vzc2liaWxpdHlFbGVtZW50IjpmYWxzZSwiZW5hYmxlQ1NTSW5oZXJpdGFuY2UiOmZhbHNlLCJlbmFibGVOZXdHZXN0dXJlIjpmYWxzZSwicGlwZWxpbmVTY2hlZHVsZXJDb25maWciOjY1NTM2LCJyZW1vdmVEZXNjZW5kYW50U2VsZWN0b3JTY29wZSI6ZmFsc2V9fSwiY3NzIjp7ImNzc01hcCI6eyIwIjpbeyJ0eXBlIjoiU3R5bGVSdWxlIiwic3R5bGUiOlt7Im5hbWUiOiJjb2xvciIsInZhbHVlIjoiXCJibHVlXCIiLCJrZXlMb2MiOnsibGluZSI6MSwiYXsdW1uIjoyNHXsInZhbExvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjMyfX1dLCJzZWxlY3RvclRleHQiOnsidmFsdWUiOiIucHN1VDFqWTE4eGdUOHlxYSIsImxvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjE4fXXsInZhcmlhYmxlcyI6e319LHsidHlwZSI6IlN0eWxlUnVsZSIsInN0eWxlIjpbeyJuYW1lIjoiYmFja2dyb3VuZC1jb2xvciIsInZhbHVlIjoiYmxhYXsiLCJrZXlMb2MiOnsibGluZSI6MSwiYXsdW1uIjo1OXXsInZhbExvYyI6eyJsaW5lIjoxLCJjb2x1bW4iOjY2fX1dLCJzZWxlY3RvclRleHQiOnsidmFsdWUiOiIubm8tY2hhbmdlIiwibG9jIjp7ImxpbmUiOjEsImNvbHVtbiI6NDJ9fSwidmFyaWFibGVzIjp7fX1dfSwiY3NzU291cmNlIjp7IjAiOiIvY3NzSWQvMC5jc3MifSwiY29udGVudE1hcCI6e319LCJsZXB1c0NvZGUiOnsibGVwdXNDaHVuayI6e319LCJtYW5pZmVzdCI6eXsImN1c3RvbVNlY3Rpb25zIjp7fX0=","deps":{"0":[]}}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Stabilize snapshot by sanitizing absolute dev-server URL embedded in base64 payload

The content field holds a base64-encoded JSON that includes the absolute dev-server URL (e.g., http://localhost:3000/.rspeedy/debug-info.json). This will create brittle snapshots if the host/port changes or if serialization differs. Recommend normalizing this URL during snapshot generation/verification:

  • Decode base64, replace the dev-server URL with a placeholder (e.g., http:///...), then re-encode.
  • Or, compare decoded JSON structurally (assert critical fields) instead of the full base64 string.

Example helper (JS) to integrate into your test snapshot sanitizer:

function sanitizeEmbeddedBase64Json(str) {
  // Find base64 JSON in the "content" property
  return str.replace(
    /"content"\s*:\s*"([A-Za-z0-9+/=]+)"/g,
    (_, b64) => {
      try {
        const json = JSON.parse(Buffer.from(b64, 'base64').toString('utf8'));
        // Replace absolute dev-server URL occurrences
        const urlFields = ['templateDebugUrl', 'debugUrl']; // adjust list as needed
        for (const key of urlFields) {
          if (typeof json?.compilerOptions?.[key] === 'string') {
            json.compilerOptions[key] = 'http://<dev-server>/.rspeedy/debug-info.json';
          }
        }
        const stable = Buffer.from(JSON.stringify(json)).toString('base64');
        return `"content":"${stable}"`;
      } catch {
        return `"content":"${b64}"`; // fallback: leave unchanged
      }
    }
  );
}

If you already have a sanitizer that remaps HTTP-style require paths, extend it to handle this embedded base64 case.

Run this script to detect absolute dev-server URLs and their base64 form across snapshots, ensuring the sanitizer covers both:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching for plain absolute dev-server URLs..."
rg -n --hidden --no-ignore 'http://localhost:3000' -A 1 -B 1 || true

echo
echo "Searching for base64-encoded dev-server URL occurrences..."
# base64("http://localhost:3000") prefix, matches embedded variants
rg -n --hidden --no-ignore 'aHR0cDovL2xvY2FsaG9zdDozMDAw' -A 1 -B 1 || true

echo
echo "List files likely containing css hot-update manifests..."
rg -n --hidden --no-ignore 'LAST_HASH\.css\.hot-update\.json' || true

Length of output: 15390


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Decoding base64 content from snapshots and searching for dev-server URLs..."

# Iterate over all snapshot files under hotCases
find packages/webpack/css-extract-webpack-plugin/test/hotCases -type f -name '*.snap.txt' | while read -r f; do
  # Extract the base64 payload after "content":
  b64=$(grep -oP '"content":"\K[A-Za-z0-9+/=]+' "$f" || true)
  if [[ -n "$b64" ]]; then
    decoded=$(echo "$b64" | base64 -d 2>/dev/null || true)
    if [[ -n "$decoded" ]] && echo "$decoded" | grep -q 'localhost'; then
      echo "FOUND dev-server URL in decoded JSON of snapshot: $f"
      echo "$decoded" | grep -o '.\{0,50\}localhost.\{0,50\}'
      echo
    fi
  fi
done

Length of output: 137423


Sanitize embedded Base64 JSON in all hotCases snapshots
All snapshots under packages/webpack/css-extract-webpack-plugin/test/hotCases/**/__snapshot__ still contain the raw http://localhost:3000/... URL inside the Base64-encoded JSON in their content fields. To stabilize tests, extend your snapshot sanitizer to:

  • Decode the Base64 payload in "content".
  • Replace any absolute dev-server URL (http://localhost:\d+) with a placeholder (e.g. http://<dev-server>).
  • Re-encode the JSON and reinject it into the snapshot before comparison.

Example helper:

function sanitizeEmbeddedBase64Json(str) {
  return str.replace(
    /"content":"([^"]+)"/g,
    (_, b64) => {
      let json;
      try {
        json = JSON.parse(Buffer.from(b64, 'base64').toString('utf8'));
      } catch {
        return `"content":"${b64}"`;
      }
      const urlRegex = /^https?:\/\/[^/]+/;
      for (const key of ['templateDebugUrl', 'debugUrl']) {
        if (json.compilerOptions?.[key]?.match(urlRegex)) {
          json.compilerOptions[key] =
            json.compilerOptions[key].replace(urlRegex, 'http://<dev-server>');
        }
      }
      const stable = Buffer.from(JSON.stringify(json)).toString('base64');
      return `"content":"${stable}"`;
    }
  );
}

Apply this in your test helper (e.g. in stubLynx.js or a Jest snapshot serializer), then re-generate the snapshots.

• Affected paths:

  • packages/webpack/css-extract-webpack-plugin/test/hotCases//snapshot//*.snap.txt
🤖 Prompt for AI Agents
packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/1.snap.txt
lines 17-17: the snapshot's "content" field contains Base64-encoded JSON with an
absolute dev-server URL (http://localhost:3000) that must be sanitized; update
the snapshot sanitizer (e.g., stubLynx.js or your Jest serializer) to decode the
Base64 "content", parse the JSON, replace any absolute dev-server URL matching
/^https?:\/\/localhost:\d+/ (or more generally /^https?:\/\/[^/]+/) in keys like
templateDebugUrl/debugUrl/compilerOptions with a stable placeholder such as
http://<dev-server>, re-stringify and Base64-encode the JSON, reinject that into
the snapshot string, and then re-generate the snapshots under
packages/webpack/css-extract-webpack-plugin/test/hotCases/**/__snapshot__ to
commit the sanitized files.

## Asset Files
- Bundle: rspack-bundle.js
- Manifest: main.LAST_HASH.css.hot-update.json, size: 986
- Manifest: main.LAST_HASH.css.hot-update.json, size: 1870
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Manifest size jump suggests additional debug/metadata; confirm intentional and stabilize snapshot inputs

The jump to size: 1870 likely comes from switching to the real plugin adding richer metadata (e.g., compiler options, template debug URL). If this is expected, fine. If not, consider disabling or stripping optional debug fields for test builds to keep snapshots leaner and less brittle.

Additionally, to reduce flakiness, normalize dynamic values (absolute URLs, env-driven flags) before snapshotting.

Run this to audit snapshot URL consistency and detect unintended hosts/ports:


🏁 Script executed:

#!/bin/bash
# List any non-localhost URLs or unexpected dev-server ports captured in snapshots
rg -n --hidden -g '!node_modules' -e 'http://(?!localhost:3000)\S+' -e 'https?://localhost:(?!3000)\d+' packages/webpack/css-extract-webpack-plugin/test | sed 's/^/MISMATCH: /'

# Count snapshots referencing the dev-server URL to ensure uniform changes
rg -n --hidden -g '!node_modules' 'http://localhost:3000' packages/webpack/css-extract-webpack-plugin/test | wc -l

Length of output: 566


Consistent Dev-Server URLs; Size Bump from Debug Metadata

After auditing all snapshots under packages/webpack/css-extract-webpack-plugin/test, we found 16 uniform references to http://localhost:3000 and no unexpected hosts or ports. The increase to ~1870 bytes in your manifest is therefore expected—your real plugin is now including richer debug/metadata (compiler options, template URLs, source maps, etc.).

To keep your snapshots leaner and less brittle, consider one of the following:

  • Disable debug metadata in tests
    Pass a flag to your plugin fixture (e.g., debug: false) so optional fields aren’t emitted in test builds.
    Example diff:

     // packages/webpack/css-extract-webpack-plugin/test/hotCases/webpack.config.js
     new CSSExtractPlugin({
       hot: true,
    -  // default emits debug metadata
    +  debug: false, // disable debug/metadata for snapshots
     })
  • Strip dynamic fields via a snapshot serializer/transformer
    Normalize or remove properties like timestamp, version, debugURL, absolute URLs, and any env-driven flags before snapshotting.

Either approach will stabilize your snapshots and reduce flakiness when plugin internals change.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
packages/webpack/css-extract-webpack-plugin/test/hotCases/modules/export-default/__snapshot__/rspack/2.snap.txt
around line 8, the manifest snapshot now includes extra debug/metadata (compiler
options, template URLs, source maps, etc.) which increased its size and made the
snapshot brittle; fix by either (A) passing a debug:false (or equivalent) flag
into the plugin/test fixture so optional debug fields are not emitted in test
builds, or (B) add a snapshot serializer/transform step that strips or
normalizes dynamic fields (timestamp, version, debugURL, absolute URLs/ports,
env-driven flags, sourceMap paths) and normalizes hosts to http://localhost:3000
before asserting snapshots. Ensure the chosen change is applied to the test
harness used by the files under packages/webpack/css-extract-webpack-plugin/test
so all related snapshots are stabilized.

@colinaaa colinaaa merged commit 6639ee3 into lynx-family:main Aug 12, 2025
41 of 44 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Sep 21, 2025
3 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 28, 2025
3 tasks
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.

3 participants