마이그레이션 가이드
esbuild에서 마이그레이션
섹션 제목: “esbuild에서 마이그레이션”ZNTC는 esbuild와 유사한 번들링 모델을 제공하지만 CLI flag surface는 아직 부분 집합입니다. 아래 표는 현재 zntc CLI에 실제로 노출된 옵션 기준입니다.
CLI 옵션 대응표
섹션 제목: “CLI 옵션 대응표”| esbuild | ZNTC | 비고 |
|---|---|---|
esbuild src/index.ts --bundle | zntc --bundle src/index.ts | 동일 |
--outfile=dist/out.js | -o dist/out.js | 축약 지원 |
--outdir=dist | --outdir dist | 동일 |
--outbase=src | --outbase=src | 동일 |
--format=esm | --format=esm | 동일 (esm/cjs/iife/umd/amd) |
--platform=node | --platform=node | 동일 (browser/node/neutral/react-native) |
--target=es2020 | --target=es2020 | 동일 (engine 타겟: chrome80, node20 등) |
--bundle | --bundle | 동일 |
--splitting | --splitting | 동일 (--outdir 필수) |
--packages=external | --packages=external | bare package import를 모두 external 처리 |
--external:react | --external react | : 대신 공백 |
--minify | --minify | 동일 (--minify-{whitespace,syntax,identifiers} 세분화 지원) |
--sourcemap | --sourcemap | 동일 |
(config only: sourceRoot) | --source-root=... | ZNTC 는 CLI 플래그로도 노출 |
--sources-content=false | --sources-content=false | 동일 |
--define:X=Y | --define:X=Y | 동일 |
--alias:react=preact/compat | --alias:react=preact/compat | 동일 |
--inject:./shim.js | --inject:./shim.js | 동일 |
--pure:Pure.* | --pure:Pure.* | pure call pattern 등록 |
--drop:console | --drop=console | : 대신 = (console/debugger) |
--drop-labels=DEV | --drop-labels=DEV | 동일. 쉼표로 여러 label 지정 가능 |
--keep-names | --keep-names | 동일 |
--banner:js=... | --banner:js=... | 동일 |
--footer:js=... | --footer:js=... | 동일 |
--intro=... | --intro=... | wrapper 내부 bundle 앞에 삽입 |
--outro=... | --outro=... | wrapper 내부 bundle 뒤에 삽입 |
--global-name=foo | --global-name=foo | IIFE/UMD 전역 이름 |
--global:react=React | --global:react=React | external specifier → IIFE/UMD global |
--public-path=/static/ | --public-path=/static/ | 동일 |
--out-extension:.js=.mjs | --out-extension:.js=.mjs | 동일 |
--entry-names=[name]-[hash] | --entry-names=[name]-[hash] | 동일 |
--chunk-names=chunks/[hash] | --chunk-names=chunks/[hash] | 동일 |
--asset-names=assets/[hash] | --asset-names=assets/[hash] | 동일 |
--loader:.css=text | --loader:.css=text | 동일 (text/file/dataurl/json/copy 등) |
--jsx=automatic | --jsx=automatic | 동일 (classic/automatic/automatic-dev) |
--jsx-dev | --jsx-dev | 동일 |
--jsx-factory=h | --jsx-factory=h | 동일 |
--jsx-fragment=Fragment | --jsx-fragment=Fragment | 동일 |
--jsx-import-source=preact | --jsx-import-source=preact | 동일 |
--jsx-side-effects | --jsx-side-effects | unused JSX expression 보존 |
--tsconfig=tsconfig.json | -p tsconfig.json 또는 --tsconfig-path=... | 축약 -p 지원 |
--tsconfig-raw='{...}' | --tsconfig-raw='{...}' | inline tsconfig JSON |
--conditions=prod,foo | --conditions=prod,foo | 기본 conditions 유지 + 사용자 condition 추가 |
--main-fields=browser,main | --main-fields=browser,main | 동일 |
--resolve-extensions=.ts,.js | --resolve-extensions=.ts,.js | 동일 (RN .ios.ts 등 지원) |
--preserve-symlinks | --preserve-symlinks | 동일 |
--node-paths=... | --node-paths=... | bare specifier 추가 탐색 경로 |
--charset=utf8 | --charset=utf8 | 동일 (UTF-8 보존) |
--charset=ascii | --ascii-only | ZNTC 는 전용 플래그. 비-ASCII를 \uXXXX 이스케이프 |
--legal-comments=eof | --legal-comments=eof | 동일 (none/inline/eof/linked/external) |
--metafile=meta.json | --metafile=meta.json | 동일 |
--analyze | --analyze | 동일 (현재 JSON, 트리 포맷 예정) |
--log-level=warning | --log-level=warning | 동일 (silent/error/warning/info/debug) |
--log-limit=10 | --log-limit=10 | 동일 |
--line-limit=80 | --line-limit=80 | 동일 (긴 출력 라인을 안전한 토큰 경계에서 줄바꿈) |
--ignore-annotations | --ignore-annotations | pure/sideEffects annotation 무시 |
--allow-overwrite | --allow-overwrite | 기본은 입력=출력 차단, 명시 시에만 허용 |
--watch | --watch 또는 -w | 동일 |
--serve | --serve | 동일 (--port 지원) |
esbuild Build API 마이그레이션
섹션 제목: “esbuild Build API 마이그레이션”// esbuildimport * as esbuild from 'esbuild';await esbuild.build({ entryPoints: ['src/index.ts'], bundle: true, outdir: 'dist', format: 'esm', minify: true,});
// ZNTC — 거의 동일import { build } from '@zntc/core';await build({ entryPoints: ['src/index.ts'], bundle: true, outdir: 'dist', format: 'esm', minify: true,});esbuild 플러그인 마이그레이션
섹션 제목: “esbuild 플러그인 마이그레이션”ZNTC 네이티브 플러그인은 esbuild 스타일 setup(build) 구조를 그대로 사용합니다. 반환값 키 이름(path/contents)도 동일합니다.
// esbuild 플러그인const myPlugin = { name: 'my-plugin', setup(build) { build.onResolve({ filter: /^virtual:/ }, (args) => ({ path: args.path, namespace: 'virtual', })); build.onLoad({ filter: /.*/, namespace: 'virtual' }, (args) => ({ contents: 'export default 42', loader: 'js', })); },};
// ZNTC 플러그인 — esbuild 스타일 동일 (namespace 대신 path prefix로 구분)import type { ZntcPlugin } from '@zntc/core';
const myPlugin: ZntcPlugin = { name: 'my-plugin', setup(build) { build.onResolve({ filter: /^virtual:/ }, (args) => ({ path: '\0' + args.path, })); build.onLoad({ filter: /^\0virtual:/ }, (args) => ({ contents: 'export default 42', })); },};Rollup/Vite 스타일 플러그인(resolveId/load/transform)을 그대로 쓰고 싶다면 vitePlugin() 래퍼로 감쌉니다.
import { vitePlugin } from '@zntc/core';
export default defineConfig({ plugins: [ vitePlugin({ name: 'virtual-loader', resolveId(source) { if (source.startsWith('virtual:')) return '\0' + source; return null; }, load(id) { if (id.startsWith('\0virtual:')) return { code: 'export default 42' }; return null; }, }), ],});지원하지 않는 esbuild 옵션
섹션 제목: “지원하지 않는 esbuild 옵션”| esbuild 옵션 | 대안 |
|---|---|
--mangle-props=<regex> | 미지원 (mangle 자체는 --minify-identifiers로 내부 식별자만) |
--mangle-cache=<path> | 미지원 |
--mangle-quoted | 미지원 |
--analyze (tree 포맷) | --analyze JSON + /analyze/ 시각화. CLI tree 포맷은 예정 |
--servedir=<path> | --serve <dir> (위치 인자) |
--bundle=false (기본 off) | 기본 동작 동일. ZNTC도 --bundle 없으면 트랜스파일만 |
--splitting=false | 기본 off. 플래그 없는 상태가 기본 |
--tree-shaking=false | 미지원. 개별 --external로 번들 포함 범위를 줄일 수 있음 |
--color=true|false | 미지원. 터미널 자동 감지 |
--log-override:X=Y | 미지원. --log-level만 |
--supported:bigint=false | 미지원. --target으로 일괄 제어 |
--reserve-props=<regex> | 미지원 |
Vite에서 마이그레이션
섹션 제목: “Vite에서 마이그레이션”Vite는 개발 서버 + 프로덕션 번들러(Rollup/Rolldown)의 조합입니다. ZNTC는 단독 번들러이므로 Vite의 모든 기능을 대체하지는 않습니다.
Vite 프로덕션 빌드 대체
섹션 제목: “Vite 프로덕션 빌드 대체”# Vitevite build
# ZNTCzntc --bundle src/main.ts --outdir dist --format=esm --splitting --minify --sourcemapvite.config.ts 대응
섹션 제목: “vite.config.ts 대응”export default defineConfig({ build: { outDir: 'dist', minify: true, sourcemap: true, rollupOptions: { external: ['react', 'react-dom'], output: { globals: { react: 'React', 'react-dom': 'ReactDOM' }, }, }, },});
// zntc CLI 대응// zntc --bundle src/main.ts --outdir dist --minify --sourcemap --external react --external react-dom \// --global:react=React --global:react-dom=ReactDOMRollup output.globals 는 ZNTC 에선 CLI --global:<specifier>=<global> 또는 defineConfig({ globals: { react: "React" } }) 로 매핑됩니다. IIFE/UMD 출력에서 external specifier 를 전역 변수로 치환할 때 사용합니다.
Vite 플러그인 → ZNTC 플러그인
섹션 제목: “Vite 플러그인 → ZNTC 플러그인”Vite/Rollup 플러그인의 resolveId/load/transform 훅은 vitePlugin() 래퍼로 감싸면 그대로 동작합니다. 반환값 키는 Rollup 규약대로 { id, code } 사용.
import { defineConfig, vitePlugin } from '@zntc/core';import fs from 'node:fs';
export default defineConfig({ plugins: [ vitePlugin({ name: 'svg-loader', load(id) { if (id.endsWith('.svg')) { const svg = fs.readFileSync(id, 'utf8'); return { code: `export default ${JSON.stringify(svg)}` }; } return null; }, }), ],});네이티브 스타일로 직접 쓰고 싶다면 setup(build) { build.onLoad(...) } 구조를 사용하세요.
Vite 기능 대응표
섹션 제목: “Vite 기능 대응표”| Vite 기능 | ZNTC 대응 |
|---|---|
vite (dev server) | zntc dev (HTML/env/public prepare + HMR/Fast Refresh + CSS-only HMR) |
vite build | zntc build 또는 library build는 zntc --bundle <entry> --outdir dist --splitting --minify --sourcemap |
vite preview | zntc preview dist |
import.meta.env.MODE | 앱 모드는 .env* 자동 로드, CLI 번들은 --define:import.meta.env.MODE=\"production\" |
import.meta.env.DEV | 앱 모드는 dev/build mode로 자동 주입, CLI 번들은 --define:import.meta.env.DEV=true |
.env / .env.production 자동 로드 | 앱 모드에서 지원 (--env-dir, --env-prefix) |
import.meta.glob | 지원 (Vite 호환 eager / import 옵션) |
import.meta.hot | 지원 (--serve --bundle) |
import.meta.url | 지원 (ESM 표준) |
@vitejs/plugin-react | --jsx=automatic (자동 런타임 내장) |
@vitejs/plugin-react Fast Refresh | HMR 내장 (React Refresh) |
@vitejs/plugin-vue | 미지원 (자세히 + 대안) |
@vitejs/plugin-legacy | --target=es5 등으로 일부 대응 |
CSS Modules (.module.css) | 앱 모드에서 지원. default export와 가능한 named export 제공 |
CSS @import | Lightning CSS 내장 후처리 또는 --loader:.css=text |
PostCSS (postcss.config.js) | 앱 모드에서 지원. zntc dev는 PostCSS dependency watch와 CSS-only HMR 지원 |
| Sass/Less/Stylus | Sass/SCSS는 앱 모드에서 지원. Less/Stylus는 미지원 |
public/ 정적 디렉토리 | 앱 모드에서 지원 (--public-dir) |
HTML 엔트리 (index.html) | 앱 모드에서 지원 (--entry-html) |
| SPA fallback | zntc preview --spa-fallback |
resolve.alias (object) | --alias:name=target 또는 defineConfig({ alias: { ... } }) |
resolve.alias (array, RegExp) | defineConfig({ alias: [{ find: /^@\//, replacement: "./src/" }] }) (build()만, buildSync 미지원) |
resolve.conditions | conditions: ["prod", "foo"] 또는 --conditions=prod,foo |
optimizeDeps (pre-bundling) | 불필요 (번들 시 직접 처리) |
ssr / SSR 빌드 | 미지원 |
worker.format | new Worker(new URL("./w.ts", import.meta.url)) 자동 감지 → 별도 IIFE 번들. Vite worker.format 설정 자체는 미지원 |
| Rollup 플러그인 호환 | resolveId/load/transform 훅 호환 |
webpack에서 마이그레이션
섹션 제목: “webpack에서 마이그레이션”webpack은 설정이 복잡하지만 ZNTC는 대부분 CLI 옵션으로 해결됩니다.
webpack.config.js → ZNTC CLI
섹션 제목: “webpack.config.js → ZNTC CLI”module.exports = { entry: './src/index.ts', output: { path: 'dist', filename: 'bundle.js' }, resolve: { extensions: ['.ts', '.tsx', '.js'] }, module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader' }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.svg$/, type: 'asset/resource' }, ], }, optimization: { minimize: true },};
// ZNTC 대응// zntc --bundle src/index.ts -o dist/bundle.js --minify --loader:.svg=file --loader:.css=textwebpack 로더 → ZNTC 로더/플러그인
섹션 제목: “webpack 로더 → ZNTC 로더/플러그인”| webpack 로더 | ZNTC 대응 |
|---|---|
ts-loader / babel-loader | 불필요. ZNTC가 TS/JSX 직접 처리 |
@swc/swc-loader / esbuild-loader | 불필요. ZNTC가 대체 |
css-loader + style-loader | --loader:.css=text 또는 내장 Lightning CSS 후처리 |
file-loader / asset/resource | --loader:.png=file |
url-loader / asset/inline | --loader:.png=dataurl |
raw-loader / asset/source | --loader:.txt=text |
svg-loader / @svgr/webpack | --loader:.svg=text/file/dataurl 또는 플러그인 |
json-loader | --loader:.json=json (기본 내장) |
sass-loader / less-loader / stylus-loader | Sass/SCSS는 앱 모드에서 지원. Less/Stylus는 사전 컴파일 필요 |
postcss-loader | 앱 모드에서 PostCSS 지원. library bundling은 plugin 또는 사전 처리 |
html-loader | 앱 모드는 index.html rewrite 지원. 문자열 import는 --loader:.html=text |
worker-loader | 불필요. new Worker(new URL("./w.ts", import.meta.url)) 자동 감지 + IIFE 번들 내장 |
thread-loader | 불필요. ZNTC 병렬 파이프라인 내장 (--jobs=N) |
cache-loader | 불필요. .zig-cache / 모듈 레벨 캐시 |
webpack 플러그인 → ZNTC 대응
섹션 제목: “webpack 플러그인 → ZNTC 대응”| webpack 플러그인 | ZNTC 대응 |
|---|---|
DefinePlugin | --define:KEY=VALUE |
ProvidePlugin | --inject:./shim.js |
IgnorePlugin | --external <pkg> 또는 --block-list=<pattern> |
resolve.fallback: { fs: false, crypto: 'crypto-browserify' } | fallback: { fs: false, crypto: 'crypto-browserify' } (해석 실패 시에만 적용) |
BannerPlugin | --banner:js=... |
SplitChunksPlugin | --splitting (자동) |
MiniCssExtractPlugin | 내장 Lightning CSS 후처리 (별도 CSS 청크 출력) |
HtmlWebpackPlugin | 앱 모드 index.html + %ENV%/asset rewrite로 대응 |
CopyWebpackPlugin | 미지원. --loader:.svg=copy 등으로 에셋 단위 복사 |
TerserPlugin | --minify 내장 |
CssMinimizerPlugin | Lightning CSS 플러그인에서 처리 |
CompressionPlugin (gzip/brotli) | 미지원. 후처리로 처리 |
webpack.ContextReplacementPlugin | 미지원 |
| Module Federation | 미지원 |
| DllPlugin / DllReferencePlugin | 미지원 |
미지원 webpack 기능
섹션 제목: “미지원 webpack 기능”| webpack 기능 | 대안 |
|---|---|
require.context | 지원 (require.context(dir, deep, regex) — 플러그인의 onResolveContext 훅으로 매칭) |
Lazy chunk (import(/* webpackChunkName: "x" */ ...)) | 동적 import 자체는 지원. 매직 코멘트는 미지원 |
webpack.config.js 함수형/멀티 컨피그 | 미지원. zntc.config.ts 단일 export |
devServer.proxy | 지원 (--proxy /api=http://localhost:3000) |
| Dev server overlay | 지원 (build/runtime error overlay + source map remap) |
Persistent cache (cache.type: 'filesystem') | 불필요. 내장 캐시 사용 |
| Stats JSON | --metafile=meta.json 으로 유사 정보 |