Appearance
Creating Local Packages
Local Package Structure and Exports
Our monorepo uses the package.json exports field to control how each local package is accessed, ensuring a clean public API and protecting internal files. This is especially important for packages that are published or consumed by other parts of the workspace.
Workspace Organization
- Workspaces are defined in the root
package.jsonand include:- Every directory inside
packages/(e.g.,@mmv3/core) - Every directory inside
tools/(for deployment and development tools) - The
assets/directory (for shared static assets)
- Every directory inside
Server vs. Client Code
- Server-only code: Suffix files with
.server.ts - Web/client-only code: Suffix files with
.web.ts - Shared code: No suffix needed
When defining exports, make it clear which entry points are safe for all environments and which are server-only. For example:
json
"exports": {
"./reports": "./src/lib/reports/index.ts", // Safe for all environments
"./reports/server": "./src/lib/reports/index.server.ts" // Server-only
}- Consumers should use
@mmv3/core/reportsfor universal code and@mmv3/core/reports/serverfor server-only code.
Why Use the Exports Field?
- Explicit API: Only files listed in
exportsare accessible to consumers. - Internal Protection: Internal files are not importable from outside the package.
- Multi-environment Support: You can define different entry points for Node, browser, ESM, CJS, and TypeScript types.
Example: @mmv3/core/package.json
json
"exports": {
"./utils": "./src/lib/utils/index.ts",
"./cql": "./src/lib/cql/index.ts",
"./api": "./src/lib/api/index.ts",
"./log/server": "./src/lib/log/index.server.ts",
"./context/server": "./src/lib/context/index.server.ts",
"./reports": "./src/lib/reports/index.ts",
"./reports/server": "./src/lib/reports/index.server.ts"
}./reportsis safe for all environments../reports/serveris only for server-side usage.
When to Worry About Exports
- If your package is not exporting anything (i.e., not meant to be consumed by others), you don't need to worry about the
exportsfield. - If your package is consumed elsewhere, always define the
exportsfield explicitly.