@simplysm/sd-cli 14.0.11 → 14.0.13
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.md +58 -253
- package/dist/angular/client-transform-stylesheet.js +1 -1
- package/dist/angular/client-transform-stylesheet.js.map +1 -1
- package/dist/angular/vite-angular-plugin.d.ts +4 -2
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +73 -36
- package/dist/angular/vite-angular-plugin.js.map +1 -1
- package/dist/angular/vite-postcss-inline-plugin.d.ts +1 -1
- package/dist/angular/vite-postcss-inline-plugin.js +1 -1
- package/dist/capacitor/capacitor.d.ts +20 -2
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +155 -28
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/build.d.ts +3 -10
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +3 -10
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/check.js +3 -3
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/dev.d.ts +3 -9
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +3 -9
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/device.d.ts +3 -3
- package/dist/commands/device.js +5 -5
- package/dist/commands/device.js.map +1 -1
- package/dist/commands/publish.d.ts +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +24 -26
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/replace-deps.d.ts +3 -3
- package/dist/commands/replace-deps.d.ts.map +1 -1
- package/dist/commands/replace-deps.js +1 -1
- package/dist/commands/typecheck.d.ts +4 -3
- package/dist/commands/typecheck.d.ts.map +1 -1
- package/dist/commands/typecheck.js +5 -11
- package/dist/commands/typecheck.js.map +1 -1
- package/dist/commands/watch.d.ts +9 -9
- package/dist/commands/watch.js +9 -9
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +42 -3
- package/dist/electron/electron.js.map +1 -1
- package/dist/engines/BaseEngine.d.ts +1 -1
- package/dist/engines/BaseEngine.d.ts.map +1 -1
- package/dist/engines/BaseEngine.js +3 -1
- package/dist/engines/BaseEngine.js.map +1 -1
- package/dist/engines/NgtscEngine.d.ts +7 -7
- package/dist/engines/NgtscEngine.d.ts.map +1 -1
- package/dist/engines/NgtscEngine.js +3 -3
- package/dist/engines/ServerEsbuildEngine.d.ts +7 -7
- package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
- package/dist/engines/ServerEsbuildEngine.js +3 -3
- package/dist/engines/TscEngine.d.ts +7 -7
- package/dist/engines/TscEngine.d.ts.map +1 -1
- package/dist/engines/TscEngine.js +3 -3
- package/dist/engines/ViteEngine.d.ts +7 -1
- package/dist/engines/ViteEngine.d.ts.map +1 -1
- package/dist/engines/ViteEngine.js +13 -12
- package/dist/engines/ViteEngine.js.map +1 -1
- package/dist/engines/index.d.ts +9 -5
- package/dist/engines/index.d.ts.map +1 -1
- package/dist/engines/index.js +7 -5
- package/dist/engines/index.js.map +1 -1
- package/dist/engines/types.d.ts +20 -20
- package/dist/engines/types.d.ts.map +1 -1
- package/dist/infra/ResultCollector.d.ts +9 -9
- package/dist/infra/ResultCollector.js +8 -8
- package/dist/infra/SignalHandler.d.ts +7 -7
- package/dist/infra/SignalHandler.js +7 -7
- package/dist/infra/WorkerManager.d.ts +14 -14
- package/dist/infra/WorkerManager.js +14 -14
- package/dist/orchestrators/BuildOrchestrator.d.ts +25 -25
- package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +34 -30
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.d.ts +7 -7
- package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.js +34 -34
- package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
- package/dist/sd-cli-entry.d.ts +2 -2
- package/dist/sd-cli-entry.d.ts.map +1 -1
- package/dist/sd-cli-entry.js +15 -8
- package/dist/sd-cli-entry.js.map +1 -1
- package/dist/sd-cli.d.ts +3 -3
- package/dist/sd-cli.js +16 -16
- package/dist/sd-cli.js.map +1 -1
- package/dist/sd-config.types.d.ts +105 -105
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/utils/angular-compiler.js +5 -5
- package/dist/utils/angular-compiler.js.map +1 -1
- package/dist/utils/build-env.d.ts +1 -1
- package/dist/utils/build-env.js +1 -1
- package/dist/utils/concurrency.d.ts +7 -7
- package/dist/utils/concurrency.js +7 -7
- package/dist/utils/copy-public.d.ts +9 -9
- package/dist/utils/copy-public.js +17 -17
- package/dist/utils/copy-public.js.map +1 -1
- package/dist/utils/copy-src.d.ts +9 -9
- package/dist/utils/copy-src.js +11 -11
- package/dist/utils/copy-src.js.map +1 -1
- package/dist/utils/engine-stop.d.ts +8 -9
- package/dist/utils/engine-stop.d.ts.map +1 -1
- package/dist/utils/engine-stop.js +9 -10
- package/dist/utils/engine-stop.js.map +1 -1
- package/dist/utils/esbuild-config.d.ts +23 -23
- package/dist/utils/esbuild-config.d.ts.map +1 -1
- package/dist/utils/esbuild-config.js +25 -25
- package/dist/utils/esbuild-config.js.map +1 -1
- package/dist/utils/lint-with-program.d.ts +15 -15
- package/dist/utils/lint-with-program.d.ts.map +1 -1
- package/dist/utils/lint-with-program.js +29 -29
- package/dist/utils/lint-with-program.js.map +1 -1
- package/dist/utils/ngtsc-build-core.d.ts +8 -8
- package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
- package/dist/utils/ngtsc-build-core.js +14 -14
- package/dist/utils/ngtsc-build-core.js.map +1 -1
- package/dist/utils/output-path-rewriter.d.ts +14 -14
- package/dist/utils/output-path-rewriter.js +18 -18
- package/dist/utils/output-path-rewriter.js.map +1 -1
- package/dist/utils/output-utils.d.ts +6 -6
- package/dist/utils/output-utils.js +11 -11
- package/dist/utils/output-utils.js.map +1 -1
- package/dist/utils/package-utils.d.ts +21 -21
- package/dist/utils/package-utils.d.ts.map +1 -1
- package/dist/utils/package-utils.js +56 -45
- package/dist/utils/package-utils.js.map +1 -1
- package/dist/utils/replace-deps.d.ts +25 -25
- package/dist/utils/replace-deps.d.ts.map +1 -1
- package/dist/utils/replace-deps.js +84 -65
- package/dist/utils/replace-deps.js.map +1 -1
- package/dist/utils/sd-config.d.ts +3 -3
- package/dist/utils/sd-config.js +3 -3
- package/dist/utils/tsc-build.d.ts +13 -13
- package/dist/utils/tsc-build.d.ts.map +1 -1
- package/dist/utils/tsc-build.js +9 -9
- package/dist/utils/tsc-build.js.map +1 -1
- package/dist/utils/tsconfig.d.ts +11 -9
- package/dist/utils/tsconfig.d.ts.map +1 -1
- package/dist/utils/tsconfig.js +11 -9
- package/dist/utils/tsconfig.js.map +1 -1
- package/dist/utils/typecheck-non-package.d.ts +5 -6
- package/dist/utils/typecheck-non-package.d.ts.map +1 -1
- package/dist/utils/typecheck-non-package.js +7 -8
- package/dist/utils/typecheck-non-package.js.map +1 -1
- package/dist/utils/typecheck-serialization.d.ts +8 -8
- package/dist/utils/typecheck-serialization.d.ts.map +1 -1
- package/dist/utils/typecheck-serialization.js +12 -16
- package/dist/utils/typecheck-serialization.js.map +1 -1
- package/dist/utils/vite-config.d.ts +12 -5
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +95 -41
- package/dist/utils/vite-config.js.map +1 -1
- package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
- package/dist/utils/vite-scope-watch-plugin.js +1 -1
- package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
- package/dist/utils/worker-events.d.ts +12 -12
- package/dist/utils/worker-events.d.ts.map +1 -1
- package/dist/utils/worker-events.js +10 -10
- package/dist/utils/worker-events.js.map +1 -1
- package/dist/utils/worker-utils.d.ts +12 -13
- package/dist/utils/worker-utils.d.ts.map +1 -1
- package/dist/utils/worker-utils.js +12 -13
- package/dist/utils/worker-utils.js.map +1 -1
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +5 -7
- package/dist/vitest-plugin.js.map +1 -1
- package/dist/workers/client.worker.d.ts +8 -2
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +215 -6
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/library-build.worker.d.ts +1 -1
- package/dist/workers/library-build.worker.d.ts.map +1 -1
- package/dist/workers/library-build.worker.js +7 -7
- package/dist/workers/library-build.worker.js.map +1 -1
- package/dist/workers/lint.worker.d.ts +2 -2
- package/dist/workers/lint.worker.js +2 -2
- package/dist/workers/ngtsc-build.worker.js +30 -30
- package/dist/workers/ngtsc-build.worker.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts +17 -17
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +46 -46
- package/dist/workers/server-build.worker.js.map +1 -1
- package/dist/workers/server-runtime.worker.d.ts +7 -7
- package/dist/workers/server-runtime.worker.d.ts.map +1 -1
- package/dist/workers/server-runtime.worker.js +17 -17
- package/dist/workers/server-runtime.worker.js.map +1 -1
- package/docs/config.md +340 -0
- package/docs/publish-configuration-types.md +87 -0
- package/docs/pwa-configuration-types.md +55 -0
- package/docs/vitest-plugin.md +47 -0
- package/package.json +9 -7
- package/src/angular/client-transform-stylesheet.ts +1 -1
- package/src/angular/vite-angular-plugin.ts +89 -39
- package/src/angular/vite-postcss-inline-plugin.ts +1 -1
- package/src/capacitor/capacitor.ts +185 -38
- package/src/commands/build.ts +3 -10
- package/src/commands/check.ts +3 -3
- package/src/commands/dev.ts +3 -9
- package/src/commands/device.ts +5 -5
- package/src/commands/publish.ts +30 -26
- package/src/commands/replace-deps.ts +3 -3
- package/src/commands/typecheck.ts +7 -13
- package/src/commands/watch.ts +9 -9
- package/src/electron/electron.ts +49 -4
- package/src/engines/BaseEngine.ts +4 -1
- package/src/engines/NgtscEngine.ts +7 -7
- package/src/engines/ServerEsbuildEngine.ts +7 -7
- package/src/engines/TscEngine.ts +7 -7
- package/src/engines/ViteEngine.ts +18 -13
- package/src/engines/index.ts +11 -5
- package/src/engines/types.ts +20 -20
- package/src/infra/ResultCollector.ts +9 -9
- package/src/infra/SignalHandler.ts +7 -7
- package/src/infra/WorkerManager.ts +14 -14
- package/src/orchestrators/BuildOrchestrator.ts +42 -38
- package/src/orchestrators/DevWatchOrchestrator.ts +36 -36
- package/src/sd-cli-entry.ts +15 -8
- package/src/sd-cli.ts +16 -16
- package/src/sd-config.types.ts +107 -107
- package/src/utils/angular-compiler.ts +5 -5
- package/src/utils/build-env.ts +1 -1
- package/src/utils/concurrency.ts +7 -7
- package/src/utils/copy-public.ts +17 -17
- package/src/utils/copy-src.ts +11 -11
- package/src/utils/engine-stop.ts +9 -10
- package/src/utils/esbuild-config.ts +29 -29
- package/src/utils/lint-with-program.ts +34 -34
- package/src/utils/ngtsc-build-core.ts +17 -17
- package/src/utils/output-path-rewriter.ts +18 -18
- package/src/utils/output-utils.ts +11 -11
- package/src/utils/package-utils.ts +57 -45
- package/src/utils/replace-deps.ts +92 -67
- package/src/utils/sd-config.ts +3 -3
- package/src/utils/tsc-build.ts +18 -18
- package/src/utils/tsconfig.ts +11 -9
- package/src/utils/typecheck-non-package.ts +7 -8
- package/src/utils/typecheck-serialization.ts +13 -15
- package/src/utils/vite-config.ts +108 -46
- package/src/utils/vite-scope-watch-plugin.ts +6 -1
- package/src/utils/worker-events.ts +16 -16
- package/src/utils/worker-utils.ts +12 -13
- package/src/vitest-plugin.ts +5 -8
- package/src/workers/client.worker.ts +246 -7
- package/src/workers/library-build.worker.ts +8 -8
- package/src/workers/lint.worker.ts +2 -2
- package/src/workers/ngtsc-build.worker.ts +31 -31
- package/src/workers/server-build.worker.ts +60 -60
- package/src/workers/server-runtime.worker.ts +22 -22
- package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +1 -0
- package/tests/angular/vite-angular-plugin-hmr.spec.ts +78 -0
- package/tests/angular/vite-angular-plugin.spec.ts +67 -0
- package/tests/capacitor/capacitor-build.spec.ts +93 -11
- package/tests/capacitor/capacitor-icon.spec.ts +7 -5
- package/tests/capacitor/capacitor-init.spec.ts +124 -10
- package/tests/capacitor/capacitor-run.spec.ts +14 -17
- package/tests/capacitor/capacitor-workspace.spec.ts +5 -3
- package/tests/commands/check.spec.ts +2 -2
- package/tests/commands/publish.spec.ts +2 -2
- package/tests/commands/typecheck.spec.ts +8 -0
- package/tests/electron/electron.spec.ts +12 -10
- package/tests/engines/base-engine.spec.ts +37 -0
- package/tests/engines/vite-engine.spec.ts +115 -3
- package/tests/utils/vite-config.spec.ts +162 -90
- package/tests/workers/client-worker.spec.ts +690 -0
- package/tests/workers/server-build-worker.spec.ts +3 -3
|
@@ -23,8 +23,8 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
23
23
|
glob: mockFsxGlob,
|
|
24
24
|
},
|
|
25
25
|
cpx: {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
spawn: mockCpxSpawn,
|
|
27
|
+
spawnSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
28
28
|
},
|
|
29
29
|
pathx: {
|
|
30
30
|
posixResolve: (...args: string[]) => path.resolve(...args).replace(/\\/g, "/"),
|
|
@@ -33,7 +33,7 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
33
33
|
}));
|
|
34
34
|
|
|
35
35
|
// cpx mock (was execa)
|
|
36
|
-
const
|
|
36
|
+
const mockCpxSpawn = vi.fn().mockResolvedValue({ stdout: "", stderr: "", exitCode: 0 });
|
|
37
37
|
|
|
38
38
|
// esbuild mock
|
|
39
39
|
const mockEsbuildBuild = vi.fn().mockResolvedValue({});
|
|
@@ -75,7 +75,9 @@ vi.mock("consola", () => ({
|
|
|
75
75
|
warn: mockLoggerWarn,
|
|
76
76
|
info: mockLoggerInfo,
|
|
77
77
|
}),
|
|
78
|
+
level: 0,
|
|
78
79
|
},
|
|
80
|
+
LogLevels: { debug: 4 },
|
|
79
81
|
}));
|
|
80
82
|
|
|
81
83
|
//#endregion
|
|
@@ -105,7 +107,7 @@ function setupDefaultMocks() {
|
|
|
105
107
|
}
|
|
106
108
|
return Promise.resolve([]);
|
|
107
109
|
});
|
|
108
|
-
|
|
110
|
+
mockCpxSpawn.mockResolvedValue({ stdout: "", stderr: "", exitCode: 0 });
|
|
109
111
|
mockEsbuildBuild.mockResolvedValue({});
|
|
110
112
|
}
|
|
111
113
|
|
|
@@ -179,7 +181,7 @@ describe("Electron", () => {
|
|
|
179
181
|
|
|
180
182
|
expect(findElectronPackageJson()).toBeDefined();
|
|
181
183
|
|
|
182
|
-
const execaCalls =
|
|
184
|
+
const execaCalls = mockCpxSpawn.mock.calls;
|
|
183
185
|
expect(
|
|
184
186
|
execaCalls.find((c) => c[0] === "npm" && (c[1] as string[]).includes("install")),
|
|
185
187
|
).toBeDefined();
|
|
@@ -196,7 +198,7 @@ describe("Electron", () => {
|
|
|
196
198
|
const electron = await Electron.create(PKG_PATH, { appId: "com.test.app" });
|
|
197
199
|
await electron.initialize();
|
|
198
200
|
|
|
199
|
-
const rebuildCall =
|
|
201
|
+
const rebuildCall = mockCpxSpawn.mock.calls.find(
|
|
200
202
|
(c) => typeof c[0] === "string" && c[0].includes("electron-rebuild"),
|
|
201
203
|
);
|
|
202
204
|
expect(rebuildCall).toBeUndefined();
|
|
@@ -453,7 +455,7 @@ describe("Electron", () => {
|
|
|
453
455
|
const electronKill = vi.fn();
|
|
454
456
|
let resolveElectron: () => void = () => {};
|
|
455
457
|
|
|
456
|
-
|
|
458
|
+
mockCpxSpawn.mockImplementation((cmd: string) => {
|
|
457
459
|
if (typeof cmd === "string" && cmd.includes("electron")) {
|
|
458
460
|
// Electron process: create a deferred promise we can resolve externally
|
|
459
461
|
const p = new Promise<void>((resolve) => {
|
|
@@ -535,7 +537,7 @@ describe("Electron", () => {
|
|
|
535
537
|
describe("단위: run() 플러그인 동작", () => {
|
|
536
538
|
it("passes custom env and ELECTRON_DEV_URL via esbuild banner", async () => {
|
|
537
539
|
let resolveElectron: () => void = () => {};
|
|
538
|
-
|
|
540
|
+
mockCpxSpawn.mockImplementation((cmd: string) => {
|
|
539
541
|
if (typeof cmd === "string" && cmd.includes("electron")) {
|
|
540
542
|
const p = new Promise<void>((resolve) => {
|
|
541
543
|
resolveElectron = resolve;
|
|
@@ -568,7 +570,7 @@ describe("Electron", () => {
|
|
|
568
570
|
|
|
569
571
|
it("calls initialize() before starting esbuild context", async () => {
|
|
570
572
|
let resolveElectron: () => void = () => {};
|
|
571
|
-
|
|
573
|
+
mockCpxSpawn.mockImplementation((cmd: string) => {
|
|
572
574
|
if (typeof cmd === "string" && cmd.includes("electron")) {
|
|
573
575
|
const p = new Promise<void>((resolve) => {
|
|
574
576
|
resolveElectron = resolve;
|
|
@@ -588,7 +590,7 @@ describe("Electron", () => {
|
|
|
588
590
|
await runPromise;
|
|
589
591
|
|
|
590
592
|
// initialize calls npm install -> execa should have been called with npm install
|
|
591
|
-
const npmInstallCall =
|
|
593
|
+
const npmInstallCall = mockCpxSpawn.mock.calls.find(
|
|
592
594
|
(c: any[]) => c[0] === "npm" && (c[1] as string[]).includes("install"),
|
|
593
595
|
);
|
|
594
596
|
expect(npmInstallCall).toBeDefined();
|
|
@@ -263,6 +263,43 @@ describe("BaseEngine", () => {
|
|
|
263
263
|
await engine.stop();
|
|
264
264
|
});
|
|
265
265
|
|
|
266
|
+
it("calls resolver on error event to release RebuildManager batch", async () => {
|
|
267
|
+
const mockResolver = vi.fn();
|
|
268
|
+
const mockRebuildManager = { registerBuild: vi.fn(() => mockResolver) };
|
|
269
|
+
|
|
270
|
+
mockWorker.startWatch.mockImplementation(() => {
|
|
271
|
+
// Trigger initial build to move past isInitialBuild
|
|
272
|
+
const buildHandler = mockWorker.on.mock.calls.find(
|
|
273
|
+
(call: any[]) => call[0] === "build",
|
|
274
|
+
)?.[1];
|
|
275
|
+
buildHandler?.({ build: { success: true } });
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
const engine = new TscEngine({
|
|
279
|
+
cwd: "/root",
|
|
280
|
+
pkg: createMockPkg(),
|
|
281
|
+
rebuildManager: mockRebuildManager as any,
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
await engine.startWatch({ js: true, dts: true });
|
|
285
|
+
|
|
286
|
+
// Simulate rebuild cycle: buildStart -> error (no build event)
|
|
287
|
+
const buildStartHandler = mockWorker.on.mock.calls.find(
|
|
288
|
+
(call: any[]) => call[0] === "buildStart",
|
|
289
|
+
)?.[1];
|
|
290
|
+
const errorHandler = mockWorker.on.mock.calls.find(
|
|
291
|
+
(call: any[]) => call[0] === "error",
|
|
292
|
+
)?.[1];
|
|
293
|
+
|
|
294
|
+
buildStartHandler?.({});
|
|
295
|
+
expect(mockRebuildManager.registerBuild).toHaveBeenCalled();
|
|
296
|
+
|
|
297
|
+
errorHandler?.({ message: "Worker crashed" });
|
|
298
|
+
expect(mockResolver).toHaveBeenCalled();
|
|
299
|
+
|
|
300
|
+
await engine.stop();
|
|
301
|
+
});
|
|
302
|
+
|
|
266
303
|
it("uses _getTarget() for BuildResult target", async () => {
|
|
267
304
|
const mockResultCollector = { add: vi.fn() };
|
|
268
305
|
|
|
@@ -191,6 +191,30 @@ describe("ViteEngine", () => {
|
|
|
191
191
|
await engine.stop();
|
|
192
192
|
});
|
|
193
193
|
|
|
194
|
+
// Acceptance: Scenario "exclude 전달 (build)"
|
|
195
|
+
it("passes exclude from config to worker build call", async () => {
|
|
196
|
+
mockWorker.build.mockResolvedValue({ success: true });
|
|
197
|
+
|
|
198
|
+
const engine = new ViteEngine({
|
|
199
|
+
cwd: "/root",
|
|
200
|
+
pkg: createMockPkg({
|
|
201
|
+
config: {
|
|
202
|
+
target: "client",
|
|
203
|
+
server: "my-server",
|
|
204
|
+
exclude: ["jeep-sqlite"],
|
|
205
|
+
} as any,
|
|
206
|
+
}),
|
|
207
|
+
});
|
|
208
|
+
await engine.run({ js: true, dts: false });
|
|
209
|
+
|
|
210
|
+
expect(mockWorker.build).toHaveBeenCalledWith(
|
|
211
|
+
expect.objectContaining({
|
|
212
|
+
exclude: ["jeep-sqlite"],
|
|
213
|
+
}),
|
|
214
|
+
);
|
|
215
|
+
await engine.stop();
|
|
216
|
+
});
|
|
217
|
+
|
|
194
218
|
// Unit: build failure reflects in result
|
|
195
219
|
it("reflects build failure in result", async () => {
|
|
196
220
|
mockWorker.build.mockResolvedValue({
|
|
@@ -265,11 +289,18 @@ describe("ViteEngine", () => {
|
|
|
265
289
|
await engine.stop();
|
|
266
290
|
});
|
|
267
291
|
|
|
268
|
-
// Acceptance: Scenario "ResultCollector에 결과 보고"
|
|
269
|
-
it("reports build result to ResultCollector", async () => {
|
|
292
|
+
// Acceptance: Scenario "ResultCollector에 결과 보고 — build 이벤트 경유"
|
|
293
|
+
it("reports build result to ResultCollector via build event only", async () => {
|
|
270
294
|
const mockResultCollector = { add: vi.fn() };
|
|
271
295
|
|
|
272
|
-
mockWorker.startWatch.
|
|
296
|
+
mockWorker.startWatch.mockImplementation(() => {
|
|
297
|
+
// Simulate "build" event during startWatch (Angular plugin buildStart)
|
|
298
|
+
const buildHandler = mockWorker.on.mock.calls.find(
|
|
299
|
+
(call: any[]) => call[0] === "build",
|
|
300
|
+
)?.[1];
|
|
301
|
+
buildHandler?.({ success: true });
|
|
302
|
+
return Promise.resolve({ success: true });
|
|
303
|
+
});
|
|
273
304
|
|
|
274
305
|
const engine = new ViteEngine({
|
|
275
306
|
cwd: "/root",
|
|
@@ -388,6 +419,32 @@ describe("ViteEngine", () => {
|
|
|
388
419
|
await engine.stop();
|
|
389
420
|
});
|
|
390
421
|
|
|
422
|
+
// Acceptance: Scenario "exclude 전달 (watch)"
|
|
423
|
+
it("passes exclude from config to worker startWatch call", async () => {
|
|
424
|
+
mockWorker.startWatch.mockResolvedValue({ success: true });
|
|
425
|
+
|
|
426
|
+
const engine = new ViteEngine({
|
|
427
|
+
cwd: "/root",
|
|
428
|
+
pkg: createMockPkg({
|
|
429
|
+
config: {
|
|
430
|
+
target: "client",
|
|
431
|
+
server: "my-server",
|
|
432
|
+
exclude: ["jeep-sqlite", "another-pkg"],
|
|
433
|
+
} as any,
|
|
434
|
+
}),
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
await engine.startWatch({ js: true, dts: false });
|
|
438
|
+
|
|
439
|
+
expect(mockWorker.startWatch).toHaveBeenCalledWith(
|
|
440
|
+
expect.objectContaining({
|
|
441
|
+
exclude: ["jeep-sqlite", "another-pkg"],
|
|
442
|
+
}),
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
await engine.stop();
|
|
446
|
+
});
|
|
447
|
+
|
|
391
448
|
// Unit: server: string does not pass port
|
|
392
449
|
it("does not pass port when config.server is a string", async () => {
|
|
393
450
|
mockWorker.startWatch.mockResolvedValue({ success: true });
|
|
@@ -480,6 +537,61 @@ describe("ViteEngine", () => {
|
|
|
480
537
|
await engine.stop();
|
|
481
538
|
});
|
|
482
539
|
|
|
540
|
+
// Unit: mock worker가 serverReady를 발행하지 않으면 port가 undefined로 남는다
|
|
541
|
+
it("leaves port undefined when worker mock does not emit serverReady for legacyModule", async () => {
|
|
542
|
+
mockWorker.startWatch.mockResolvedValue({ success: true });
|
|
543
|
+
|
|
544
|
+
const engine = new ViteEngine({
|
|
545
|
+
cwd: "/root",
|
|
546
|
+
pkg: createMockPkg({
|
|
547
|
+
config: {
|
|
548
|
+
target: "client",
|
|
549
|
+
server: "my-server",
|
|
550
|
+
browserSupport: { legacyModule: true },
|
|
551
|
+
} as any,
|
|
552
|
+
}),
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
await engine.startWatch({ js: true, dts: false });
|
|
556
|
+
|
|
557
|
+
// serverReady is subscribed but never emitted — port stays undefined
|
|
558
|
+
expect(engine.port).toBeUndefined();
|
|
559
|
+
|
|
560
|
+
// buildStart/build event handlers are still registered
|
|
561
|
+
expect(mockWorker.on).toHaveBeenCalledWith("buildStart", expect.any(Function));
|
|
562
|
+
expect(mockWorker.on).toHaveBeenCalledWith("build", expect.any(Function));
|
|
563
|
+
|
|
564
|
+
await engine.stop();
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// Unit: initial build result is reported exactly once (not duplicated by startWatch return)
|
|
568
|
+
it("reports initial build result exactly once to ResultCollector", async () => {
|
|
569
|
+
const mockResultCollector = { add: vi.fn() };
|
|
570
|
+
|
|
571
|
+
mockWorker.startWatch.mockImplementation(() => {
|
|
572
|
+
const buildHandler = mockWorker.on.mock.calls.find(
|
|
573
|
+
(call: any[]) => call[0] === "build",
|
|
574
|
+
)?.[1];
|
|
575
|
+
buildHandler?.({ success: true });
|
|
576
|
+
return Promise.resolve({ success: true });
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
const engine = new ViteEngine({
|
|
580
|
+
cwd: "/root",
|
|
581
|
+
pkg: createMockPkg(),
|
|
582
|
+
resultCollector: mockResultCollector as any,
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
await engine.startWatch({ js: true, dts: false });
|
|
586
|
+
|
|
587
|
+
const buildAddCalls = mockResultCollector.add.mock.calls.filter(
|
|
588
|
+
(c: any[]) => c[0].type === "build",
|
|
589
|
+
);
|
|
590
|
+
expect(buildAddCalls).toHaveLength(1);
|
|
591
|
+
|
|
592
|
+
await engine.stop();
|
|
593
|
+
});
|
|
594
|
+
|
|
483
595
|
// Unit: error event reports to ResultCollector
|
|
484
596
|
it("reports error from error event to ResultCollector", async () => {
|
|
485
597
|
const mockResultCollector = { add: vi.fn() };
|
|
@@ -221,8 +221,8 @@ describe("createClientViteConfig", () => {
|
|
|
221
221
|
|
|
222
222
|
// --- legacyModule (Feature 1.1) ---
|
|
223
223
|
|
|
224
|
-
// Acceptance: Scenario "legacyModule
|
|
225
|
-
it("enables inlineDynamicImports
|
|
224
|
+
// Acceptance: Scenario "legacyModule 활성화 시 inlineDynamicImports만 설정한다"
|
|
225
|
+
it("enables inlineDynamicImports without import.meta plugin when legacyModule is true", async () => {
|
|
226
226
|
const config = await createClientViteConfig({
|
|
227
227
|
...createDefaultOptions(),
|
|
228
228
|
legacyModule: true,
|
|
@@ -230,26 +230,22 @@ describe("createClientViteConfig", () => {
|
|
|
230
230
|
|
|
231
231
|
// inlineDynamicImports가 활성화된다
|
|
232
232
|
expect((config.build as any)?.rollupOptions?.output?.inlineDynamicImports).toBe(true);
|
|
233
|
-
// import.meta 치환 플러그인이
|
|
233
|
+
// import.meta 치환 플러그인이 없다 (esbuild target이 자동 치환)
|
|
234
234
|
const plugins = config.plugins as Array<{ name: string }>;
|
|
235
235
|
const legacyPlugin = plugins.find((p) => p.name === "sd-legacy-import-meta");
|
|
236
|
-
expect(legacyPlugin).
|
|
236
|
+
expect(legacyPlugin).toBeUndefined();
|
|
237
237
|
});
|
|
238
238
|
|
|
239
|
-
// Acceptance: Scenario "legacyModule
|
|
240
|
-
it("does not set inlineDynamicImports
|
|
239
|
+
// Acceptance: Scenario "legacyModule 미설정 시 코드 분할이 기본 동작한다"
|
|
240
|
+
it("does not set inlineDynamicImports when legacyModule is not set", async () => {
|
|
241
241
|
const config = await createClientViteConfig(createDefaultOptions());
|
|
242
242
|
|
|
243
243
|
// 코드 분할이 기본 동작한다
|
|
244
244
|
expect(config.build?.rollupOptions).toBeUndefined();
|
|
245
|
-
// import.meta가 그대로 유지된다
|
|
246
|
-
const plugins = config.plugins as Array<{ name: string }>;
|
|
247
|
-
const legacyPlugin = plugins.find((p) => p.name === "sd-legacy-import-meta");
|
|
248
|
-
expect(legacyPlugin).toBeUndefined();
|
|
249
245
|
});
|
|
250
246
|
|
|
251
|
-
// Acceptance: Scenario "
|
|
252
|
-
it("legacyModule: true provides inlineDynamicImports
|
|
247
|
+
// Acceptance: Scenario "legacyModule: true는 inlineDynamicImports를 활성화한다"
|
|
248
|
+
it("legacyModule: true provides inlineDynamicImports (splitting replacement)", async () => {
|
|
253
249
|
const config = await createClientViteConfig({
|
|
254
250
|
...createDefaultOptions(),
|
|
255
251
|
legacyModule: true,
|
|
@@ -257,95 +253,31 @@ describe("createClientViteConfig", () => {
|
|
|
257
253
|
|
|
258
254
|
// 기존 splitting: false와 동일한 inlineDynamicImports 동작
|
|
259
255
|
expect((config.build as any)?.rollupOptions?.output?.inlineDynamicImports).toBe(true);
|
|
260
|
-
// 추가로 import.meta 치환이 활성화된다
|
|
261
|
-
const plugins = config.plugins as Array<{ name: string }>;
|
|
262
|
-
const legacyPlugin = plugins.find((p) => p.name === "sd-legacy-import-meta");
|
|
263
|
-
expect(legacyPlugin).toBeDefined();
|
|
264
256
|
});
|
|
265
257
|
|
|
266
|
-
//
|
|
267
|
-
it("sd-legacy-import-meta plugin has enforce: post", async () => {
|
|
268
|
-
const config = await createClientViteConfig({
|
|
269
|
-
...createDefaultOptions(),
|
|
270
|
-
legacyModule: true,
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
const plugins = config.plugins as Array<{ name: string; enforce?: string }>;
|
|
274
|
-
const legacyPlugin = plugins.find((p) => p.name === "sd-legacy-import-meta");
|
|
275
|
-
expect(legacyPlugin?.enforce).toBe("post");
|
|
276
|
-
});
|
|
258
|
+
// --- legacyModule esbuild.supported override (Feature 1.4) ---
|
|
277
259
|
|
|
278
|
-
// Acceptance: Scenario "
|
|
279
|
-
it("
|
|
260
|
+
// Acceptance: Scenario "legacyModule: true일 때 esbuild.supported에 import-meta false 설정"
|
|
261
|
+
it("sets esbuild.supported to disable import-meta when legacyModule is true", async () => {
|
|
280
262
|
const config = await createClientViteConfig({
|
|
281
263
|
...createDefaultOptions(),
|
|
282
264
|
legacyModule: true,
|
|
283
265
|
});
|
|
284
266
|
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const result = legacyPlugin!.transform!(code, id);
|
|
292
|
-
|
|
293
|
-
expect(result).toBeDefined();
|
|
294
|
-
expect(result.code).toContain(JSON.stringify(id));
|
|
295
|
-
expect(result.code).not.toContain("import.meta");
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
// Acceptance: Scenario "Vite가 주입한 import.meta.hot을 치환한다"
|
|
299
|
-
it("sd-legacy-import-meta plugin replaces import.meta.hot injected by Vite", async () => {
|
|
300
|
-
const config = await createClientViteConfig({
|
|
301
|
-
...createDefaultOptions(),
|
|
302
|
-
legacyModule: true,
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
const plugins = config.plugins as Array<{ name: string; transform?: Function }>;
|
|
306
|
-
const legacyPlugin = plugins.find((p) => p.name === "sd-legacy-import-meta");
|
|
307
|
-
|
|
308
|
-
const code = 'import.meta.hot = createHotContext("/src/app.ts");';
|
|
309
|
-
const id = "/packages/my-client/src/app.ts";
|
|
310
|
-
const result = legacyPlugin!.transform!(code, id);
|
|
311
|
-
|
|
312
|
-
expect(result).toBeDefined();
|
|
313
|
-
expect(result.code).not.toContain("import.meta");
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
// Acceptance: Scenario "/@vite/client의 import.meta를 치환한다"
|
|
317
|
-
it("sd-legacy-import-meta plugin replaces import.meta in /@vite/client", async () => {
|
|
318
|
-
const config = await createClientViteConfig({
|
|
319
|
-
...createDefaultOptions(),
|
|
320
|
-
legacyModule: true,
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
const plugins = config.plugins as Array<{ name: string; transform?: Function }>;
|
|
324
|
-
const legacyPlugin = plugins.find((p) => p.name === "sd-legacy-import-meta");
|
|
325
|
-
|
|
326
|
-
const code = 'const base = import.meta.url;';
|
|
327
|
-
const id = "/@vite/client";
|
|
328
|
-
const result = legacyPlugin!.transform!(code, id);
|
|
329
|
-
|
|
330
|
-
expect(result).toBeDefined();
|
|
331
|
-
expect(result.code).not.toContain("import.meta");
|
|
267
|
+
const esbuildOpts = config.esbuild as Record<string, unknown> | undefined;
|
|
268
|
+
expect(esbuildOpts?.["supported"]).toEqual(
|
|
269
|
+
expect.objectContaining({
|
|
270
|
+
"import-meta": false,
|
|
271
|
+
}),
|
|
272
|
+
);
|
|
332
273
|
});
|
|
333
274
|
|
|
334
|
-
// Acceptance: Scenario "
|
|
335
|
-
it("
|
|
336
|
-
const config = await createClientViteConfig(
|
|
337
|
-
...createDefaultOptions(),
|
|
338
|
-
legacyModule: true,
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
const plugins = config.plugins as Array<{ name: string; transform?: Function }>;
|
|
342
|
-
const legacyPlugin = plugins.find((p) => p.name === "sd-legacy-import-meta");
|
|
343
|
-
|
|
344
|
-
const code = 'const x = 1 + 2;';
|
|
345
|
-
const id = "/packages/my-client/src/utils.ts";
|
|
346
|
-
const result = legacyPlugin!.transform!(code, id);
|
|
275
|
+
// Acceptance: Scenario "legacyModule 미설정 시 esbuild.supported 변경 없음"
|
|
276
|
+
it("does not set esbuild.supported when legacyModule is not specified", async () => {
|
|
277
|
+
const config = await createClientViteConfig(createDefaultOptions());
|
|
347
278
|
|
|
348
|
-
|
|
279
|
+
const esbuildOpts = config.esbuild as Record<string, unknown> | undefined;
|
|
280
|
+
expect(esbuildOpts?.["supported"]).toBeUndefined();
|
|
349
281
|
});
|
|
350
282
|
|
|
351
283
|
// --- PWA (Feature 5.2) ---
|
|
@@ -505,6 +437,146 @@ describe("createClientViteConfig", () => {
|
|
|
505
437
|
);
|
|
506
438
|
});
|
|
507
439
|
|
|
440
|
+
// --- watch option (Feature 1.2: legacy dev mode) ---
|
|
441
|
+
|
|
442
|
+
// Acceptance: Scenario "watch: true 시 build.watch 설정 및 emptyOutDir: false"
|
|
443
|
+
it("sets build.watch and emptyOutDir: false when watch is true in build mode", async () => {
|
|
444
|
+
const config = await createClientViteConfig({
|
|
445
|
+
...createDefaultOptions(),
|
|
446
|
+
mode: "build",
|
|
447
|
+
watch: true,
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
expect(config.build?.watch).toEqual({});
|
|
451
|
+
expect(config.build?.emptyOutDir).toBe(false);
|
|
452
|
+
expect(config.logLevel).toBeUndefined();
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
// Acceptance: Scenario "watch: true + replaceDeps 시 sdScopeWatchPlugin 포함"
|
|
456
|
+
it("includes sdScopeWatchPlugin when watch is true with replaceDeps in build mode", async () => {
|
|
457
|
+
const { sdScopeWatchPlugin } = await import("../../src/utils/vite-scope-watch-plugin");
|
|
458
|
+
|
|
459
|
+
const config = await createClientViteConfig({
|
|
460
|
+
...createDefaultOptions(),
|
|
461
|
+
mode: "build",
|
|
462
|
+
watch: true,
|
|
463
|
+
replaceDeps: [{ packageName: "@scope/core", sourcePath: "/packages/core" }],
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
const plugins = config.plugins as Array<{ name: string }>;
|
|
467
|
+
const scopePlugin = plugins.find((p) => p.name === "sd-scope-watch-plugin");
|
|
468
|
+
expect(scopePlugin).toBeDefined();
|
|
469
|
+
expect(sdScopeWatchPlugin).toHaveBeenCalled();
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Acceptance: Scenario "watch 미설정 시 기존 build 동작 유지"
|
|
473
|
+
it("sets emptyOutDir: true and logLevel: silent when watch is not set in build mode", async () => {
|
|
474
|
+
const config = await createClientViteConfig(createDefaultOptions());
|
|
475
|
+
|
|
476
|
+
expect(config.build?.emptyOutDir).toBe(true);
|
|
477
|
+
expect(config.logLevel).toBe("silent");
|
|
478
|
+
expect(config.build?.watch).toBeUndefined();
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// Unit: watch: true without replaceDeps does not add sdScopeWatchPlugin
|
|
482
|
+
it("does not add sdScopeWatchPlugin in watch mode without replaceDeps", async () => {
|
|
483
|
+
const config = await createClientViteConfig({
|
|
484
|
+
...createDefaultOptions(),
|
|
485
|
+
mode: "build",
|
|
486
|
+
watch: true,
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
const plugins = config.plugins as Array<{ name: string }>;
|
|
490
|
+
const scopePlugin = plugins.find((p) => p.name === "sd-scope-watch-plugin");
|
|
491
|
+
expect(scopePlugin).toBeUndefined();
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// Unit: watch: true still sets outDir
|
|
495
|
+
it("sets outDir in watch mode", async () => {
|
|
496
|
+
const config = await createClientViteConfig({
|
|
497
|
+
...createDefaultOptions(),
|
|
498
|
+
mode: "build",
|
|
499
|
+
watch: true,
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
expect(config.build?.outDir).toContain("my-client");
|
|
503
|
+
expect(config.build?.outDir).toMatch(/dist$/);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
// --- outDir override ---
|
|
507
|
+
|
|
508
|
+
// Acceptance: Scenario "outDir 설정 시 해당 경로로 빌드 출력"
|
|
509
|
+
it("uses custom outDir when provided", async () => {
|
|
510
|
+
const config = await createClientViteConfig({
|
|
511
|
+
...createDefaultOptions(),
|
|
512
|
+
outDir: "/packages/my-client/.capacitor/www",
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
expect(config.build?.outDir).toBe("/packages/my-client/.capacitor/www");
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
// Acceptance: Scenario "outDir 미설정 시 pkgDir/dist 사용"
|
|
519
|
+
it("defaults outDir to pkgDir/dist when not provided", async () => {
|
|
520
|
+
const config = await createClientViteConfig(createDefaultOptions());
|
|
521
|
+
|
|
522
|
+
expect(config.build?.outDir).toMatch(/my-client[\\/]dist$/);
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// --- exclude (Feature 1.1: vite-exclude-passthrough) ---
|
|
526
|
+
|
|
527
|
+
// Acceptance: Scenario "exclude에 패키지를 지정하면 pre-bundling에서 제외된다"
|
|
528
|
+
it("sets optimizeDeps.exclude when exclude is provided", async () => {
|
|
529
|
+
const config = await createClientViteConfig({
|
|
530
|
+
...createDefaultOptions(),
|
|
531
|
+
mode: "dev",
|
|
532
|
+
exclude: ["jeep-sqlite"],
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
expect(config.optimizeDeps?.exclude).toEqual(["jeep-sqlite"]);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// Acceptance: Scenario "exclude 미설정 시 기존 동작과 동일하다"
|
|
539
|
+
it("does not set optimizeDeps.exclude when exclude is not provided", async () => {
|
|
540
|
+
const config = await createClientViteConfig({
|
|
541
|
+
...createDefaultOptions(),
|
|
542
|
+
mode: "dev",
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
expect(config.optimizeDeps?.exclude).toBeUndefined();
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
// Acceptance: Scenario "exclude와 replaceDeps가 모두 있으면 둘 다 제외된다"
|
|
549
|
+
it("sets optimizeDeps.exclude from exclude while sdScopeWatchPlugin handles replaceDeps", async () => {
|
|
550
|
+
const { sdScopeWatchPlugin } = await import("../../src/utils/vite-scope-watch-plugin");
|
|
551
|
+
|
|
552
|
+
const config = await createClientViteConfig({
|
|
553
|
+
...createDefaultOptions(),
|
|
554
|
+
mode: "dev",
|
|
555
|
+
exclude: ["jeep-sqlite"],
|
|
556
|
+
replaceDeps: [{ packageName: "@scope/core", sourcePath: "/packages/core" }],
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
// Base config에 exclude 설정
|
|
560
|
+
expect(config.optimizeDeps?.exclude).toEqual(["jeep-sqlite"]);
|
|
561
|
+
// sdScopeWatchPlugin도 호출됨 (replaceDeps용 exclude는 plugin이 처리)
|
|
562
|
+
expect(sdScopeWatchPlugin).toHaveBeenCalled();
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
// Acceptance: Scenario "exclude만 있고 replaceDeps가 없으면 exclude만 제외된다"
|
|
566
|
+
it("sets optimizeDeps.exclude from exclude when no replaceDeps", async () => {
|
|
567
|
+
const config = await createClientViteConfig({
|
|
568
|
+
...createDefaultOptions(),
|
|
569
|
+
mode: "dev",
|
|
570
|
+
exclude: ["jeep-sqlite"],
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
expect(config.optimizeDeps?.exclude).toEqual(["jeep-sqlite"]);
|
|
574
|
+
// sdScopeWatchPlugin은 호출되지 않음
|
|
575
|
+
const plugins = config.plugins as Array<{ name: string }>;
|
|
576
|
+
const scopePlugin = plugins.find((p) => p.name === "sd-scope-watch-plugin");
|
|
577
|
+
expect(scopePlugin).toBeUndefined();
|
|
578
|
+
});
|
|
579
|
+
|
|
508
580
|
// Acceptance: Scenario "pwa 필드 미설정 시 기본값"
|
|
509
581
|
it("uses default manifest values from pkgName when pwa is undefined", async () => {
|
|
510
582
|
await createClientViteConfig(createDefaultOptions());
|