Skip to content

Protect *.server.* files in workspace #12529

@Rich-Harris

Description

@Rich-Harris

Describe the problem

Files that contain .server. in the filename can't be accidentally imported into client-side code, meaning it's safe for them to use sensitive things like API keys and database credentials.

This protection ends at the cwd boundary — anything can be imported into client-side code from outside the current directory. This is unhelpful if your app is in a workspace, importing code from a package elsewhere in that workspace:

<script>
  import { oops } from 'my-workspace-package/module.server.js';
</script>

<h1>{oops()}</h1>

Describe the proposed solution

We could change the behaviour by just removing the !id.startsWith(dirs.cwd) || from this function:

export function is_illegal(id, dirs) {
if (ILLEGAL_IMPORTS.has(id)) return true;
if (!id.startsWith(dirs.cwd) || id.startsWith(dirs.node_modules)) return false;
return ILLEGAL_MODULE_NAME_PATTERN.test(path.basename(id)) || id.startsWith(dirs.server);
}

That would be a breaking change, so it would presumably need to be behind an option until SvelteKit 3 — something like this:

// svelte.config.js
export default {
  kit: {
    allowWorkspaceServerImports: true
  }
}

Open to bikeshedding.

Alternatives considered

Alternatively (or in addition), we could make things fully customizable: #12477. I'm less keen on that because it makes things less obvious/visible within a codebase.

This proposal doesn't address *.server.* files in node_modules. If a workspace package were published, people might be surprised to learn that the protection no longer applies. But I'm not sure that's an easy thing to fix, because of things like prebundling (and in any case we can't just liberally apply this policy to node_modules contents, because of false positives).

Published packages should probably use a solution like server-only instead. Maybe svelte-package could inject server-only imports into server-only modules?

Importance

nice to have

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions