@fluojs/vite 1.0.4 → 1.0.6

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/README.ko.md CHANGED
@@ -9,6 +9,7 @@ fluo 프로젝트를 위한 Vite 플러그인과 빌드 유틸리티입니다.
9
9
  - [설치](#설치)
10
10
  - [사용 시점](#사용-시점)
11
11
  - [빠른 시작](#빠른-시작)
12
+ - [데코레이터 변환 경계](#데코레이터-변환-경계)
12
13
  - [공개 API](#공개-api)
13
14
  - [관련 패키지](#관련-패키지)
14
15
  - [예제 소스](#예제-소스)
@@ -19,7 +20,7 @@ fluo 프로젝트를 위한 Vite 플러그인과 빌드 유틸리티입니다.
19
20
  npm install --save-dev @fluojs/vite vite @babel/core @babel/plugin-proposal-decorators @babel/preset-typescript
20
21
  ```
21
22
 
22
- `@babel/core` `>=7.26.0`, `@babel/plugin-proposal-decorators` `>=7.28.0`, `@babel/preset-typescript` `>=7.27.0`, `vite` `>=6.2.0`은 peer dependency입니다. `fluoDecoratorsPlugin()`이 Vite transform 시점에 Babel decorator plugin과 TypeScript preset을 해석하기 때문입니다.
23
+ `@babel/core` `>=7.26.0`, `@babel/plugin-proposal-decorators` `>=7.28.0`, `@babel/preset-typescript` `>=7.27.0`, `vite` `>=6.2.0`은 peer dependency입니다. `fluoDecoratorsPlugin()`이 Vite transform 시점에 Babel 로드하고 Babel decorator plugin과 TypeScript preset을 해석하며, 누락된 peer dependency를 Vite `transform` hook의 진단으로 보고하기 때문입니다.
23
24
 
24
25
  ## 사용 시점
25
26
 
@@ -42,7 +43,17 @@ export default defineConfig({
42
43
  });
43
44
  ```
44
45
 
45
- 이 플러그인은 `.ts` 애플리케이션 파일을 Babel로 변환하며 `2023-11` decorators proposal과 `@babel/preset-typescript`를 사용합니다. 파일 경계를 판단하기 전에 Vite query suffix를 제거한 뒤 declaration 파일, `*.test.ts` 또는 `*.spec.ts` 파일, `node_modules`, `.ts`가 아닌 파일은 건너뛰므로 생성된 Vitest 테스트 파일은 계속 전용 `@fluojs/testing/vitest` transform 경로를 사용합니다.
46
+ 이 플러그인은 `.ts` 애플리케이션 파일을 Babel로 변환하며 `2023-11` decorators proposal과 `@babel/preset-typescript`를 사용합니다. 파일 경계를 판단하기 전에 Vite query suffix를 제거한 뒤 declaration 파일, `*.test.ts` 또는 `*.spec.ts` 파일, `node_modules`, `.ts`가 아닌 파일은 건너뛰므로 생성된 Vitest 테스트 파일은 계속 전용 `@fluojs/testing/vitest` transform 경로를 사용합니다. `@fluojs/vite`를 import하거나 `fluoDecoratorsPlugin()`을 생성하는 시점에는 `@babel/core`를 로드하지 않으며, 누락된 Babel peer는 Vite가 변환 중인 소스 파일에 대한 transform-time 진단으로 표시됩니다.
47
+
48
+ ## 데코레이터 변환 경계
49
+
50
+ `@fluojs/vite`는 Vitest 테스트 변환이 아니라 애플리케이션 빌드 변환을 소유합니다. 생성된 non-Deno starter는 파일 경계 분리를 명시적으로 유지합니다:
51
+
52
+ 1. `vite.config.ts`는 `@fluojs/vite`에서 `fluoDecoratorsPlugin()`을 import합니다.
53
+ 2. Vite 플러그인은 query suffix를 제거하고 애플리케이션 `.ts` 파일만 허용하며, 첫 eligible transform 시점에 Babel을 lazy load한 뒤 `@babel/plugin-proposal-decorators`의 `{ version: '2023-11' }` 설정과 `@babel/preset-typescript`를 실행합니다.
54
+ 3. `vitest.config.ts`는 `@fluojs/testing/vitest`에서 `fluoBabelDecoratorsPlugin()`을 import하므로 `*.test.ts`와 `*.spec.ts` 파일은 testing-specific transform 경로에 남습니다.
55
+
56
+ 생성 프로젝트를 커스터마이즈할 때도 이 경계를 분리하세요. `experimentalDecorators`를 다시 활성화하거나, direct esbuild decorator handling에 의존하거나, 테스트 파일을 Vite 애플리케이션 transform으로 보내는 방식은 문서화된 fluo 지원 계약 밖에 있습니다.
46
57
 
47
58
  ## 공개 API
48
59
 
package/README.md CHANGED
@@ -9,6 +9,7 @@ Vite plugin and build utilities for fluo projects.
9
9
  - [Installation](#installation)
10
10
  - [When to Use](#when-to-use)
11
11
  - [Quick Start](#quick-start)
12
+ - [Decorator Transform Boundary](#decorator-transform-boundary)
12
13
  - [Public API](#public-api)
13
14
  - [Related Packages](#related-packages)
14
15
  - [Example Sources](#example-sources)
@@ -19,7 +20,7 @@ Vite plugin and build utilities for fluo projects.
19
20
  npm install --save-dev @fluojs/vite vite @babel/core @babel/plugin-proposal-decorators @babel/preset-typescript
20
21
  ```
21
22
 
22
- `@babel/core` `>=7.26.0`, `@babel/plugin-proposal-decorators` `>=7.28.0`, `@babel/preset-typescript` `>=7.27.0`, and `vite` `>=6.2.0` are peer dependencies because `fluoDecoratorsPlugin()` resolves the Babel decorator plugin and TypeScript preset when Vite transforms source files.
23
+ `@babel/core` `>=7.26.0`, `@babel/plugin-proposal-decorators` `>=7.28.0`, `@babel/preset-typescript` `>=7.27.0`, and `vite` `>=6.2.0` are peer dependencies because `fluoDecoratorsPlugin()` loads Babel, resolves the Babel decorator plugin and TypeScript preset, and reports missing peer dependencies from the Vite `transform` hook when Vite transforms source files.
23
24
 
24
25
  ## When to Use
25
26
 
@@ -42,7 +43,17 @@ export default defineConfig({
42
43
  });
43
44
  ```
44
45
 
45
- The plugin transforms `.ts` application files with Babel using the `2023-11` decorators proposal and `@babel/preset-typescript`. It strips Vite query suffixes before deciding the file boundary, then skips declaration files, `*.test.ts` or `*.spec.ts` files, `node_modules`, and non-`.ts` files so generated Vitest test files continue to use the dedicated `@fluojs/testing/vitest` transform path.
46
+ The plugin transforms `.ts` application files with Babel using the `2023-11` decorators proposal and `@babel/preset-typescript`. It strips Vite query suffixes before deciding the file boundary, then skips declaration files, `*.test.ts` or `*.spec.ts` files, `node_modules`, and non-`.ts` files so generated Vitest test files continue to use the dedicated `@fluojs/testing/vitest` transform path. Importing `@fluojs/vite` or creating `fluoDecoratorsPlugin()` does not load `@babel/core`; missing Babel peers are surfaced as transform-time diagnostics for the source file Vite is transforming.
47
+
48
+ ## Decorator Transform Boundary
49
+
50
+ `@fluojs/vite` owns application build transforms, not Vitest test transforms. Generated non-Deno starters keep the file-boundary split explicit:
51
+
52
+ 1. `vite.config.ts` imports `fluoDecoratorsPlugin()` from `@fluojs/vite`.
53
+ 2. The Vite plugin strips query suffixes, accepts only application `.ts` files, lazily loads Babel on the first eligible transform, and runs `@babel/plugin-proposal-decorators` with `{ version: '2023-11' }` plus `@babel/preset-typescript`.
54
+ 3. `vitest.config.ts` imports `fluoBabelDecoratorsPlugin()` from `@fluojs/testing/vitest`, so `*.test.ts` and `*.spec.ts` files stay on the testing-specific transform path.
55
+
56
+ Keep those boundaries separate when customizing generated projects. Re-enabling `experimentalDecorators`, relying on direct esbuild decorator handling, or routing test files through the Vite application transform is outside the documented fluo support contract.
46
57
 
47
58
  ## Public API
48
59
 
@@ -1,19 +1,7 @@
1
1
  import type { Plugin } from 'vite';
2
- /**
3
- * Creates the Vite transform plugin used by fluo starter projects to compile
4
- * TC39 standard decorator syntax through Babel before Vite bundles the app.
5
- *
6
- * @returns A Vite plugin that transforms TypeScript application files and skips test files.
7
- *
8
- * @example
9
- * ```ts
10
- * import { fluoDecoratorsPlugin } from '@fluojs/vite';
11
- * import { defineConfig } from 'vite';
12
- *
13
- * export default defineConfig({
14
- * plugins: [fluoDecoratorsPlugin()],
15
- * });
16
- * ```
17
- */
2
+ type BabelCoreModule = Pick<typeof import('@babel/core'), 'transformAsync'>;
3
+ type BabelCoreImporter = () => Promise<BabelCoreModule>;
18
4
  export declare function fluoDecoratorsPlugin(): Plugin;
5
+ export declare function createFluoDecoratorsPluginForTesting(importBabelCoreModule: BabelCoreImporter): Plugin;
6
+ export {};
19
7
  //# sourceMappingURL=decorators-plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"decorators-plugin.d.ts","sourceRoot":"","sources":["../src/decorators-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAC;AA8BnD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CA6B7C"}
1
+ {"version":3,"file":"decorators-plugin.d.ts","sourceRoot":"","sources":["../src/decorators-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAC;AAEnD,KAAK,eAAe,GAAG,IAAI,CAAC,cAAc,aAAa,CAAC,EAAE,gBAAgB,CAAC,CAAC;AAC5E,KAAK,iBAAiB,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;AA8IxD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,oCAAoC,CAAC,qBAAqB,EAAE,iBAAiB,GAAG,MAAM,CAErG"}
@@ -1,4 +1,36 @@
1
- import { transformAsync } from '@babel/core';
1
+ const BABEL_PEER_DEPENDENCIES = ['@babel/core', '@babel/plugin-proposal-decorators', '@babel/preset-typescript'];
2
+ function readErrorCode(value) {
3
+ if (!value || typeof value !== 'object' || !('code' in value)) {
4
+ return undefined;
5
+ }
6
+ const code = value.code;
7
+ return typeof code === 'string' ? code : undefined;
8
+ }
9
+ function readErrorMessage(value) {
10
+ return value instanceof Error ? value.message : String(value);
11
+ }
12
+ function isMissingPeerDependencyError(error) {
13
+ const code = readErrorCode(error);
14
+ const message = readErrorMessage(error);
15
+ return (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND' || message.includes('Cannot find package')) && BABEL_PEER_DEPENDENCIES.some(dependencyName => message.includes(dependencyName));
16
+ }
17
+ function createBabelTransformDiagnostic(error, filePath) {
18
+ const message = readErrorMessage(error);
19
+ if (!isMissingPeerDependencyError(error)) {
20
+ return error instanceof Error ? error : new Error(message);
21
+ }
22
+ return new Error(`[fluo-babel-decorators] Failed to resolve a Babel peer dependency while transforming ${filePath}. ` + 'Install @babel/core, @babel/plugin-proposal-decorators, and @babel/preset-typescript in the Vite project. ' + `Original error: ${message}`);
23
+ }
24
+ async function importBabelCore() {
25
+ return await import('@babel/core');
26
+ }
27
+ async function loadBabelCore(filePath, importBabelCoreModule) {
28
+ try {
29
+ return await importBabelCoreModule();
30
+ } catch (error) {
31
+ throw createBabelTransformDiagnostic(error, filePath);
32
+ }
33
+ }
2
34
  function readViteFilePath(id) {
3
35
  const filePath = id.split(/[?#]/, 1)[0] ?? id;
4
36
  return filePath;
@@ -36,8 +68,9 @@ function shouldRequestBabelSourceMaps(config) {
36
68
  * });
37
69
  * ```
38
70
  */
39
- export function fluoDecoratorsPlugin() {
71
+ function createFluoDecoratorsPlugin(importBabelCoreModule) {
40
72
  let shouldGenerateSourceMaps = false;
73
+ let babelCorePromise;
41
74
  return {
42
75
  name: 'fluo-babel-decorators',
43
76
  configResolved(config) {
@@ -47,10 +80,13 @@ export function fluoDecoratorsPlugin() {
47
80
  if (!shouldTransformTypeScriptApplicationFile(id)) {
48
81
  return null;
49
82
  }
50
- const result = await transformAsync(code, {
83
+ const filePath = readViteFilePath(id);
84
+ babelCorePromise ??= loadBabelCore(filePath, importBabelCoreModule);
85
+ const babelCore = await babelCorePromise;
86
+ const result = await babelCore.transformAsync(code, {
51
87
  babelrc: false,
52
88
  configFile: false,
53
- filename: readViteFilePath(id),
89
+ filename: filePath,
54
90
  plugins: [['@babel/plugin-proposal-decorators', {
55
91
  version: '2023-11'
56
92
  }]],
@@ -58,6 +94,8 @@ export function fluoDecoratorsPlugin() {
58
94
  allowDeclareFields: true
59
95
  }]],
60
96
  sourceMaps: shouldGenerateSourceMaps
97
+ }).catch(error => {
98
+ throw createBabelTransformDiagnostic(error, filePath);
61
99
  });
62
100
  if (!result?.code) {
63
101
  return null;
@@ -68,4 +106,10 @@ export function fluoDecoratorsPlugin() {
68
106
  };
69
107
  }
70
108
  };
109
+ }
110
+ export function fluoDecoratorsPlugin() {
111
+ return createFluoDecoratorsPlugin(importBabelCore);
112
+ }
113
+ export function createFluoDecoratorsPluginForTesting(importBabelCoreModule) {
114
+ return createFluoDecoratorsPlugin(importBabelCoreModule);
71
115
  }
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "babel",
9
9
  "build-tooling"
10
10
  ],
11
- "version": "1.0.4",
11
+ "version": "1.0.6",
12
12
  "private": false,
13
13
  "license": "MIT",
14
14
  "repository": {