carbon-preprocess-svelte icon indicating copy to clipboard operation
carbon-preprocess-svelte copied to clipboard

ParseError with scss inside component

Open jeremyben opened this issue 3 years ago • 1 comments

There is a problem during build with optimizeCss, when the scss is inside a component's style tag.

Here is the error:

[plugin-optimize-css] Selector is expected
file: /home/jeremy/app/front/src/lib/Uploads.svelte
125:   @import '../styles/vars';
126:
127:   $position: fixed;
       ^
128:
129:   .container {
error during build:
ParseError: Selector is expected
    at error (file:///home/jeremy/app/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/carbon-preprocess-svelte/dist/index.mjs:19062:18)

It does not recognize nested styles either.

Here is my relevant vite config:

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import sveltePreprocess from 'svelte-preprocess'
import viteCompression from 'vite-plugin-compression'
import { optimizeCss, optimizeImports } from 'carbon-preprocess-svelte'

export default defineConfig(({ mode }) => {
	const prod = mode === 'production'
	return {
		plugins: [
			svelte({
				preprocess: [sveltePreprocess({ scss: true }), optimizeImports()],
				emitCss: prod,
			}),
			prod && optimizeCss(),
			prod && viteCompression({ algorithm: 'brotliCompress', ext: '.br' }),
			prod && viteCompression({ algorithm: 'gzip' }),
		],
		build: {
			minify: prod,
		}
	}
})

I think the plugins order is allright. I do not have any problem during development as my style tags does have lang="scss" for proper preprocessing.

The interesting thing is that the build works fine when the scss is external:

<style lang="scss" src="./container.scss"></style>

Does anybody have a clue ?

jeremyben avatar Dec 24 '21 22:12 jeremyben

Same issue here using SvelteKit. I thought it had something to do with node-sass, sass or svelte-preprocess. But couldn’t nail it down yet.

import adapter from '@sveltejs/adapter-auto';
import { optimizeImports, optimizeCss, elements } from 'carbon-preprocess-svelte';
import path from 'path';
import sveltePreprocess from 'svelte-preprocess';
import autoprefixer from 'autoprefixer';

const production = process.env.NODE_ENV === 'production';
const __dirname = path.resolve();

/** @type {import('@sveltejs/kit').Config} */
const config = {
	preprocess: [
		optimizeImports(), 
		elements(), 
		sveltePreprocess({
			scss: {
				prependData: `@use "${path.resolve(__dirname,'src/variables.scss')}" as *;`,
			},
			postcss: {
				plugins: [
					autoprefixer()
				]
			}
		})
	],
	kit: {
		adapter: adapter(),
		vite: {
			build: {
				sourcemap: !production,
				minify: production
			},

			// plugins: [
			// 	production && optimizeCss() // buggy
			// ],

			optimizeDeps: {
				include: ['@carbon/charts'],
				exclude: ['@carbon/telemetry']
			},

			ssr: {
				noExternal: [production && '@carbon/charts'].filter(Boolean)
			},

			css: {
				preprocessorOptions: {
					scss: {
						additionalData: `@use "${path.resolve(__dirname,'src/variables.scss')}" as *;`,
					}
				}
			}
		}
	}
};

export default config;

johannesmutter avatar Mar 23 '22 23:03 johannesmutter

Commenting for posterity. This library was rewritten in v0.11, but many concepts still apply.

optimizeImports preprocessor

optimizeImports does not perform preprocessing. Additional preprocessing (e.g., TypeScript) should be performed first.

For example, vitePreprocess should precede optimizeImports.

// svelte.config.js
import adapter from "@sveltejs/adapter-static";
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
import { optimizeImports } from "carbon-preprocess-svelte";

/** @type {import('@sveltejs/kit').Config} */
const config = {
  preprocess: [
    // Preprocessors are run in sequence.
    // If using TypeScript, the code must be transpiled first.
    vitePreprocess(),
    optimizeImports(),
  ],
  kit: {
    adapter: adapter(),
  },
};

optimizeCss plugin

The optimizeCss plugin was rewritten from scratch. It's sole responsibility is to avoid false positives. This means it's slightly less aggressive in what unused styles it can remove. However, accuracy must be higher.

It was also rewritten as a Vite plugin (meaning it's Rollup compatible) as well as Webpack plugin.

Docs on using it are here: https://github.com/carbon-design-system/carbon-preprocess-svelte?tab=readme-ov-file#optimizecss

metonym avatar Apr 13 '24 20:04 metonym