@zntc/rspack-loader 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ohah
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # @zntc/rspack-loader
2
+
3
+ Rspack / Webpack 5 의 `swc-loader` / `esbuild-loader` / `babel-loader` 자리를 ZNTC (Zig 기반 트랜스파일러) 로 교체하는 loader. TypeScript / JSX / Flow / decorators 변환을 ZNTC 가 담당.
4
+
5
+ ## 설치
6
+
7
+ ```bash
8
+ bun add -D @zntc/rspack-loader @zntc/core
9
+ # 또는
10
+ npm i -D @zntc/rspack-loader @zntc/core
11
+ ```
12
+
13
+ `@zntc/core` 가 dependency 로 함께 따라옴 (NAPI binary 포함).
14
+
15
+ ## 사용 — Rspack
16
+
17
+ ```js
18
+ // rspack.config.mjs
19
+ export default {
20
+ module: {
21
+ rules: [
22
+ {
23
+ test: /\.(?:tsx?|jsx?)$/,
24
+ exclude: /node_modules/,
25
+ loader: '@zntc/rspack-loader',
26
+ options: {
27
+ transpileOptions: { target: 'es2020', jsx: 'automatic' },
28
+ },
29
+ },
30
+ ],
31
+ },
32
+ };
33
+ ```
34
+
35
+ `builtin:swc-loader` 를 쓰던 자리에 그대로 대체 가능.
36
+
37
+ ## 사용 — Webpack 5
38
+
39
+ ```js
40
+ // webpack.config.mjs
41
+ export default {
42
+ module: {
43
+ rules: [
44
+ {
45
+ test: /\.(?:tsx?|jsx?)$/,
46
+ exclude: /node_modules/,
47
+ use: {
48
+ loader: '@zntc/rspack-loader',
49
+ options: {
50
+ transpileOptions: { target: 'es2020', jsx: 'automatic' },
51
+ },
52
+ },
53
+ },
54
+ ],
55
+ },
56
+ };
57
+ ```
58
+
59
+ loader API 가 webpack/rspack 공통이라 동일 코드로 양쪽 동작.
60
+
61
+ ## 옵션
62
+
63
+ ```ts
64
+ interface ZntcLoaderOptions {
65
+ transpileOptions?: Omit<TranspileOptions, 'filename'>;
66
+ tsconfigCache?: boolean;
67
+ }
68
+ ```
69
+
70
+ ### `tsconfigCache` (default: `true`)
71
+
72
+ tsconfig autodiscover walk 결과를 worker 별로 캐시. dev/watch 세션에서 같은 워크스페이스 안 파일은 한 번만 walk → file 당 5–10 fs syscall 절약. `transpileOptions.tsconfigPath` / `tsconfigRaw` 명시 시 자동 무시.
73
+
74
+ ### `transpileOptions`
75
+
76
+ `@zntc/core` 의 `TranspileOptions` 와 동일 (`filename` 만 loader 가 `this.resourcePath` 로 자동 채움).
77
+
78
+ #### Target / 모듈
79
+
80
+ | 옵션 | 타입 | 설명 |
81
+ | -------------- | ---------------------------------------------------- | ---------------------------------------------- |
82
+ | `target` | `'es5' \| 'es2015' \| ... \| 'es2024' \| 'esnext'` | ES 다운레벨 타겟 |
83
+ | `browserslist` | `string \| string[]` | browserslist 쿼리 (지정 시 `target` 보다 우선) |
84
+ | `platform` | `'browser' \| 'node' \| 'neutral' \| 'react-native'` | 타겟 플랫폼 |
85
+ | `format` | `'esm' \| 'cjs'` | 모듈 포맷 |
86
+
87
+ #### JSX
88
+
89
+ | 옵션 | 타입 | 설명 |
90
+ | ----------------- | --------------------------------------------- | ----------------------------------------------- |
91
+ | `jsx` | `'classic' \| 'automatic' \| 'automatic-dev'` | JSX 런타임 |
92
+ | `jsxFactory` | `string` | classic factory (default `React.createElement`) |
93
+ | `jsxFragment` | `string` | classic Fragment (default `React.Fragment`) |
94
+ | `jsxImportSource` | `string` | automatic import source (default `react`) |
95
+ | `jsxInJs` | `boolean` | `.js` 에서도 JSX 허용 |
96
+
97
+ #### TypeScript / Flow / Decorator
98
+
99
+ | 옵션 | 타입 | 설명 |
100
+ | ------------------------- | --------- | ------------------------------------------------------------------ |
101
+ | `tsconfigPath` | `string` | tsconfig.json 경로 (파일 또는 디렉토리). compilerOptions 자동 머지 |
102
+ | `tsconfigRaw` | `string` | inline tsconfig JSON 문자열 (esbuild 와 동일 의미) |
103
+ | `verbatimModuleSyntax` | `boolean` | TS 5.0+: 미사용 import elide 안 함 |
104
+ | `useDefineForClassFields` | `boolean` | class field → constructor `this.x = v` 변환 (default: `true`) |
105
+ | `flow` | `boolean` | Flow 타입 스트리핑 |
106
+ | `experimentalDecorators` | `boolean` | legacy decorator 변환 |
107
+ | `emitDecoratorMetadata` | `boolean` | decorator metadata emit |
108
+
109
+ #### 소스맵
110
+
111
+ | 옵션 | 타입 | 설명 |
112
+ | ------------------- | --------- | -------------------------------- |
113
+ | `sourcemap` | `boolean` | 소스맵 생성 |
114
+ | `sourcemapDebugIds` | `boolean` | Sentry 호환 Debug ID |
115
+ | `sourcesContent` | `boolean` | 원본 소스 포함 (default: `true`) |
116
+ | `sourceRoot` | `string` | 소스맵 sourceRoot 필드 |
117
+
118
+ #### Minify
119
+
120
+ | 옵션 | 타입 | 설명 |
121
+ | ------------------- | --------- | -------------------------------------- |
122
+ | `minify` | `boolean` | whitespace + identifiers + syntax 전체 |
123
+ | `minifyWhitespace` | `boolean` | 공백 축소만 |
124
+ | `minifyIdentifiers` | `boolean` | 식별자 축소만 |
125
+ | `minifySyntax` | `boolean` | 구문 축소만 |
126
+ | `dropConsole` | `boolean` | `console.*` 호출 제거 |
127
+ | `dropDebugger` | `boolean` | `debugger` 문 제거 |
128
+
129
+ #### 기타
130
+
131
+ | 옵션 | 타입 | 설명 |
132
+ | ------------- | ------------------------------------------------------------- | -------------------------------------- |
133
+ | `define` | `Array<{ key: string; value: string }>` | 식별자 치환 (`value` 는 raw JSON) |
134
+ | `quotes` | `'double' \| 'single' \| 'preserve'` | 문자열 따옴표 스타일 |
135
+ | `asciiOnly` | `boolean` | non-ASCII → `\uXXXX` 이스케이프 |
136
+ | `charsetUtf8` | `boolean` | non-ASCII 이스케이프 안 함 |
137
+ | `stopAfter` | `'scan' \| 'parse' \| 'semantic' \| 'transform' \| 'codegen'` | 디버그/프로파일 — 해당 phase 이후 skip |
138
+
139
+ 전체 옵션 정의는 [`@zntc/core` TranspileOptions](https://github.com/ohah/zntc/blob/main/packages/shared/index.ts) 참고.
140
+
141
+ ## 예시 — `define` 으로 환경변수 치환
142
+
143
+ ```js
144
+ {
145
+ loader: '@zntc/rspack-loader',
146
+ options: {
147
+ transpileOptions: {
148
+ define: [
149
+ { key: 'process.env.NODE_ENV', value: '"production"' },
150
+ { key: '__DEV__', value: 'false' },
151
+ ],
152
+ },
153
+ },
154
+ }
155
+ ```
156
+
157
+ ## 예시 — Flow 코드
158
+
159
+ ```js
160
+ {
161
+ test: /\.js$/,
162
+ loader: '@zntc/rspack-loader',
163
+ options: { transpileOptions: { flow: true, jsx: 'automatic' } },
164
+ }
165
+ ```
166
+
167
+ ## 예시 — tsconfig 명시 + decorator
168
+
169
+ ```js
170
+ {
171
+ loader: '@zntc/rspack-loader',
172
+ options: {
173
+ transpileOptions: {
174
+ tsconfigPath: './tsconfig.json',
175
+ experimentalDecorators: true,
176
+ emitDecoratorMetadata: true,
177
+ },
178
+ },
179
+ }
180
+ ```
181
+
182
+ ## peer
183
+
184
+ - `@rspack/core >= 1.0.0` (optional, rspack 1.x / 2.x 모두 지원)
185
+ - `webpack >= 5.0.0` (optional)
186
+
187
+ 둘 중 하나만 설치돼있어도 됨.
188
+
189
+ ## 라이센스
190
+
191
+ MIT.
package/dist/index.cjs ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ //#region index.ts
3
+ var TsconfigCache = require("@zntc/core").TsconfigCache;
4
+ var init = require("@zntc/core").init;
5
+ var transpile = require("@zntc/core").transpile;
6
+ let initialized = false,cache;
7
+ function ensureInit(useCache) {
8
+ if (!initialized) {
9
+ init();
10
+ initialized = true;
11
+ }
12
+ if (useCache && !cache) {
13
+ cache = new TsconfigCache();
14
+ }
15
+ }
16
+ function zntcLoader(source) {
17
+ const callback = this.async(),options = (this.getOptions() ?? {}),transpileOpts = options.transpileOptions ?? {},useCache = options.tsconfigCache ?? true;
18
+ try {
19
+ ensureInit(useCache);
20
+ const result = transpile(source, { ...transpileOpts, filename: this.resourcePath, cache: useCache ? cache : undefined });
21
+ callback(null, result.code, result.map ? JSON.parse(result.map) : undefined);
22
+ } catch (err) {
23
+ callback(err instanceof Error ? err : new Error(String(err)));
24
+ }
25
+ }
26
+ module.exports = zntcLoader;
27
+ //#endregion
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @zntc/rspack-loader — Rspack/Webpack loader that runs source through ZNTC
3
+ * (TS/JSX/Flow → JS) instead of swc-loader / esbuild-loader / babel-loader.
4
+ *
5
+ * @example
6
+ * ```js
7
+ * // rspack.config.mjs
8
+ * export default {
9
+ * module: {
10
+ * rules: [
11
+ * {
12
+ * test: /\.(?:tsx?|jsx?)$/,
13
+ * exclude: /node_modules/,
14
+ * loader: "@zntc/rspack-loader",
15
+ * options: {
16
+ * transpileOptions: { target: "es2020", jsx: "automatic" },
17
+ * },
18
+ * },
19
+ * ],
20
+ * },
21
+ * };
22
+ * ```
23
+ */
24
+ import type { TranspileOptions } from '@zntc/core';
25
+ /**
26
+ * webpack/rspack loader 의 최소 contract — 두 번들러가 공유하는 surface 만
27
+ * 정의해 사용자가 webpack 또는 @rspack/core 한쪽만 설치해도 타입이 깨지지
28
+ * 않도록 함 (esbuild-loader 와 동일 패턴).
29
+ */
30
+ interface LoaderContext {
31
+ resourcePath: string;
32
+ async(): (err: Error | null, content?: string, sourceMap?: object | string) => void;
33
+ getOptions(): unknown;
34
+ }
35
+ export interface ZntcLoaderOptions {
36
+ /**
37
+ * ZNTC transpile 옵션 (target, jsx 등). `filename` 은 loader 가 자동으로
38
+ * `this.resourcePath` 에서 채워주므로 지정하지 않아도 됨.
39
+ */
40
+ transpileOptions?: Omit<TranspileOptions, 'filename'>;
41
+ /**
42
+ * tsconfig autodiscover walk 결과 캐시 (기본: true). Rspack/Webpack 의 watch
43
+ * 세션 동안 같은 워크스페이스 안 파일은 한 번만 walk → file 당 5–10 fs
44
+ * syscall 절약 (#2367). `transpileOptions.tsconfigPath` / `tsconfigRaw`
45
+ * 명시 시 캐시는 자동으로 무시됨.
46
+ */
47
+ tsconfigCache?: boolean;
48
+ }
49
+ export default function zntcLoader(this: LoaderContext, source: string): void;
50
+ export {};
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @zntc/rspack-loader — Rspack/Webpack loader that runs source through ZNTC
3
+ * (TS/JSX/Flow → JS) instead of swc-loader / esbuild-loader / babel-loader.
4
+ *
5
+ * @example
6
+ * ```js
7
+ * // rspack.config.mjs
8
+ * export default {
9
+ * module: {
10
+ * rules: [
11
+ * {
12
+ * test: /\.(?:tsx?|jsx?)$/,
13
+ * exclude: /node_modules/,
14
+ * loader: "@zntc/rspack-loader",
15
+ * options: {
16
+ * transpileOptions: { target: "es2020", jsx: "automatic" },
17
+ * },
18
+ * },
19
+ * ],
20
+ * },
21
+ * };
22
+ * ```
23
+ */
24
+ import type { TranspileOptions } from '@zntc/core';
25
+ /**
26
+ * webpack/rspack loader 의 최소 contract — 두 번들러가 공유하는 surface 만
27
+ * 정의해 사용자가 webpack 또는 @rspack/core 한쪽만 설치해도 타입이 깨지지
28
+ * 않도록 함 (esbuild-loader 와 동일 패턴).
29
+ */
30
+ interface LoaderContext {
31
+ resourcePath: string;
32
+ async(): (err: Error | null, content?: string, sourceMap?: object | string) => void;
33
+ getOptions(): unknown;
34
+ }
35
+ export interface ZntcLoaderOptions {
36
+ /**
37
+ * ZNTC transpile 옵션 (target, jsx 등). `filename` 은 loader 가 자동으로
38
+ * `this.resourcePath` 에서 채워주므로 지정하지 않아도 됨.
39
+ */
40
+ transpileOptions?: Omit<TranspileOptions, 'filename'>;
41
+ /**
42
+ * tsconfig autodiscover walk 결과 캐시 (기본: true). Rspack/Webpack 의 watch
43
+ * 세션 동안 같은 워크스페이스 안 파일은 한 번만 walk → file 당 5–10 fs
44
+ * syscall 절약 (#2367). `transpileOptions.tsconfigPath` / `tsconfigRaw`
45
+ * 명시 시 캐시는 자동으로 무시됨.
46
+ */
47
+ tsconfigCache?: boolean;
48
+ }
49
+ export default function zntcLoader(this: LoaderContext, source: string): void;
50
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ import { TsconfigCache, init, transpile } from "@zntc/core";
2
+ //#region index.ts
3
+ let initialized = false,cache;
4
+ function ensureInit(useCache) {
5
+ if (!initialized) {
6
+ init();
7
+ initialized = true;
8
+ }
9
+ if (useCache && !cache) {
10
+ cache = new TsconfigCache();
11
+ }
12
+ }
13
+ function zntcLoader(source) {
14
+ const callback = this.async(),options = (this.getOptions() ?? {}),transpileOpts = options.transpileOptions ?? {},useCache = options.tsconfigCache ?? true;
15
+ try {
16
+ ensureInit(useCache);
17
+ const result = transpile(source, { ...transpileOpts, filename: this.resourcePath, cache: useCache ? cache : undefined });
18
+ callback(null, result.code, result.map ? JSON.parse(result.map) : undefined);
19
+ } catch (err) {
20
+ callback(err instanceof Error ? err : new Error(String(err)));
21
+ }
22
+ }
23
+ export { zntcLoader as default };
24
+ //#endregion
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@zntc/rspack-loader",
3
+ "version": "0.1.0",
4
+ "description": "Use ZNTC as the TypeScript/JSX/Flow transformer in Rspack and Webpack (drop-in alternative to swc-loader / esbuild-loader / babel-loader)",
5
+ "keywords": [
6
+ "babel-loader",
7
+ "esbuild-loader",
8
+ "flow",
9
+ "jsx",
10
+ "rspack",
11
+ "rspack-loader",
12
+ "swc-loader",
13
+ "transpiler",
14
+ "typescript",
15
+ "webpack",
16
+ "webpack-loader",
17
+ "zntc"
18
+ ],
19
+ "homepage": "https://ohah.github.io/zntc",
20
+ "bugs": {
21
+ "url": "https://github.com/ohah/zntc/issues"
22
+ },
23
+ "license": "MIT",
24
+ "author": "ohah",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/ohah/zntc.git",
28
+ "directory": "packages/rspack-loader"
29
+ },
30
+ "source": "./src/index.ts",
31
+ "files": [
32
+ "dist/",
33
+ "README.md"
34
+ ],
35
+ "type": "module",
36
+ "main": "./dist/index.cjs",
37
+ "module": "./dist/index.js",
38
+ "types": "./dist/index.d.ts",
39
+ "exports": {
40
+ ".": {
41
+ "source": "./src/index.ts",
42
+ "import": {
43
+ "types": "./dist/index.d.ts",
44
+ "default": "./dist/index.js"
45
+ },
46
+ "require": {
47
+ "types": "./dist/index.d.cts",
48
+ "default": "./dist/index.cjs"
49
+ }
50
+ }
51
+ },
52
+ "scripts": {
53
+ "build:bundle": "node ../core/bin/zntc.mjs --bundle src/index.ts --outfile dist/index.js --format=esm --target=node --conditions=source --external @zntc/core && node ../core/bin/zntc.mjs --bundle src/index.ts --outfile dist/index.cjs --format=cjs --target=node --conditions=source --external @zntc/core",
54
+ "build:dts": "bun x tsc -b && cp dist/index.d.ts dist/index.d.cts",
55
+ "build": "bun run build:bundle && bun run build:dts",
56
+ "test": "bun test",
57
+ "prepublishOnly": "bun run build && bunx publint --strict --level error ."
58
+ },
59
+ "dependencies": {
60
+ "@zntc/core": "workspace:*"
61
+ },
62
+ "devDependencies": {
63
+ "@rspack/core": "^2.0.1",
64
+ "@types/node": "^25.5.2",
65
+ "webpack": "^5.94.0"
66
+ },
67
+ "peerDependencies": {
68
+ "@rspack/core": ">=1.0.0",
69
+ "webpack": ">=5.0.0"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "@rspack/core": {
73
+ "optional": true
74
+ },
75
+ "webpack": {
76
+ "optional": true
77
+ }
78
+ },
79
+ "engines": {
80
+ "node": ">=24.0.0"
81
+ }
82
+ }