Open TheComputerM opened 3 years ago
Do you have a reproduction I could take a look at?
The project is quite large, I am sending a video to demonstrate instead.
My preprocess config:
const preprocess = [
mdsvex({
extension: '.svx',
layout: './src/helpers/MDXLayout.svelte',
remarkPlugins: [
require('remark-sectionize'),
[
require('remark-class-names'),
{
classMap: {
'heading[depth=1]': 'text-h2 mb-4',
'heading[depth=2]': 'text-h3 mb-3',
'heading[depth=3]': 'text-h4 mb-2',
},
},
],
require('remark-external-links'),
require('remark-slug'),
[
require('remark-autolink-headings'),
{
content: {
type: 'element',
tagName: 'i',
properties: { className: ['mdi', 'mdi-pound'] },
},
},
],
],
highlight: {
highlighter: (code, lang) => {
if (lang && Prism.languages[lang]) {
const parsed = Prism.highlight(code, Prism.languages[lang]);
const escaped = parsed
.replace(/{/g, '{')
.replace(/}/g, '}');
const langTag = 'language-' + lang;
const codeTag = `<code class=${langTag}>${escaped}</code>`;
const pre = `<pre class=${langTag}>${codeTag}</pre>`;
return `<Components.CodeBlock lang='${lang}'>${pre}</Components.CodeBlock>`;
} else {
const escaped = code.replace(/{/g, '{').replace(/}/g, '}');
const pre = `<pre><code>${escaped}</code></pre>`;
return `<Components.CodeBlock>${pre}</Components.CodeBlock>`;
}
},
},
}),
sveltePreprocess({
scss: {
includePaths: ['theme'],
},
postcss: {
plugins: [require('autoprefixer')],
},
}),
];
Sorry for the delay
Interesting thing was that when I was first removed the lang tag, then ran the sapper dev
then added the lang tag back in, there were no errors.
I tried moving the sveltePreprocess
to the start of the array but the outcome was still the same
This is the same issue as #51 which was closed but never actually went away.
I have traced this one down and the issue here is not that preprocessors don't run but that mdsvex
is mangling the output. mdsvex
uses the svelte parser internally to get some semantics about the document, sadly, if there is non-standard syntax (especially relevant to style and script contents) then this parse will fail. mdsvex
handles this case without erroring but since there is no information about that chunk of the source then the AST transform can sometimes fail to hoist script and style elements properly when wrapping the document in a layout.
Although this issue has surfaced when using scss, I think using typescript in the script element would also cause the same issue.
I will be refactoring some of the internals significantly to parse the markup itself fully, building a complete AST with no raw
html parts, giving me complete information about the document. This will not use the svelte compiler which requires standard javascript and css but will be a custom parser that is completely language agnostic. This agnosticism will apply to the contents of all script and style tags and the content of any expressions in the markup itself. It will also perform no validation on block names, directive names, number of script and style tags, etc. Hopefully this will make the parser flexible enough to be used in most contexts with most preprocessors, even if they do pretty weird stuff. This will introduce one or two limitations that the svelte parser does not have but I think that is a worthwhile tradeoff and these limitations will be clearly documented.
@TheComputerM I'm running into a similar issue, and I think I've got a messy-but-potential workaround. It looks like you're trying to use sveltePreprocess
to do some css transforms. I was having issues with the same thing, specifically globalStyle
and scss
in my case. What I found is that those can be used in the project, just not directly in a file used as a layout
. I was able to string this together to accomplish what I needed, maybe you can do something similar for now?
// rollup.config.js
import { mdsvex } from 'mdsvex'
import { globalStyle, scss } from 'svelte-preprocess'
const preprocess = [
mdsvex({
layout: {
_: 'src/layouts/default.svelte',
}),
scss(),
globalStyle()
]
// layouts/default.svelte
<script>
import Styles from './styles.svelte'
</script>
<Styles />
<div>
<slot />
</div>
// style.svelte
<style global type='text/scss'>
$red: red;
div {
color: $red;
}
@import './test.scss';
</style>
// test.scss
$blue: blue;
div {
border: 1px solid green;
}
This works for me, I'm able to import a variable, apply it in a style tag, and set that style tag to apply globally, then import that into my layout. This should work for you postcss
plugin, I'm not sure about includePaths
.
I will be refactoring some of the internals significantly
Hey @pngwn! How's this going? Just wonderin'
Well I did almost all of the work (in the svelte-parse
package in this repo) and now I need to do it all again because the remark APIs changed significantly.
I don't have an eta on this but I am about to start actively working on it. Situation completely sucks but it is what it is sadly.
Oh well, that does seem to suck... Keep us updated. And great work so far!
I hit an error while trying to use typescript in my layout files like this:
<script lang="ts">
export let title: string;
</script>
<div class="mt-8 mx-auto prose">
<h1>{title}</h1>
<slot />
</div>
A workaround for the TypeScript issue is to use JSDoc types:
<script>
/** @type {import("$lib/types/blog").Post} */
const post = { ...$$restProps };
</script>
A rather simple workaround to this that seems to do the job well, is to wrap your actual Layout in another "plain" svelte component, that only passes down frontmatter props. Apprently whatever is imported into layout file is still correctly preprocessed. E.g.:
<!-- WrappedLayout.svelte -->
<script lang="ts">
import Layout from './Layout.svelte'
export let someProp = ''
</script>
<Layout {someProp}>
<slot />
</Layout>
The above will work just fine even if Layout.svelte
is written in typescript or needs other preprocessors.
Thank you @jfcieslak! Until this is issue is fixed, it's a great workaround.
Can confirm - works well for us. Thanks for pointing this out <3
I tried to use SCSS in my layout svelte file and it gave me the error:
But when I removed the
lang
attribute from mystyle
tag and used CSS instead of SCSS, it showed no errors and worked fine.