Bug: DocumentSnapshot.ts is not passing preprocessed markup to svelte2tsx
See original GitHub issueEdit:
Initially I though this was a feature request, but the more I’ve dug into it it seems that there is a bug causing markup preprocessing not to take place.
DocumentSnapshot.ts is passing the raw string of the svelte file instead of the preprocessed svelte file to svelte2tsx.
This results in a valid preprocessor not being supported by the VSCode editor.
This may be by design as I’d imagine VSCode may show strange errors to users who don’t realize their code is being rewritten before it has the TS validator run on it.
Hi, I’m working on a full fledged SSG that is designed to be Svelte’s answer to Gatsby. It is designed for SEO focused, mainly static sites that have some highly interactive components. It has easy to reason about data flow, is highly pluggable, and honestly I think it has a chance at becoming ‘the framework’ for people building SEO sites using a SSG.
We’re already using this SSG in production at https://elderguide.com but are working to make it more user friendly before releasing it.
The key feature that has been blocking me from using Svelte 100% for templating is partial hydration.
Thanks to the help from @kev on Discord, we’ve come up with a pretty elegant solution, but I can’t get VS code to accept the custom directive.
Example of usage:
<!-- Parent -->
<script>
import HydrateMe from './HydrateMe.svelte';
const lotsOfData = {
stuff: true,
name: 'Nick',
email: 'yep@yep.com',
notThisOne: [1, 2, 3, 4],
};
</script>
<!-- problemsome syntax -->
<HydrateMe interactive:data={{ name: lotsOfData.name, email: lotsOfData.email }} />
<!-- Hydrate Me -->
<script>
export let name;
export let email;
</script>
<div>{name} {email}</div>
Custom Directive:
<HydrateMe interactive:data={{ name: lotsOfData.name, email: lotsOfData.email }} />
svelte.config.js:
const partialHydration = require('./partialHydration');
module.exports = {
preprocess: partialHydration,
};
partialHydration.js
module.exports = {
markup: async ({ content, filename }) => {
const matches = content.matchAll(/<([a-zA-Z]+)\s+interactive:data={(.*)}/gim);
for (const match of matches) {
console.log('match', match);
const componentName = match[1];
const dataFunction = match[2];
const replacement = `<div class="needs-hydration" data-component="${componentName}" data-data={JSON.stringify(${dataFunction})}`;
content = content.replace(match[0], replacement);
}
return { code: content };
},
};
Under the Hood
To be clear, how this is working is the SSR version of the component is built with the preprocessor. Then when we parse what is returned from the SSR component, we have a small wrapper which adds a new root component when it finds <div class="needs-hydration" ...
The data found in data-compontent
is added as the props on the new root component.
Questions
1 – Is there a way I can get VS code to accept this custom directive? Here is the error I’m seeing after restarting VS code to make sure the language server had the latest svelte.config.
2 – I know the language server is limited to 1 preprocessor based on #279. What needs to be done to unblock this? Where would I start?
Issue Analytics
- State:
- Created 3 years ago
- Comments:14 (7 by maintainers)
Top GitHub Comments
@jasonlyu123 Was discussing this with @halfnelson on Discord. He mentioned:
Hi, it’s been a year) The problem is not solved?🥲