barvian / sveltekit-document

The missing document manager for SvelteKit
55 stars 2 forks source link

Incorrect path escape on "documentPreprocessor" on Windows Server #4

Open PoolFlamingo opened 2 months ago

PoolFlamingo commented 2 months ago

I'm having trouble with a route that tries to load "documentPreprocessor" in svelte.config.js resulting in an error like this:

[vite] Error when evaluating SSR module /@fs/D:/MisCosas/Documentos/Svelte/ssr-document-test/node_modules/@sveltejs/kit/src/runtime/server/index.js: failed to import "D:MisCosasDocumentosSveltessr-document-test
ode_modules@sveltekit-addonsdocumentdistaction.js"
|- Error: Cannot find module 'D:MisCosasDocumentosSveltessr-document-test
ode_modules@sveltekit-addonsdocumentdistaction.js' imported from 'D:/MisCosas/Documentos/Svelte/ssr-document-test/.svelte-kit/generated/root.svelte'
    at nodeImport (file:///D:/MisCosas/Documentos/Svelte/ssr-document-test/node_modules/vite/dist/node/chunks/dep-CDnG8rE7.js:52990:19)
    at ssrImport (file:///D:/MisCosas/Documentos/Svelte/ssr-document-test/node_modules/vite/dist/node/chunks/dep-CDnG8rE7.js:52857:22)
    at eval (D:/MisCosas/Documentos/Svelte/ssr-document-test/.svelte-kit/generated/root.svelte:4:37)
    at async instantiateModule (file:///D:/MisCosas/Documentos/Svelte/ssr-document-test/node_modules/vite/dist/node/chunks/dep-CDnG8rE7.js:52915:5)

It seems that you are not properly escaping the path "D:MyStuffDocumentsSveltessr-document-test ode_modules@sveltekit-addonsdocumentdistaction.js" due to the Windows "\".

This bug can be easily reproduced on a Windows machine by creating a blank svelte-kit project, installing the module, and following the deployment steps.

PoolFlamingo commented 2 months ago

It seems that I have found a concrete solution to this problem, because of the "\", the "sveltekit-document" preprocessor treats the path of the scripts of the svelte-kit modules in posix format (the format that Linux, macos, etc. work with).

The way to solve this problem and other similar ones from other similar preprocessors where paths in this format are involved, is the following:

Add the following to svelte.config.js:

import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import { preprocessor as documentPreprocessor } from '@sveltekit-addons/document';

// Function to fix paths in the preprocessor
function fixWindowsPathsPreprocessor() {
    return {
        markup({ content, filename }) 
        {
            if (process.platform === 'win32') 
            {
                // Function to check if a path is absolute in Windows.
                const isWindowsAbsolutePath = (path) => /^[A-Z]:\\/.test(path);

                // Only replace the slashes if the path is absolute in Windows.
                const fixedContent = content.replace(/([A-Z]:\\[^'"]+)/g, (match) => {
                    if (isWindowsAbsolutePath(match))
                        return match.replace(/\\/g, '/');
                    else
                        return match;
                });

                // Also apply the same correction to the filename.
                const fixedFilename = filename.replace(/\\/g, '/');

                return { code: fixedContent, map: null, filename: fixedFilename };
            }

            // Do not modify anything if we are not on Windows.
            return { code: content, map: null };
        }
    };
}

/** @type {import('@sveltejs/kit').Config} */
const config = {
    // Consult https://kit.svelte.dev/docs/integrations#preprocessors
    // for more information about preprocessors
    preprocess: [vitePreprocess(), documentPreprocessor(), fixWindowsPathsPreprocessor()],

    kit: {
        // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
        // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
        // See https://kit.svelte.dev/docs/adapters for more information about adapters.
        adapter: adapter()
    }
};

export default config;

NOTE: If you already have a function that does the same thing, just put it at the end.