Svelte服务端SCSS预处理失败:Svelte.preprocess支持Component.render吗?
svelte/register Why You're Getting the ParseError
The Colon is expected error pops up because Svelte's default compiler doesn't recognize SCSS syntax when you use svelte/register without extra configuration. When you add lang="scss" to your <style> block, the compiler still tries to parse it as plain CSS—and nested selectors like h1 { span { ... } } break that plain CSS parsing rule, hence the syntax error.
To answer your core question directly: Svelte.preprocess doesn't work on Component.render()—preprocessing has to happen before the component is compiled. render() is a method of the already-compiled component, so by that point it's too late to process the SCSS.
How to Set Up SCSS Preprocessing for SSR
To get SCSS working with your SSR setup, you need to configure svelte/register to use a preprocessor that handles SCSS before the component is compiled. Here's how to do it step by step:
1. Install Required Dependencies
First, install svelte-preprocess (a utility that handles preprocessing for Svelte) and a SCSS compiler (we'll use sass, the modern replacement for node-sass):
npm install svelte-preprocess sass --save-dev
2. Update Your server.js to Configure Preprocessing
Instead of just requiring svelte/register, you'll need to override its default behavior to include the SCSS preprocessor. Here's the modified server.js:
const svelte = require('svelte/compiler'); const sveltePreprocess = require('svelte-preprocess'); const fs = require('fs'); const path = require('path'); // Override the .svelte require handler to use preprocessing require.extensions['.svelte'] = function(module, filename) { const source = fs.readFileSync(filename, 'utf8'); // Compile the component with SCSS preprocessing const result = svelte.compile(source, { filename, generate: 'ssr', // Critical for SSR functionality format: 'cjs', preprocess: sveltePreprocess({ scss: { // Optional: Add SCSS config here (e.g., include paths for global styles) // includePaths: [path.join(__dirname, 'src/styles')] } }) }); // Evaluate the compiled code and export the component module._compile(result.js.code, filename); }; // Now require your App component as before const App = require('./App.svelte').default; // Rest of your SSR code stays the same const { html, css, head } = App.render({ pageData }); reply.view('index', { pageData: JSON.stringify(pageData), STATIC_DIR, html, css: css.code, // This will now be processed SCSS -> valid CSS head });
3. Keep Your Component's Style Block Intact
Ensure your App.svelte (and any child components) still have lang="scss" on their <style> blocks:
<style lang="scss"> h1{ color: red; span{color: yellow} } </style>
Why This Works
By overriding the require.extensions['.svelte'] handler, we're telling Node.js to run every .svelte file through svelte-preprocess before compiling it with the Svelte compiler. The preprocessor converts your SCSS syntax into plain CSS that the Svelte compiler understands, eliminating the parse error. When you call App.render(), the css.code will be the fully processed, valid CSS generated from your SCSS.
Bonus: Child Component Support
This setup automatically applies SCSS preprocessing to all child components (like Navigation.svelte, Page.svelte, etc.) as long as they use lang="scss" in their style blocks—no extra configuration needed.
内容的提问来源于stack exchange,提问作者Peter Meier

