콘텐츠로 이동

마이그레이션 가이드

ZNTC는 esbuild와 유사한 번들링 모델을 제공하지만 CLI flag surface는 아직 부분 집합입니다. 아래 표는 현재 zntc CLI에 실제로 노출된 옵션 기준입니다.

esbuildZNTC비고
esbuild src/index.ts --bundlezntc --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=externalbare 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=fooIIFE/UMD 전역 이름
--global:react=React--global:react=Reactexternal 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-effectsunused 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-onlyZNTC 는 전용 플래그. 비-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-annotationspure/sideEffects annotation 무시
--allow-overwrite--allow-overwrite기본은 입력=출력 차단, 명시 시에만 허용
--watch--watch 또는 -w동일
--serve--serve동일 (--port 지원)
// esbuild
import * 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,
});

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 옵션대안
--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는 개발 서버 + 프로덕션 번들러(Rollup/Rolldown)의 조합입니다. ZNTC는 단독 번들러이므로 Vite의 모든 기능을 대체하지는 않습니다.

Terminal window
# Vite
vite build
# ZNTC
zntc --bundle src/main.ts --outdir dist --format=esm --splitting --minify --sourcemap
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=ReactDOM

Rollup output.globals 는 ZNTC 에선 CLI --global:<specifier>=<global> 또는 defineConfig({ globals: { react: "React" } }) 로 매핑됩니다. IIFE/UMD 출력에서 external specifier 를 전역 변수로 치환할 때 사용합니다.

Vite/Rollup 플러그인의 resolveId/load/transform 훅은 vitePlugin() 래퍼로 감싸면 그대로 동작합니다. 반환값 키는 Rollup 규약대로 { id, code } 사용.

zntc.config.ts
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 기능ZNTC 대응
vite (dev server)zntc dev (HTML/env/public prepare + HMR/Fast Refresh + CSS-only HMR)
vite buildzntc build 또는 library build는 zntc --bundle <entry> --outdir dist --splitting --minify --sourcemap
vite previewzntc 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 RefreshHMR 내장 (React Refresh)
@vitejs/plugin-vue미지원 (자세히 + 대안)
@vitejs/plugin-legacy--target=es5 등으로 일부 대응
CSS Modules (.module.css)앱 모드에서 지원. default export와 가능한 named export 제공
CSS @importLightning CSS 내장 후처리 또는 --loader:.css=text
PostCSS (postcss.config.js)앱 모드에서 지원. zntc dev는 PostCSS dependency watch와 CSS-only HMR 지원
Sass/Less/StylusSass/SCSS는 앱 모드에서 지원. Less/Stylus는 미지원
public/ 정적 디렉토리앱 모드에서 지원 (--public-dir)
HTML 엔트리 (index.html)앱 모드에서 지원 (--entry-html)
SPA fallbackzntc preview --spa-fallback
resolve.alias (object)--alias:name=target 또는 defineConfig({ alias: { ... } })
resolve.alias (array, RegExp)defineConfig({ alias: [{ find: /^@\//, replacement: "./src/" }] }) (build()만, buildSync 미지원)
resolve.conditionsconditions: ["prod", "foo"] 또는 --conditions=prod,foo
optimizeDeps (pre-bundling)불필요 (번들 시 직접 처리)
ssr / SSR 빌드미지원
worker.formatnew Worker(new URL("./w.ts", import.meta.url)) 자동 감지 → 별도 IIFE 번들. Vite worker.format 설정 자체는 미지원
Rollup 플러그인 호환resolveId/load/transform 훅 호환

webpack은 설정이 복잡하지만 ZNTC는 대부분 CLI 옵션으로 해결됩니다.

webpack.config.js
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=text

webpack 로더 → 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-loaderSass/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 대응
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 내장
CssMinimizerPluginLightning CSS 플러그인에서 처리
CompressionPlugin (gzip/brotli)미지원. 후처리로 처리
webpack.ContextReplacementPlugin미지원
Module Federation미지원
DllPlugin / DllReferencePlugin미지원
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 으로 유사 정보