JGuang / JGuang UI

包导入

本页提供 JGuang UI 技术内容、中文导航与术语适配。

中文模式已适配导航、标题、简介、目录与常用章节名称。翻译状态:部分完成;技术正文目前仍为英文。

The JGuang UI Registry CLI supports package imports for installing components, rewriting imports, and resolving third-party registries.

Package imports let you use private #... import aliases from your package.json instead of compilerOptions.paths in tsconfig.json.

Example

You configure imports in your package.json:

{
  "imports": {
    "#components/*": "./src/components/*.tsx",
    "#lib/*": "./src/lib/*.ts",
    "#hooks/*": "./src/hooks/*.ts"
  }
}

Then import generated components using #... specifiers:

import { Button } from "#components/ui/button"
import { cn } from "#lib/utils"

Package import specifiers must start with #. Use TypeScript 5 or later with moduleResolution: "bundler" and resolvePackageJsonImports: true.

App

For Next.js, Vite, and TanStack Start apps that install components into the same workspace.

Configure ,[object Object]

Add imports for the JGuang UI install targets.

{
  "imports": {
    "#components/*": "./src/components/*.tsx",
    "#lib/*": "./src/lib/*.ts",
    "#hooks/*": "./src/hooks/*.ts"
  }
}

If your app does not use a src directory, remove src/ from the targets. For example:

{
  "imports": {
    "#components/*": "./components/*.tsx",
    "#lib/*": "./lib/*.ts",
    "#hooks/*": "./hooks/*.ts"
  }
}

Configure TypeScript

Enable package import resolution.

{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "resolvePackageJsonImports": true
  }
}

You do not need compilerOptions.paths for these aliases.

Configure ,[object Object]

Use the same #... roots in components.json.

{
  "aliases": {
    "components": "#components",
    "ui": "#components/ui",
    "lib": "#lib",
    "hooks": "#hooks",
    "utils": "#lib/utils"
  }
}

The ui alias uses #components/ui. It is still covered by the #components/* import in package.json.

The utils alias uses #lib/utils. It is covered by #lib/*, so you do not need a separate #utils import.

Monorepo

In a monorepo, use package imports for files inside each package and package exports for files shared across workspaces.

For an app workspace:

{
  "name": "web",
  "private": true,
  "imports": {
    "#components/*": "./src/components/*.tsx",
    "#lib/*": "./src/lib/*.ts",
    "#hooks/*": "./src/hooks/*.ts"
  },
  "dependencies": {
    "@workspace/ui": "workspace:*"
  }
}
{
  "aliases": {
    "components": "#components",
    "ui": "@workspace/ui/components",
    "lib": "#lib",
    "hooks": "#hooks",
    "utils": "@workspace/ui/lib/utils"
  }
}

For the shared UI package:

{
  "name": "@workspace/ui",
  "private": true,
  "imports": {
    "#components/*": "./src/components/*.tsx",
    "#lib/*": "./src/lib/*.ts",
    "#hooks/*": "./src/hooks/*.ts"
  },
  "exports": {
    "./globals.css": "./src/styles/globals.css",
    "./components/*": "./src/components/*.tsx",
    "./lib/*": "./src/lib/*.ts",
    "./hooks/*": "./src/hooks/*.ts"
  }
}
{
  "aliases": {
    "components": "#components",
    "ui": "#components",
    "lib": "#lib",
    "hooks": "#hooks",
    "utils": "#lib/utils"
  }
}

When you run add from apps/web, app-local files use #... imports and shared UI files are imported from @workspace/ui.

import { Button } from "@workspace/ui/components/button"
import { LoginForm } from "#components/login-form"

File extensions

The target pattern in package.json#imports controls whether generated imports include file extensions.

{
  "imports": {
    "#components/*": "./src/components/*.tsx"
  }
}

This generates imports without extensions:

import { Button } from "#components/ui/button"

If you use a target without the extension:

{
  "imports": {
    "#components/*": "./src/components/*"
  }
}

The generated import keeps the source extension:

import { Button } from "#components/ui/button.tsx"

For most apps, use the extension in the target pattern.

Troubleshooting

If TypeScript cannot resolve a #... import, check that:

  • the specifier starts with #
  • the imports entry is in the nearest package.json
  • moduleResolution is set to bundler
  • resolvePackageJsonImports is enabled
  • the matching target exists after components are added

If a component is installed but imports still point to @/..., check that components.json uses the same #... aliases as your package imports.

来源: (root)/package-imports.mdx

JGuang UI 技术文档。

On this page