Skip to content

fix: return original source when no inline styles are found#7

Open
arkthur wants to merge 6 commits intochristophbuehler:mainfrom
arkthur:fix/stringify-empty-source-on-no-inline-styles
Open

fix: return original source when no inline styles are found#7
arkthur wants to merge 6 commits intochristophbuehler:mainfrom
arkthur:fix/stringify-empty-source-on-no-inline-styles

Conversation

@arkthur
Copy link
Copy Markdown

@arkthur arkthur commented Mar 15, 2026

Problem

When stylelint runs with --fix on an Angular .ts file that uses styleUrl (external stylesheet) — or any plain .ts file with no inline styles — the stringifier produces an empty string. Stylelint writes that empty string back to disk, erasing the entire file.

Reported in issue #6.

Root cause

Parser: the PostCSS document root is created by postcss.parse("", { from }) — an empty string. The original TypeScript source is never stored anywhere on the PostCSS tree.

Stringifier: iterates over node.root().nodes. When there are no inline styles, nodes is an empty array, forEach never executes, builder is never called, and the output is "". The attempted fallback node.source?.input?.css also returns "" because the root was parsed from an empty string, not the original source.

Stylelint then writes "" back to disk.

The CLI accidentally avoids overwriting because it skips the write step when result.code is falsy. The VS Code stylelint extension replaces the full document content unconditionally, so it is always affected.

Fix

Parser — store the original TypeScript source in document.raws.angularSource before returning:

+document.raws.angularSource = sourceString;

Stringifier — when nodes is empty, read root.raws.angularSource and return the original source unchanged:

-node.root().nodes.forEach((node) => {
-  builder(node.raws.angularCodeBefore, node);
-  postcssStringify(node, builder);
-  builder(node.raws.angularCodeAfter, node);
-});
+const root = node.root();
+const nodes = root.nodes;
+
+if (nodes.length === 0) {
+  builder(root.raws.angularSource ?? "");
+  return;
+}
+
+nodes.forEach((node) => {
+  builder(node.raws.angularCodeBefore, node);
+  postcssStringify(node, builder);
+  builder(node.raws.angularCodeAfter, node);
+});

arkthur added 6 commits March 15, 2026 20:22
When a .ts file has no inline `styles`, `node.root().nodes` is empty
and the forEach loop never calls `builder`, producing an empty string.
Stylelint then writes that empty string back to disk, erasing the file.

The VS Code stylelint extension is particularly affected because it
replaces the full document content unconditionally, whereas the CLI
accidentally skips the write when `result.code` is falsy.

Fix: when there are no nodes, call `builder` with the original source
so the file is preserved unchanged.

Closes christophbuehler#6
The Root document is created by parsing an empty string, so
root.source.input.css is always "". The original TypeScript source
was never stored on the PostCSS tree, making it impossible for the
stringifier to return it unchanged when no inline styles are present.

Store it in document.raws.angularSource so the stringifier can use it.
Previously the fallback used node.source?.input?.css which is always ""
because the Root is created by parsing an empty string in the parser.

Now reads root.raws.angularSource (set by the parser) to return the
original TypeScript file content unchanged.
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.

1 participant