The resolution settings
The export conditions mapping each subpath to its source file, as listed in customConditions; where a package
matches more than one, the key order of its own exports decides which applies.
A plugin resolving linked imports to source, deduplicating linked packages and their peers, and leaving all other imports to the default resolution
Linked packages map each exported subpath to its source under a custom condition, next to the build:
{
"exports": {
".": { "source": "./src/index.ts", "default": "./dist/index.js" }
}
}
The consuming project registers the plugin with the same condition in its Vite or Vitest configuration:
import { symlinks } from "@metreeca/rack/vite";
import { defineConfig } from "vitest/config";
export default defineConfig({
plugins: [symlinks({ conditions: "source" })]
});
Creates a plugin running tests against the live source of locally linked packages, with no rebuild.
Imports of workspace members and of sibling checkouts linked into
node_modulesresolve to their TypeScript source, so edits are picked up as they are saved. Packages installed from the registry keep resolving to their build.Packages are looked up as Node does, from the
node_modulesnearest to the importer up through its ancestors, so links hoisted to a workspace root are found from any member; imports with no importer start from the Vite root. A package the importer resolves to an installed copy is looked up again from the Vite root, so a linked checkout importing a package the project links as well loads the linked source rather than its own registry copy.The project and its linked packages load a single copy of every linked package and of each of their
peerDependencies, as libraries holding module state such as Preact hooks require: the links found in thenode_modulesof the Vite root, of its ancestors and of its workspace members extendresolve.dedupe, so that those packages always resolve from the project, dependencies prebundled by the optimizer included, whatever copies a linked checkout installs. Other dependencies of a linked package resolve from its checkout, as Node does.The plugin replaces
resolve.conditions, which breaks registry packages whose exports name a condition without publishing its target: Vite does not fall back todefaultwhen that target is missing from the installed files.