@jogak/ui 0.1.0-alpha.1 → 0.1.0-alpha.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -0
- package/README.md +201 -15
- package/dist/app/App.d.ts +24 -1
- package/dist/components/Preview/IframeMount.d.ts +35 -0
- package/dist/components/Preview/ShadowMount.d.ts +25 -0
- package/dist/components/Preview/index.d.ts +19 -2
- package/dist/host/index.cjs +1 -0
- package/dist/host/index.d.ts +38 -1
- package/dist/host/index.mjs +40 -34
- package/dist/index.cjs +1 -0
- package/dist/index.mjs +726 -901
- package/package.json +15 -6
- package/preview-frame.html +17 -0
- package/src/app/App.tsx +189 -0
- package/src/app/main.tsx +31 -0
- package/src/app/preview-frame.tsx +61 -0
- package/src/components/Actions/index.tsx +92 -0
- package/src/components/Controls/index.tsx +190 -0
- package/src/components/Preview/IframeMount.tsx +101 -0
- package/src/components/Preview/ShadowMount.tsx +57 -0
- package/src/components/Preview/index.tsx +766 -0
- package/src/components/Sidebar/index.tsx +285 -0
- package/src/hooks/useRegistry.ts +22 -0
- package/src/index.ts +12 -0
- package/src/styles/jogak.css +128 -0
- package/src/vite-env.d.ts +30 -0
- package/dist/host/index.js +0 -1
- package/dist/index.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,118 @@ All notable changes to Jogak packages are documented here. The repository follow
|
|
|
5
5
|
|
|
6
6
|
Version numbers apply to all packages in the workspace (synchronized release).
|
|
7
7
|
|
|
8
|
+
## [0.1.0-alpha.10.2] — 2026-05-09
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **vitest.workspace.ts**: 알파.10에서 7개 패키지 디렉토리를 삭제했지만 `vitest.workspace.ts`가 여전히 `packages/react`, `packages/next`, `packages/web-components`를 참조해 `pnpm test` 시 startup error. core/ui/cli 3개로 정리.
|
|
13
|
+
|
|
14
|
+
기타 패키지: source 변경 없음, synchronized release 유지를 위해 버전만 bump.
|
|
15
|
+
|
|
16
|
+
## [0.1.0-alpha.10.1] — 2026-05-09
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **CI typecheck**: 알파.10에서 root `tsconfig.json` references에 `packages/cli`를 추가했으나, `tsc -b`가 cli typecheck 시점에 ui의 `dist/host/index.d.ts` (실제 파일은 없음 — ui는 `noEmit: true`)를 찾으려 해 `Cannot find module '@jogak/ui/host'` 에러 발생. 알파.9 이전처럼 cli는 root references에서 제외 — cli는 자기 `pnpm build` 단계의 `tsc -p tsconfig.json`에서 typecheck됨 (그 시점엔 ui dist가 이미 빌드돼 있음).
|
|
21
|
+
|
|
22
|
+
기타 패키지: source 변경 없음, synchronized release 유지를 위해 버전만 bump.
|
|
23
|
+
|
|
24
|
+
## [0.1.0-alpha.10] — 2026-05-09
|
|
25
|
+
|
|
26
|
+
### Architectural unification — 10 packages → 3 packages
|
|
27
|
+
|
|
28
|
+
알파.9.x에서 분리됐던 4개 빌더 어댑터(`@jogak/vite-adapter`, `@jogak/next-adapter`, `@jogak/webpack-adapter`, `@jogak/standalone-adapter`)와 3개 프레임워크 렌더러(`@jogak/react`, `@jogak/next`, `@jogak/web-components`)를 모두 `@jogak/core`로 통합. 이들의 본질은 build-tool / runtime 통합 코드이며 별도 패키지로 격리할 만한 런타임 substance가 없다는 판단.
|
|
29
|
+
|
|
30
|
+
이제 publish되는 패키지는 `@jogak/core`, `@jogak/ui`, `@jogak/cli` 3개로 축소. 기능은 모두 유지되며 사용자 install도 단순화 (vite/next/webpack peer deps는 모두 `peerDependenciesMeta.optional` 처리 — 사용자가 실제로 쓰는 빌더만 install).
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- **`@jogak/core/adapters/{vite,next,webpack,standalone}`**: 4개 builder adapter subpath. `@jogak/${name}-adapter` 패키지를 흡수.
|
|
35
|
+
- **`@jogak/core/renderers/{react,next,web-components}`**: 3개 framework renderer subpath. 동명 별도 패키지를 흡수.
|
|
36
|
+
- **`@jogak/core/vite-plugin`**: 알파.9.x의 `@jogak/core/vite`를 정식 명명. 기존 `@jogak/core/vite`는 backward-compat alias로 유지.
|
|
37
|
+
- **CLI `loadAdapter`**: 사용자 cwd의 `@jogak/core` exports를 직접 lookup해서 adapter dynamic import. 별도 어댑터 패키지 install 불필요.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- **import 경로 마이그레이션** (사용자 영향):
|
|
42
|
+
- `import ... from '@jogak/react'` → `import ... from '@jogak/core/renderers/react'`
|
|
43
|
+
- `import ... from '@jogak/next'` → `import ... from '@jogak/core/renderers/next'`
|
|
44
|
+
- `import ... from '@jogak/web-components'` → `import ... from '@jogak/core/renderers/web-components'`
|
|
45
|
+
- `import { jogak } from '@jogak/core/vite'` → `import { jogak } from '@jogak/core/vite-plugin'` (구 경로도 동작하지만 deprecated)
|
|
46
|
+
- **`@jogak/core` peer deps 확장**: react/react-dom/next/webpack/webpack-dev-server/webpack-merge/html-webpack-plugin 추가 (모두 optional). 사용자가 쓰는 빌더만 설치.
|
|
47
|
+
- **iframe scaffold 코드** (next-adapter, webpack-adapter): 생성되는 page.tsx/preview-entry.tsx가 `@jogak/core/renderers/react`를 import (이전 `@jogak/react`).
|
|
48
|
+
|
|
49
|
+
### Removed
|
|
50
|
+
|
|
51
|
+
- 7개 패키지 디렉토리 + npm registry deprecate notice:
|
|
52
|
+
- `@jogak/react`, `@jogak/next`, `@jogak/web-components`
|
|
53
|
+
- `@jogak/vite-adapter`, `@jogak/next-adapter`, `@jogak/webpack-adapter`, `@jogak/standalone-adapter`
|
|
54
|
+
- 알파.9.x 사용자는 `npm view @jogak/<pkg> deprecated` 메시지로 마이그레이션 안내 받음.
|
|
55
|
+
|
|
56
|
+
### CI
|
|
57
|
+
|
|
58
|
+
- `release.yml`: pack/publish 목록을 `core/ui/cli` 3개로 축소. Trusted Publisher 신규 등록 zero (3개 모두 알파.9 시점 등록 완료).
|
|
59
|
+
|
|
60
|
+
## [0.1.0-alpha.9.2] — 2026-05-09
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- **CI**: `release.yml`의 publish 단계가 `jogak-next-*.tgz` 글로브 패턴을 사용해 `next` 패키지 publish 시 `next-adapter` tarball까지 매치되어 npm publish가 EUSAGE(다중 tarball)으로 실패. 이로 인해 알파.9.1에서 `core/react/ui/web-components`만 publish되고 `next/cli` 및 4개 어댑터는 publish 안 됨. 정확한 파일명(`jogak-${pkg}-${VERSION}.tgz`)으로 변경.
|
|
65
|
+
|
|
66
|
+
기타 패키지: source 변경 없음, synchronized release 유지를 위해 버전만 bump.
|
|
67
|
+
|
|
68
|
+
## [0.1.0-alpha.9.1] — 2026-05-09
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
|
|
72
|
+
- **CI**: `release.yml`의 pack 단계가 `core/react/ui/web-components/next/cli`만 포함했고 알파.9에서 신규 추가된 4개 어댑터(`vite-adapter` / `next-adapter` / `webpack-adapter` / `standalone-adapter`)를 누락. v0.1.0-alpha.9 태그로 부분 publish됐으나 어댑터들이 npm에 올라가지 않아 사용자가 import 불가. 4개 어댑터를 pack 목록에 추가 후 alpha.9.1로 재발행.
|
|
73
|
+
|
|
74
|
+
기타 패키지: source 변경 없음, synchronized release 유지를 위해 버전만 bump.
|
|
75
|
+
|
|
76
|
+
## [0.1.0-alpha.9] — 2026-05-09
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- **`@jogak/vite-adapter`**, **`@jogak/next-adapter`**, **`@jogak/webpack-adapter`**, **`@jogak/standalone-adapter`**: 새 builder-agnostic adapter 패키지군. CLI가 사용자 cwd의 빌더(`next.config`, `vite.config`, `webpack.config`)를 감지하여 해당 adapter를 dynamic import한다. 사용자 컴포넌트는 사용자의 정상 빌더 client에서 평가되므로 utility class compiler(Tailwind v4 등)이 자연스럽게 동작한다.
|
|
81
|
+
- **`@jogak/core`**: `BuilderAdapter` ABI(`adapter.ts`), 빌더 자동 감지(`detectBuilder`, `@jogak/core/server`), preview entry 공통 source(`renderPreviewEntrySource`), postMessage 프로토콜(`@jogak/core/preview-entry/protocol`).
|
|
82
|
+
- **`JogakPluginOptions.userPreviewUrl` / `previewEntryPath`**: adapter dispatch 결과를 host UI iframe src로 주입하는 통로. (`userViteUrl`은 alpha.8 호환을 위해 alias로 유지)
|
|
83
|
+
- **`@jogak/next-adapter`**: Next 14+ App Router에 `<userRoot>/app/jogak-preview/page.tsx` scaffold(`.gitignore` 자동, shutdown cleanup). `next dev` child process spawn + HTTP poll ready 감지. CLI가 사전 생성한 `.jogak/registry.ts`의 entries를 import하여 모듈 평가 시점에 등록.
|
|
84
|
+
- **`@jogak/webpack-adapter`**: `<userRoot>/.jogak/webpack-preview/preview-entry.tsx` scaffold + `webpack-dev-server` programmatic API + `webpack-merge`로 사용자 webpack.config 통합.
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
|
|
88
|
+
- **`@jogak/core`**: `fs`/`path`를 사용하는 server-only utility(`detectBuilder`, `resolveGlobalCssPaths`, `detectUserGlobalCss`)를 `@jogak/core/server` subpath로 분리. client bundle에 Node 모듈이 leak되는 문제를 차단.
|
|
89
|
+
- **`@jogak/core`**, **`@jogak/ui`**, all adapters: CJS 산출물 확장자를 `.js` → `.cjs`로 변경. `"type": "module"` 환경에서 `.js`가 ESM으로 해석되어 발생하던 `exports is not defined in ES module scope` 오류를 해소.
|
|
90
|
+
- **`previewIsolation`** default: `'shadow'` → `'iframe'`. shadow DOM 모드는 일부 portal 라이브러리(Radix 등)와 호환성 이슈가 있어 iframe 격리를 표준으로.
|
|
91
|
+
- **`@jogak/ui`** preview-frame: 기존 `__jogak_setProps__` 직접 호출 프로토콜 → postMessage(`jogak:setProps` / `jogak:rendered` / `jogak:error`)로 통일. 모든 어댑터의 iframe entry가 동일 프로토콜을 따른다.
|
|
92
|
+
- **`@jogak/cli`**: `jogak dev`가 registry 생성 완료를 대기한 뒤 어댑터를 spawn (이전: fire-and-forget). non-vite 어댑터의 scaffold가 비어있는 registry를 import하던 race condition 해소.
|
|
93
|
+
|
|
94
|
+
### Fixed
|
|
95
|
+
|
|
96
|
+
- **`@jogak/cli`**: 어댑터 dynamic import 시 `import.meta.resolve`/`createRequire`가 cli/dist 기준으로 해석돼 사용자 cwd의 어댑터 패키지를 찾지 못하던 문제. `<cwd>/node_modules/@jogak/${name}-adapter/package.json`을 직접 읽어 `exports['.'].import` 경로로 해석하도록 변경.
|
|
97
|
+
- **`@jogak/next-adapter`**: 이전 시도의 `__jogak_preview__` 경로는 Next App Router의 private folder convention(`_`로 시작하는 폴더는 라우팅 제외)과 충돌해 404. `jogak-preview`로 변경.
|
|
98
|
+
|
|
99
|
+
## [0.1.0-alpha.3] — 2026-05-07
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
|
|
103
|
+
- **`@jogak/core`**: Vite plugin now auto-detects user `tsconfig.json` (and `tsconfig.app.json` for the Vite scaffold-default split-references layout) and converts `compilerOptions.paths` into `vite resolve.alias`. This makes `runHost`-driven dev/build work zero-config for projects that use path aliases (shadcn/ui's `@/lib/utils` etc.). Without this, `runHost` ignored the user's `vite.config.ts` (`configFile: false`) and any `@/...` import inside a user component failed to resolve.
|
|
104
|
+
- **`JogakPluginOptions.resolveAlias`**: explicit user-provided alias map for cases the auto-extraction can't handle (extends chains, complex glob patterns). Explicit entries override auto-extracted ones. Relative paths are resolved against the user root.
|
|
105
|
+
|
|
106
|
+
### Fixed
|
|
107
|
+
|
|
108
|
+
- Path aliases declared in user `tsconfig` are now respected during `jogak dev` and `jogak build`. Previously, every `*.jogak.tsx` that imported a component using `@/`-style imports would fail with `Failed to resolve import "@/..."` in the browser dev overlay.
|
|
109
|
+
|
|
110
|
+
Other packages: no source changes; version bumped to keep the workspace synchronized.
|
|
111
|
+
|
|
112
|
+
## [0.1.0-alpha.2] — 2026-05-07
|
|
113
|
+
|
|
114
|
+
### Fixed
|
|
115
|
+
|
|
116
|
+
- **`@jogak/ui`**: Published package was missing `src/app/main.tsx` (referenced by `index.html` as the SPA entry), causing `jogak dev` to 404 on the entry script and `jogak build` to fail with `Failed to resolve /src/app/main.tsx`. The `files` field in `package.json` only included `dist/`, but `runHost` uses the package's `index.html` as the Vite root and resolves `/src/app/main.tsx` from source. Added `src/app`, `src/components`, `src/hooks`, `src/index.ts`, `src/vite-env.d.ts` to `files`. Internal `src/host` and `src/examples` remain excluded (host is consumed via the published `dist/host` build; examples are repository-only demos).
|
|
117
|
+
|
|
118
|
+
Other packages: no source changes; version bumped to keep the workspace synchronized.
|
|
119
|
+
|
|
8
120
|
## [0.1.0-alpha.1] — 2026-05-07
|
|
9
121
|
|
|
10
122
|
### Changed
|
package/README.md
CHANGED
|
@@ -12,27 +12,32 @@ pnpm add @jogak/ui @jogak/core @jogak/react react react-dom
|
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
|
-
###
|
|
15
|
+
### `jogak.config.ts` 사용 (권장)
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
import { jogak } from '@jogak/core/vite'
|
|
17
|
+
알파.7부터 `jogak` CLI는 사용자 프로젝트 root의 `jogak.config.{ts,mts,mjs,js,json}`을
|
|
18
|
+
자동 발견해 옵션을 읽습니다. shadcn/ui 사용자가 자주 만지는 옵션은 한 곳에 선언하세요:
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
```ts
|
|
21
|
+
// jogak.config.ts (사용자 프로젝트 root)
|
|
22
|
+
import { defineJogakConfig } from '@jogak/core'
|
|
23
|
+
|
|
24
|
+
export default defineJogakConfig({
|
|
25
|
+
globalCss: true, // 사용자 globalCss 자동 감지 + import
|
|
26
|
+
// previewIsolation: 'iframe', // 'iframe' (default, 알파.8) | 'shadow' (deprecated) | 'none' (deprecated)
|
|
27
|
+
// userVite: { port: 5174 }, // 사용자 vite spawn 옵션 (자동 탐지 시 미명시)
|
|
28
|
+
codeTheme: 'vsDark',
|
|
29
|
+
port: 5173, // dev server (CLI --port로 override)
|
|
23
30
|
})
|
|
24
31
|
```
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
import { JogakApp } from '@jogak/ui'
|
|
31
|
-
import { createRoot } from 'react-dom/client'
|
|
33
|
+
CLI는 본 config의 옵션을 읽어 jogak SPA 빌드/dev에 전달합니다. CLI 플래그가
|
|
34
|
+
명시되면 config 값을 override합니다 (Vite 패턴).
|
|
35
|
+
|
|
36
|
+
### `jogak.config.ts` 미사용 (CLI flag만)
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
```bash
|
|
39
|
+
jogak dev --global-css --preview-isolation=none
|
|
40
|
+
jogak build --global-css --preview-isolation=shadow
|
|
36
41
|
```
|
|
37
42
|
|
|
38
43
|
### Static catalog (Next.js / any host bundler)
|
|
@@ -48,6 +53,17 @@ export default function Page() {
|
|
|
48
53
|
|
|
49
54
|
`@jogak/ui` ships pre-built ESM/CJS — no `transpilePackages` required for Next.js.
|
|
50
55
|
|
|
56
|
+
### legacy: `vite.config.ts`에 `jogak()` plugin 직접 사용
|
|
57
|
+
|
|
58
|
+
> 알파.6까지의 README는 사용자 `vite.config.ts`에 `jogak({ globalCss: true })`를
|
|
59
|
+
> 작성하라 안내했지만, 이는 사용자 일반 vite 빌드용에만 적용되고 jogak SPA에는
|
|
60
|
+
> 무효였습니다 (`runHost`가 `configFile: false`로 사용자 vite config 무시).
|
|
61
|
+
> 알파.7부터는 위 `jogak.config.ts` 패턴을 사용하세요.
|
|
62
|
+
|
|
63
|
+
`@jogak/core/vite`의 `jogak()` plugin은 사용자가 vite로 직접 jogak 카탈로그를
|
|
64
|
+
embed하는 고급 시나리오(예: Next.js page 안에서 `<JogakApp entries={...} />`로
|
|
65
|
+
정적 entries를 전달할 때 빌드 타임 generate)에서만 사용합니다.
|
|
66
|
+
|
|
51
67
|
### Sub-paths
|
|
52
68
|
|
|
53
69
|
```ts
|
|
@@ -62,6 +78,176 @@ import { runHost } from '@jogak/ui/host' // Node-only, used by @jogak/cli
|
|
|
62
78
|
|
|
63
79
|
See the [main README](https://github.com/devclib/jogak#readme) for the full host embedding guide.
|
|
64
80
|
|
|
81
|
+
## Styling roadmap
|
|
82
|
+
|
|
83
|
+
| 단계 | 상태 | 내용 |
|
|
84
|
+
|------|------|------|
|
|
85
|
+
| alpha.4 | ✅ 완료 | jogak UI 빌드에 Tailwind v4 + `jogak:` prefix 도입 |
|
|
86
|
+
| alpha.5 | ✅ 완료 | jogak UI 컴포넌트를 Tailwind class로 마이그레이션 (4 PR) |
|
|
87
|
+
| alpha.6 | ✅ 완료 | `JogakPluginOptions.globalCss` 옵션 + chrome 보호 rule (단, 통로 부재로 사용자 환경에서 무효 — 알파.7에서 정정) |
|
|
88
|
+
| alpha.7 | ✅ 완료 | `jogak.config.ts` 통로 + `previewIsolation` 옵션 + `JogakHostOptionsBase` 확장 (단, isolation 통로 결함으로 격리 무효 — 알파.7.1에서 정정) |
|
|
89
|
+
| alpha.7.1 | ✅ 완료 | isolation 통로 hotfix + default `previewIsolation: 'shadow'` (단, 사용자 utility 미컴파일 한계 — 알파.8에서 사용자 vite 통합으로 해결) |
|
|
90
|
+
| **alpha.8** | ✅ **본 릴리즈** | **사용자 vite 자동 spawn + 사용자 Tailwind utility 정상 컴파일 + default `previewIsolation: 'iframe'`** |
|
|
91
|
+
| alpha.9+ | 예정 | shadow 모드 사용자 utility inject 부활, iframe sandbox 옵션, multi-baseline VR |
|
|
92
|
+
|
|
93
|
+
### 사용자 globalCss 적용
|
|
94
|
+
|
|
95
|
+
`runHost`는 vite root를 `@jogak/ui` 패키지로 두고 사용자 `vite.config.ts` / `main.tsx`를 무시하므로(`configFile: false`), 사용자 `index.css`(Tailwind/shadcn 디자인 토큰)가 jogak SPA에 자동 적용되지 않습니다. `globalCss` 옵션은 이를 opt-in으로 해결합니다.
|
|
96
|
+
|
|
97
|
+
#### 사용법
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
// jogak.config.ts (사용자 프로젝트 root)
|
|
101
|
+
import { defineJogakConfig } from '@jogak/core'
|
|
102
|
+
|
|
103
|
+
export default defineJogakConfig({
|
|
104
|
+
globalCss: true,
|
|
105
|
+
})
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`globalCss: true`는 다음 후보를 우선순위 순으로 자동 감지해 **첫 발견 1개**만 import합니다:
|
|
109
|
+
|
|
110
|
+
1. `src/index.css` (shadcn/ui Vite)
|
|
111
|
+
2. `src/main.css`
|
|
112
|
+
3. `src/styles.css`
|
|
113
|
+
4. `src/styles/globals.css` (Next.js shadcn)
|
|
114
|
+
5. `src/styles/index.css`
|
|
115
|
+
6. `src/app/globals.css` (Next.js App Router shadcn)
|
|
116
|
+
7. `src/global.css`
|
|
117
|
+
8. `src/app.css`
|
|
118
|
+
|
|
119
|
+
명시 경로(상대/절대) 또는 배열도 사용 가능합니다:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
// 명시 경로 1개
|
|
123
|
+
defineJogakConfig({ globalCss: './src/index.css' })
|
|
124
|
+
|
|
125
|
+
// 다중 import (디자인 토큰 + reset 분리)
|
|
126
|
+
defineJogakConfig({ globalCss: ['./src/tokens.css', './src/reset.css'] })
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### 격리 보장 (default `previewIsolation: 'iframe'`, 알파.8)
|
|
130
|
+
|
|
131
|
+
- **Tailwind utility class**: jogak UI는 `prefix=jogak`로 빌드되어 사용자 utility와 충돌 zero (예: 사용자 `bg-primary` ≠ jogak `jogak:bg-...`).
|
|
132
|
+
- **CSS variable**: jogak은 `--jogak-*` prefix로 namespace 격리 → 사용자 `:root { --primary }` 같은 디자인 토큰은 영향 없음.
|
|
133
|
+
- **Form element 보호**: `[data-jogak-shell]` 안의 button/input/select/textarea는 사용자 reset의 `border` / `background` / `color` 침범을 받지 않도록 `:where()` 보호 rule 적용. specificity 0이라 사용자가 명시적으로 `[data-jogak-shell] button { ... }`를 작성하면 정상 override됩니다.
|
|
134
|
+
|
|
135
|
+
### previewIsolation 사용 가이드 (알파.8)
|
|
136
|
+
|
|
137
|
+
jogak chrome ↔ 사용자 영역의 **양방향 격리** + 사용자 컴포넌트는 사용자 디자인 시스템 그대로 표시. 알파.8부터 default가 `'iframe'`로 변경되어 사용자 vite 인스턴스가 자동 spawn되고, iframe document가 사용자 vite의 정상 client로 작동합니다.
|
|
138
|
+
|
|
139
|
+
#### 모드 비교
|
|
140
|
+
|
|
141
|
+
| 모드 | mount | 사용자 utility 컴파일 | chrome 침범 | Radix portal | cold start |
|
|
142
|
+
|------|-------|---------------------|-----------|--------------|-----------|
|
|
143
|
+
| `'iframe'` (default) | iframe document (사용자 vite scope) | **정상** ✅ | zero | iframe document (정상) | ★★ |
|
|
144
|
+
| `'shadow'` (deprecated) | ShadowRoot | **미컴파일** | zero | document.body (shadow 외부) | ★★★ |
|
|
145
|
+
| `'none'` (deprecated) | 같은 document | 미컴파일 | **있음** | document.body | ★★★ |
|
|
146
|
+
|
|
147
|
+
#### `'iframe'` 모드 (default, 알파.8)
|
|
148
|
+
|
|
149
|
+
jogak CLI가 사용자 cwd의 `vite.config.{ts,mts,js,mjs,cjs}`를 자동 탐지해 별도 vite dev server를 spawn합니다. iframe `src`가 그 사용자 vite를 가리키므로 사용자 plugins(@tailwindcss/vite, custom alias 등)이 정상 작동 → **사용자 컴포넌트가 사용자 디자인 그대로 표시**.
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
// jogak.config.ts (사용자 프로젝트 root)
|
|
153
|
+
import { defineJogakConfig } from '@jogak/core'
|
|
154
|
+
|
|
155
|
+
export default defineJogakConfig({
|
|
156
|
+
globalCss: true,
|
|
157
|
+
// previewIsolation: 'iframe', // default
|
|
158
|
+
// userVite: { port: 5174 }, // 명시 시
|
|
159
|
+
})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**자동 동작:**
|
|
163
|
+
- 사용자 `vite.config.ts` 자동 탐지 → `loadConfigFromFile` + `mergeConfig`로 jogak plugins 자동 inject (사용자 액션 zero)
|
|
164
|
+
- 사용자 vite default port 5174 (jogak SPA가 default 5173 차지). 사용자 명시 가능
|
|
165
|
+
- cross-origin postMessage로 entry/args 전달 (`entry.id`만, iframe 안에서 `defaultRegistry.requestEntry(id)` dynamic import)
|
|
166
|
+
- HMR: 사용자 vite의 React Fast Refresh + Tailwind utility 재생성 정상 작동
|
|
167
|
+
|
|
168
|
+
**Fallback:**
|
|
169
|
+
- `vite.config.ts` 미발견 또는 평가 실패 → spawn skip + warning. jogak SPA만 시작 (`'none'` 모드 동등 동작).
|
|
170
|
+
|
|
171
|
+
**주의:**
|
|
172
|
+
- jogak ↔ 사용자 vite 두 인스턴스 (vs 알파.7.1까지의 single vite). dev cold start +100ms, RSS +50~80MB.
|
|
173
|
+
- iframe sandbox 미적용 (사용자 컴포넌트의 fetch/clipboard/storage 자유 사용).
|
|
174
|
+
|
|
175
|
+
#### `'shadow'` 모드 (deprecated)
|
|
176
|
+
|
|
177
|
+
ShadowRoot 격리는 정상 작동하나 사용자 utility가 shadow scope에 inject되지 않아 사용자 컴포넌트가 raw 형태로 표시됩니다. 알파.9에서 사용자 vite의 `transformRequest` API로 shadow inject 부활 검토.
|
|
178
|
+
|
|
179
|
+
#### `'none'` 모드 (deprecated)
|
|
180
|
+
|
|
181
|
+
사용자 globalCss를 outer document에 inject. 사용자 reset이 jogak chrome 침범. back-compat 시나리오만 사용:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
defineJogakConfig({ globalCss: true, previewIsolation: 'none' })
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### scope 가이드 — 알려진 영향 영역 (`'none'` 모드 기준)
|
|
188
|
+
|
|
189
|
+
사용자 css의 다음 패턴은 jogak chrome에도 영향을 줄 수 있습니다 (전역 import이므로):
|
|
190
|
+
|
|
191
|
+
- `body { ... }` — jogak SPA의 body에도 적용
|
|
192
|
+
- `* { ... }` 또는 `*, *::before { ... }` — 모든 요소
|
|
193
|
+
- 글로벌 reset (`button { all: unset }`, `* { border: 1px solid var(--border) }` 등)
|
|
194
|
+
|
|
195
|
+
이를 사용자 콘텐츠 영역(preview)으로만 한정하려면 셀렉터를 `[data-jogak-content] *` scope로 작성하거나, `previewIsolation: 'shadow' | 'iframe'`을 사용하세요.
|
|
196
|
+
|
|
197
|
+
```css
|
|
198
|
+
/* 권장: preview 영역으로만 한정 */
|
|
199
|
+
[data-jogak-content] *,
|
|
200
|
+
[data-jogak-content] *::before,
|
|
201
|
+
[data-jogak-content] *::after {
|
|
202
|
+
box-sizing: border-box;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
[data-jogak-content] button {
|
|
206
|
+
/* 사용자 디자인 시스템 button reset */
|
|
207
|
+
all: unset;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### selector hint
|
|
212
|
+
|
|
213
|
+
- `[data-jogak-shell]` — `JogakApp` 최상위 wrapper (chrome + preview 모두 포함)
|
|
214
|
+
- `[data-jogak-content]` — Preview의 사용자 콘텐츠 영역 (사용자 컴포넌트가 렌더되는 div)
|
|
215
|
+
|
|
216
|
+
### 알파.6 → 알파.7 마이그레이션
|
|
217
|
+
|
|
218
|
+
알파.6 README는 다음 가이드를 안내했습니다:
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
// alpha.6 README (무효)
|
|
222
|
+
// vite.config.ts
|
|
223
|
+
import { jogak } from '@jogak/core/vite'
|
|
224
|
+
export default defineConfig({
|
|
225
|
+
plugins: [react(), jogak({ globalCss: true })],
|
|
226
|
+
})
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
이 설정은 사용자 일반 vite 빌드용에만 적용되고 jogak SPA에는 전달되지 않았습니다.
|
|
230
|
+
알파.7부터 `jogak.config.ts`로 옮기세요:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
// alpha.7+ — jogak.config.ts (사용자 프로젝트 root)
|
|
234
|
+
import { defineJogakConfig } from '@jogak/core'
|
|
235
|
+
|
|
236
|
+
export default defineJogakConfig({
|
|
237
|
+
globalCss: true,
|
|
238
|
+
})
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
`vite.config.ts`에 `jogak()` plugin이 그대로 있어도 jogak SPA에는 영향 없으므로
|
|
242
|
+
당장 제거할 필요는 없습니다 (alpha.6 동작 유지). 하지만 jogak.config.ts로 옮긴 후
|
|
243
|
+
중복 제거를 권장합니다.
|
|
244
|
+
|
|
245
|
+
### 알려진 한계
|
|
246
|
+
|
|
247
|
+
- `globalCss` 옵션은 **opt-in**입니다 (default `false`). 알파.5까지의 동작은 동일합니다.
|
|
248
|
+
- `globalCss: true` 자동 감지는 dev 시작 시점에 한 번만 수행됩니다. 후보 css 파일이 dev 시작 후에 새로 추가되면 dev 서버를 재시작해야 합니다. 명시 경로(`globalCss: './src/index.css'`)는 파일이 나중에 생성되어도 정상 hot reload됩니다.
|
|
249
|
+
- CSS module(`.module.css`)을 자동 감지 후보에서 직접 import하지 않습니다 — 명시 경로로 넘기면 Vite가 module 처리합니다.
|
|
250
|
+
|
|
65
251
|
- Repository: https://github.com/devclib/jogak
|
|
66
252
|
- Issues: https://github.com/devclib/jogak/issues
|
|
67
253
|
- License: [MIT](./LICENSE)
|
package/dist/app/App.d.ts
CHANGED
|
@@ -14,5 +14,28 @@ export interface JogakAppProps {
|
|
|
14
14
|
readonly entries?: readonly RegistryEntry[];
|
|
15
15
|
readonly metas?: readonly RegistryEntryMeta[];
|
|
16
16
|
readonly codeTheme?: string;
|
|
17
|
+
/**
|
|
18
|
+
* 알파.8: Preview 영역 격리 모드. default `'iframe'`.
|
|
19
|
+
*
|
|
20
|
+
* - `'iframe'` (default) — 사용자 vite 정상 client(iframe)에 마운트. 사용자 utility 정상 컴파일.
|
|
21
|
+
* - `'shadow'` (deprecated) — ShadowRoot 안에 마운트. 사용자 utility 미적용.
|
|
22
|
+
* - `'none'` (deprecated) — chrome 같은 document에 렌더. 알파.6까지의 동작.
|
|
23
|
+
*
|
|
24
|
+
* 자세한 트레이드오프는 `@jogak/ui` README의 "previewIsolation 사용 가이드" 참조.
|
|
25
|
+
*/
|
|
26
|
+
readonly previewIsolation?: 'none' | 'shadow' | 'iframe';
|
|
27
|
+
/**
|
|
28
|
+
* 알파.9: 어댑터 dev URL. iframe `src` base.
|
|
29
|
+
* 빈 문자열 시 fallback (jogak SPA Vite scope의 preview-frame.tsx).
|
|
30
|
+
*/
|
|
31
|
+
readonly userPreviewUrl?: string;
|
|
32
|
+
/**
|
|
33
|
+
* 알파.9: iframe entry path (예: `/__jogak_preview__/index.html`).
|
|
34
|
+
*/
|
|
35
|
+
readonly previewEntryPath?: string;
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated 알파.10 제거 예정. `userPreviewUrl` 사용.
|
|
38
|
+
*/
|
|
39
|
+
readonly userViteUrl?: string;
|
|
17
40
|
}
|
|
18
|
-
export declare function JogakApp({ entries, metas, codeTheme, }?: JogakAppProps): ReactElement;
|
|
41
|
+
export declare function JogakApp({ entries, metas, codeTheme, previewIsolation, userPreviewUrl, previewEntryPath, userViteUrl, }?: JogakAppProps): ReactElement;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { RegistryEntry } from '@jogak/core';
|
|
3
|
+
export interface IframeMountProps {
|
|
4
|
+
readonly entry: RegistryEntry;
|
|
5
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
6
|
+
/**
|
|
7
|
+
* 알파.9: 어댑터 dev URL (예: `http://localhost:5174`).
|
|
8
|
+
* 빈 문자열 시 fallback (jogak SPA Vite scope의 `/preview-frame.html`).
|
|
9
|
+
*/
|
|
10
|
+
readonly userPreviewUrl: string;
|
|
11
|
+
/**
|
|
12
|
+
* 알파.9: iframe entry path (예: `/__jogak_preview__/index.html`).
|
|
13
|
+
* 어댑터의 `previewEntryMeta.devEntryPath`.
|
|
14
|
+
*/
|
|
15
|
+
readonly previewEntryPath: string;
|
|
16
|
+
readonly className?: string;
|
|
17
|
+
readonly 'data-testid'?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 알파.8: previewIsolation='iframe' 모드의 mount 컴포넌트.
|
|
21
|
+
*
|
|
22
|
+
* 통신:
|
|
23
|
+
* - 사용자 vite spawn URL이 주어지면(`userViteUrl !== ''`) iframe src를
|
|
24
|
+
* `${userViteUrl}/__jogak_preview__/index.html` (cross-origin)로 설정.
|
|
25
|
+
* - 동일 origin fallback 시 `/preview-frame.html` (jogak SPA Vite scope).
|
|
26
|
+
*
|
|
27
|
+
* 양쪽 모두 postMessage로 통신:
|
|
28
|
+
* - 부모 → iframe: `{ type: 'jogak:setProps', entryId, args }` | `{ type: 'jogak:unmount' }`
|
|
29
|
+
* - iframe → 부모: `{ type: 'jogak:ready' }` | `{ type: 'jogak:rendered', entryId }`
|
|
30
|
+
*
|
|
31
|
+
* `entry`는 객체가 아닌 **id만 전달** — iframe 안에서 `defaultRegistry.requestEntry(id)`로
|
|
32
|
+
* dynamic import. 사용자 vite scope의 entry 가상 모듈이 사용자 컴포넌트를 fetch하므로
|
|
33
|
+
* 사용자 plugins(@tailwindcss/vite, custom alias 등)이 정상 작동.
|
|
34
|
+
*/
|
|
35
|
+
export declare function IframeMount({ entry, args, userPreviewUrl, previewEntryPath, className, 'data-testid': dataTestId, }: IframeMountProps): ReactElement;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactElement, ReactNode, CSSProperties } from 'react';
|
|
2
|
+
export interface ShadowMountProps {
|
|
3
|
+
readonly children: ReactNode;
|
|
4
|
+
readonly className?: string;
|
|
5
|
+
readonly style?: CSSProperties;
|
|
6
|
+
readonly 'data-testid'?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 알파.7.1: previewIsolation='shadow' 모드의 mount 컴포넌트.
|
|
10
|
+
*
|
|
11
|
+
* 책임: 양방향 격리만 제공 (Preview ↔ outer document 양방향 cascade 차단).
|
|
12
|
+
* - 사용자 globalCss는 main.tsx 가드로 outer document에 inject되지 않음.
|
|
13
|
+
* - shadow root 안에는 jogak chrome css도 사용자 css도 없음 (둘 다 외부에서 격리).
|
|
14
|
+
* - 사용자 컴포넌트의 utility class 컴파일은 결함 B (알파.8 사이클).
|
|
15
|
+
*
|
|
16
|
+
* 알파.7 결함 정정:
|
|
17
|
+
* - `syncStyleSheets`/`MutationObserver`/`adoptedStyleSheets` 흡수 로직 제거.
|
|
18
|
+
* 알파.7은 outer document에 사용자 css가 있는 한 chrome을 침범했고, shadow
|
|
19
|
+
* 안의 흡수 로직은 의미가 없었음. 알파.7.1: outer에 사용자 css 자체가 없음.
|
|
20
|
+
*
|
|
21
|
+
* Radix portal 한계 (사용자 인지 필요, README 명시):
|
|
22
|
+
* - default Portal target = document.body (shadow 외부). 사용자가 명시적으로
|
|
23
|
+
* `<Portal container={shadowRootEl}>`을 전달해야 portal 내용도 격리됨.
|
|
24
|
+
*/
|
|
25
|
+
export declare function ShadowMount({ children, className, style, 'data-testid': dataTestId, }: ShadowMountProps): ReactElement;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
|
-
import { UseEntryState } from '@jogak/react';
|
|
2
|
+
import { UseEntryState } from '@jogak/core/renderers/react';
|
|
3
3
|
export interface PreviewProps {
|
|
4
4
|
readonly entryId: string;
|
|
5
5
|
readonly jogakName: string | null;
|
|
@@ -12,6 +12,23 @@ export interface PreviewProps {
|
|
|
12
12
|
* 첫 jogak로 자동 보정하기 위한 콜백. 부모가 selectedJogakName / URL을 갱신.
|
|
13
13
|
*/
|
|
14
14
|
readonly onResolveJogak?: (entryId: string, jogakName: string) => void;
|
|
15
|
+
/**
|
|
16
|
+
* 알파.8: Preview 영역 격리 모드. default `'iframe'`.
|
|
17
|
+
*
|
|
18
|
+
* - `'iframe'` (default) — 사용자 vite scope에 마운트. 사용자 utility 정상 컴파일.
|
|
19
|
+
* - `'shadow'` (deprecated) — ShadowRoot에 마운트. 사용자 utility 미적용.
|
|
20
|
+
* - `'none'` (deprecated) — chrome과 같은 document에 렌더.
|
|
21
|
+
*/
|
|
22
|
+
readonly previewIsolation?: 'none' | 'shadow' | 'iframe';
|
|
23
|
+
/**
|
|
24
|
+
* 알파.9: 어댑터 dev URL. iframe `src` base.
|
|
25
|
+
* 빈 문자열 시 fallback (jogak SPA Vite scope의 `/preview-frame.html`).
|
|
26
|
+
*/
|
|
27
|
+
readonly userPreviewUrl?: string;
|
|
28
|
+
/**
|
|
29
|
+
* 알파.9: iframe entry path.
|
|
30
|
+
*/
|
|
31
|
+
readonly previewEntryPath?: string;
|
|
15
32
|
}
|
|
16
33
|
/**
|
|
17
34
|
* Preview — `useEntry(entryId)`의 status에 따라 분기 (계약 §5.4).
|
|
@@ -23,5 +40,5 @@ export interface PreviewProps {
|
|
|
23
40
|
*
|
|
24
41
|
* Layout shift 방지를 위해 캔버스 영역 minHeight 유지.
|
|
25
42
|
*/
|
|
26
|
-
export declare function Preview({ entryId, jogakName, overrideArgs, onArgChange, onReset, codeTheme, onResolveJogak, }: PreviewProps): ReactElement;
|
|
43
|
+
export declare function Preview({ entryId, jogakName, overrideArgs, onArgChange, onReset, codeTheme, onResolveJogak, previewIsolation, userPreviewUrl, previewEntryPath, }: PreviewProps): ReactElement;
|
|
27
44
|
export type { UseEntryState };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var S=Object.create;var g=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var H=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of A(t))!E.call(e,o)&&o!==r&&g(e,o,{get:()=>t[o],enumerable:!(n=k(t,o))||n.enumerable});return e};var a=(e,t,r)=>(r=e!=null?S(B(e)):{},H(t||!e||!e.__esModule?g(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=require("node:url"),u=require("node:path");var f=typeof document<"u"?document.currentScript:null;const x=N.fileURLToPath(typeof document>"u"?require("url").pathToFileURL(__filename).href:f&&f.tagName.toUpperCase()==="SCRIPT"&&f.src||new URL("host/index.cjs",document.baseURI).href),s=u.resolve(u.dirname(x),"..",".."),F=u.resolve(s,"index.html"),V=u.resolve(s,"src/app/main.tsx");async function Y(e){const t=await import("vite"),r=await import("@vitejs/plugin-react"),n=await import("@jogak/core/vite-plugin"),o=await import("@tailwindcss/vite"),{createServer:y,build:h}=t,w=r.default,b=o.default,{jogak:P}=n,U=e.codeTheme??"vsDark",i={patterns:e.patterns,codeTheme:U,cwd:e.userRoot};e.tsConfigFilePath!==void 0&&(i.tsConfigFilePath=e.tsConfigFilePath),e.globalCss!==void 0&&(i.globalCss=e.globalCss),e.previewIsolation!==void 0&&(i.previewIsolation=e.previewIsolation),e.userPreviewUrl!==void 0&&(i.userPreviewUrl=e.userPreviewUrl),e.previewEntryPath!==void 0&&(i.previewEntryPath=e.previewEntryPath),e.userViteUrl!==void 0&&e.userPreviewUrl===void 0&&(i.userViteUrl=e.userViteUrl);const _=e.extraPlugins??[],d={root:s,configFile:!1,plugins:[w(),b(),P(i),..._],optimizeDeps:{include:["react","react-dom/client","@jogak/core","@jogak/core/renderers/react"]}};if(e.mode==="dev"){const D={port:e.port??5173,host:e.host??"localhost",open:e.open??!1,fs:{allow:[s,e.userRoot]}},L={...d,server:D},l=await y(L);await l.listen();const v=l.config.server.port??e.port??5173,c=e.host??"localhost",M=`http://${typeof c=="boolean"?c?"0.0.0.0":"localhost":c}:${v.toString()}/`;let p=!1;return{url:M,port:v,close:async()=>{p||(p=!0,await l.close())},printUrls:()=>{l.printUrls()}}}const C={...d,base:e.base??"./",build:{outDir:e.outDir,emptyOutDir:!0,sourcemap:e.sourcemap??!1,minify:e.minify??"esbuild",rollupOptions:{input:{main:u.resolve(s,"index.html"),preview:u.resolve(s,"preview-frame.html")}}}},R=Date.now(),I=await h(C),T=Date.now()-R,{assetCount:O,totalBytes:j}=q(I);return{outDir:e.outDir,elapsedMs:T,assetCount:O,totalBytes:j}}function q(e){const t=z(e);if(t===void 0)return{assetCount:0,totalBytes:0};let r=0,n=0;for(const o of t)r+=1,n+=$(o);return{assetCount:r,totalBytes:n}}function m(e){return typeof e=="object"&&e!==null&&Array.isArray(e.output)}function z(e){if(Array.isArray(e)){const t=[];for(const r of e)m(r)&&t.push(...r.output);return t}if(m(e))return e.output}function $(e){if(typeof e!="object"||e===null)return 0;const t=e;if(t.type==="chunk"&&typeof t.code=="string")return Buffer.byteLength(t.code,"utf8");if(t.type==="asset"){const r=t.source;if(typeof r=="string")return Buffer.byteLength(r,"utf8");if(r instanceof Uint8Array)return r.byteLength}return 0}exports.UI_HTML_ENTRY=F;exports.UI_MAIN_ENTRY=V;exports.runHost=Y;
|
package/dist/host/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* 주의:
|
|
8
8
|
* - 이 파일은 Node.js 환경에서만 import되어야 한다.
|
|
9
|
-
* - `vite`, `@vitejs/plugin-react`, `@jogak/core/vite
|
|
9
|
+
* - `vite`, `@vitejs/plugin-react`, `@jogak/core/vite-plugin`은 모두 dynamic import로
|
|
10
10
|
* 로드한다 — `@jogak/ui` 메인 entry(브라우저 SPA)에서 우연히 host를 import
|
|
11
11
|
* 하더라도 vite가 브라우저 번들에 포함되지 않게 하기 위함.
|
|
12
12
|
*/
|
|
@@ -38,6 +38,43 @@ export interface JogakHostOptionsBase {
|
|
|
38
38
|
readonly extraPlugins?: readonly unknown[];
|
|
39
39
|
/** stdout/stderr 출력 stream (테스트 시 주입). */
|
|
40
40
|
readonly logger?: HostLogger;
|
|
41
|
+
/**
|
|
42
|
+
* 알파.7: 사용자 globalCss를 jogak SPA에 import한다 (algfa.6 옵션의 host 통로).
|
|
43
|
+
*
|
|
44
|
+
* `false`/`undefined` (default): 미주입.
|
|
45
|
+
* `true`: `<userRoot>/src/{...}.css` 자동 감지 후 첫 발견 1개 import.
|
|
46
|
+
* `string` / `readonly string[]`: 명시 경로.
|
|
47
|
+
*
|
|
48
|
+
* 본 옵션은 jogak() Vite plugin의 `globalCss` 옵션으로 그대로 전달된다.
|
|
49
|
+
*/
|
|
50
|
+
readonly globalCss?: boolean | string | readonly string[];
|
|
51
|
+
/**
|
|
52
|
+
* 알파.8: Preview 영역 격리 모드.
|
|
53
|
+
*
|
|
54
|
+
* `'iframe'` (default, 알파.8), `'shadow'` (deprecated), `'none'` (deprecated) 중 하나.
|
|
55
|
+
* jogak() Vite plugin의 `previewIsolation` 옵션으로 그대로 전달된다.
|
|
56
|
+
*
|
|
57
|
+
* 자세한 모드 설명은 `JogakPluginOptions.previewIsolation` JSDoc 참조.
|
|
58
|
+
*/
|
|
59
|
+
readonly previewIsolation?: 'none' | 'shadow' | 'iframe';
|
|
60
|
+
/**
|
|
61
|
+
* 알파.9: 어댑터 dev URL (예: `http://localhost:5174`).
|
|
62
|
+
* jogak SPA가 iframe `src` base로 사용한다.
|
|
63
|
+
*
|
|
64
|
+
* 미지정/빈 문자열 시 fallback (jogak SPA Vite scope의 preview-frame.tsx).
|
|
65
|
+
*
|
|
66
|
+
* jogak CLI의 어댑터 dispatch 결과 자동 전달 — 사용자가 직접 설정하지 않는다.
|
|
67
|
+
*/
|
|
68
|
+
readonly userPreviewUrl?: string;
|
|
69
|
+
/**
|
|
70
|
+
* 알파.9: iframe entry path (예: `/__jogak_preview__/index.html`).
|
|
71
|
+
* `BuilderAdapter.previewEntryMeta.devEntryPath` 값. CLI 자동 전달.
|
|
72
|
+
*/
|
|
73
|
+
readonly previewEntryPath?: string;
|
|
74
|
+
/**
|
|
75
|
+
* @deprecated 알파.10 제거 예정. `userPreviewUrl` 사용.
|
|
76
|
+
*/
|
|
77
|
+
readonly userViteUrl?: string;
|
|
41
78
|
}
|
|
42
79
|
export interface JogakDevOptions extends JogakHostOptionsBase {
|
|
43
80
|
readonly mode: 'dev';
|