Skip to content

Version 6 breaksbuild --watch throwing [commonjs] [postcss] Unknown word xxxΒ #1186

@rallets

Description

@rallets

Describe the bug

Hi, after a long debugging session I think I found the root cause of a compilation error that is breaking my pipeline.
After upgrading from @sveltejs/vite-plugin-svelte from 5.1.0 to 6.0.0-next.1 (or newer) the build in watch mode has started to throw this error:

[commonjs] [postcss] <path.svelte> Unknown word Table <== a type imported inside script lang ts
file: <path.svelte>?svelte&type=style&lang.css:2:13

for example the mentioned file <path.svelte> starts with:

<script lang="ts">
    import { Table } from '@sveltestrap/sveltestrap';

I just need to transpile SCSS in svelte components, I don't need (or at least explicitly in my configuration) postcss etc.

<style lang="scss">
</style>

The build initially works fine, it's only after I change (and save) a file that this error is thrown. Btw a normal build works fine.

I'm using an inlined config, we can say a bit custom, so for sure I encountered a weird edge case.
Any tips on what is going on?

Many thanks for any help.

Reproduction URL

https://vite.new/svelte

Reproduction

// package.json

{
  "scripts": {
    "v3-watch-all": "cross-env NODE_ENV=development MODE=development node ./App-v3/pipeline/vite.build.mjs",
  }
}
// ./App-v3/pipeline/vite.build.mjs

import path from 'node:path'
import fs from 'node:fs';
import { build } from 'vite'
import { svelte, vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/* 
 * VITE
 * command: vite/vite dev/vite serve => 'serve', vite build => 'build'
 * mode: vite dev => 'development', vite build => 'production'
*/

if (!process.env.NODE_ENV) {
    throw new Error('process.env.NODE_ENV not set [production|development]')
}

if (!process.env.MODE) {
    throw new Error('process.env.MODE not set [production|development]')
}

const basePath = process.cwd();
const isProduction = process.env.NODE_ENV === 'production';
const isWatch = process.env.MODE === 'development';
const outDir = path.resolve(basePath, 'wwwroot/dist-v3/build');

console.log('Using configurations', {
    'MODE:': process.env.MODE,
    'NODE_ENV': process.env.NODE_ENV,
    basePath,
    isProduction,
    isWatch,
    outDir
});

const apps = [
    { root: path.resolve(basePath, './Views/AdminV3/'), alias: 'adminv3', entry: './Views/AdminV3/AdminV3.entry.ts' },
    { root: path.resolve(basePath, './Views/AdminPvcV3/'), alias: 'adminpvcv3', entry: './Views/AdminPvcV3/AdminPvcV3.entry.ts' },
    { root: path.resolve(basePath, './Views/InspectionOverviewV3/'), alias: 'inspectionoverviewv3', entry: './Views/InspectionOverviewV3/InspectionOverviewV3.entry.ts' },
    { root: path.resolve(basePath, './Views/InspectionPvcV3/'), alias: 'inspectionpvcv3', entry: './Views/InspectionPvcV3/InspectionPvcV3.entry.ts' },
    { root: path.resolve(basePath, './Views/InspectionV3/'), alias: 'inspectionv3', entry: './Views/InspectionV3/InspectionV3.entry.ts' }
];

// to be able to generate separated js and css assets, we need to build each app separately.
const builds = apps.map(app => {
    console.log('Building app', { app });

    return build({
        root: app.root,
        appType: 'custom',
        build: {
            // https://rollupjs.org/configuration-options/#watch
            watch: isWatch ? {
                buildDelay: 100,
                clearScreen: true,
                exclude: 'node_modules/**'
            } : undefined,

            // https://rollupjs.org/configuration-options/
            rollupOptions: {
                input: {
                    [app.alias]: app.entry
                },
                output: {
                    entryFileNames: '[name].js',
                    chunkFileNames: '[name].js',
                    assetFileNames: `${app.alias}.[ext]`,
                },

                onwarn(warning, warn) {
                    if (warning.code === 'INVALID_ANNOTATION' && warning.id.includes('node_modules')) {
                        return;
                    }
                    warn(warning);
                },
            },

            // we don't have a "public" dir, we use fs.cpSync(...) instead
            copyPublicDir: false,

            outDir: outDir,
            sourcemap: true,
            modulePreload: {
                polyfill: true
            },
            emptyOutDir: false,
            cssCodeSplit: false,
            minify: isProduction,
            reportCompressedSize: false,

            // default 500
            chunkSizeWarningLimit: 2500
        },
        plugins: [
            svelte({
                emitCss: true,
                experimental: {
                    disableSvelteResolveWarnings: true
                },
                preprocess: [vitePreprocess({ script: false, style: true })],
                compilerOptions: {
                    compatibility: {
                        componentApi: 4
                    },
                    css: 'external',

                    // enable run-time checks when not in production
                    dev: !isProduction,
                },

                // Warnings are normally passed straight to Rollup. You can optionally handle them here, for example to squelch warnings with a particular code
                onwarn: (warning, handler) => {
                    if (warning.filename?.endsWith('/SimpleAutocomplete.svelte')) {
                        return;
                    }

                    // let Rollup handle all other warnings normally
                    handler && handler(warning);
                },
            })
        ],

    })
});

// top level async function is not supported by "concurrently", the vite process exits immediately
async function buildApps() {
    for (let build of builds) {
        await build;
    }
}

try {
    console.log(`Preparing ${outDir}`);

    try {
        // to avoid concurrency issues, the folder could be cleaned from a custom npm script in package.json, "v[x]-clean".
        fs.mkdirSync(outDir, { recursive: true });
    } catch (err) {
        console.error(err)
    }

    console.log('Building svelte apps');

    buildApps();

} catch (e) {
    console.error(e);
    process.exit(1);
}

/*
 * NB. Do not return an exit code, for example via `process.exit(0)`, otherwise
 * "concurrently" will not wait for the script completion while in watch mode.
 */

Logs

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12700H
    Memory: 26.62 GB / 63.68 GB
  Binaries:
    Node: 22.17.0 - C:\Program Files\nodejs\node.EXE
    npm: 11.4.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (131.0.2903.86)
    Internet Explorer: 11.0.26100.1882
  npmPackages:
    @sveltejs/vite-plugin-svelte: ^6.0.0-next.1 => 6.1.0
    svelte: ^5.37.1 => 5.37.1
    vite: ^7.0.6 => 7.0.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions