Skip to content

Conversation

Rich-Harris
Copy link
Member

Per #14276 and #14271, we currently have a bug caused by node.parent being incorrect during CSS pruning.

One idea is to allow the AST to be mutated rather than replaced, so that links between nodes creating before traversal happens can be preserved. While it might fix this specific issue, I'm confident that it will lead to more problems down the road.

Instead, I propose simply getting rid of node.parent and node.prev. They're a hacky solution to the problem that adds overhead and complicates the types, and we still wouldn't have guarantees that the links would remain valid after traversal. Instead, we can use context.path in the places where we would use node.parent.

This PR doesn't touch the CSS pruning code, which is where the bulk of node.parent (and all of node.prev) usage happens — untangling that stuff is a little bit hairier. I had a WIP branch locally that did it, and it became stale, so I figured I'd try doing the simple bit first and then coming back to the CSS stuff rather than trying again to do it all in one go.

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.
  • If this PR changes code within packages/svelte/src, add a changeset (npx changeset).

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

Copy link

changeset-bot bot commented Nov 21, 2024

⚠️ No Changeset found

Latest commit: 2e85130

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

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

Click here to learn what changesets are, and how to add one.

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

@Rich-Harris
Copy link
Member Author

preview: https://svelte-dev-git-preview-svelte-14395-svelte.vercel.app/

this is an automated message

Copy link
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@14395

Comment on lines 25 to 27
node.metadata.path = [...context.path];

context.state.analysis.elements.push(node);
context.state.analysis.elements.push({ node, path: context.path });
Copy link
Member

Choose a reason for hiding this comment

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

We already have path as metadata on the node, would be better to either reuse that or to replace usages of metadata.path where possible.
(having metadata.path might make it easier for the CSS prune stuff)

Copy link
Member Author

Choose a reason for hiding this comment

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

As far as I can see we're using metadata.path in only one place. Seems like we could probably get rid of it. Using metadata.path in pruning is a possibility but it seems easier to just use context.path everywhere instead

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually I take that back, I misunderstood — reverting most recent change

Copy link
Member

Choose a reason for hiding this comment

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

but it seems easier to just use context.path everywhere instead

But during pruning context.path will relate to the css tree and not the element's parent tree

Copy link
Member Author

Choose a reason for hiding this comment

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

I meant the context.path being stored on analysis.elements. But on reflection it does make sense to use metadata.path everywhere — you probably missed that reply because GitHub's UI is a piece of shit

@Rich-Harris
Copy link
Member Author

going to try and tackle #14399 as part of this PR. there's a lot of pretty weird code in css-prune.js

Copy link
Contributor

@trueadm trueadm left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@Rich-Harris Rich-Harris merged commit 0469008 into main Nov 22, 2024
11 checks passed
@Rich-Harris Rich-Harris deleted the remove-node-dot-parent branch November 22, 2024 14:48
dummdidumm added a commit that referenced this pull request Nov 28, 2024
… HTML

fixes #14466

The logic introduced in #14395 was flawed - not every text or expression outside the template is the child of an attribute. This turns it around: We know that every child of a fragment is inside the template, so we ignore all text/expression tags that are not child of a fragment
Rich-Harris pushed a commit that referenced this pull request Nov 29, 2024
… HTML (#14468)

fixes #14466

The logic introduced in #14395 was flawed - not every text or expression outside the template is the child of an attribute. This turns it around: We know that every child of a fragment is inside the template, so we ignore all text/expression tags that are not child of a fragment
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.

3 participants