@simplysm/sd-cli 14.0.10 → 14.0.12
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 +1 -1
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +60 -34
- 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 +14 -2
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +131 -17
- 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 +13 -0
- package/dist/commands/device.d.ts.map +1 -0
- package/dist/commands/device.js +53 -0
- package/dist/commands/device.js.map +1 -0
- package/dist/commands/publish.d.ts +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +18 -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 +1 -1
- package/dist/engines/ViteEngine.d.ts.map +1 -1
- package/dist/engines/ViteEngine.js +7 -12
- package/dist/engines/ViteEngine.js.map +1 -1
- package/dist/engines/index.d.ts +5 -5
- package/dist/engines/index.js +5 -5
- 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 +29 -29
- 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 +35 -57
- 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 +45 -9
- 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 +8 -5
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +36 -29
- 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 +4 -2
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +209 -1
- 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 +70 -37
- package/src/angular/vite-postcss-inline-plugin.ts +1 -1
- package/src/capacitor/capacitor.ts +159 -23
- 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 +65 -0
- 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 +8 -13
- package/src/engines/index.ts +5 -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 +37 -37
- package/src/orchestrators/DevWatchOrchestrator.ts +37 -61
- package/src/sd-cli-entry.ts +51 -9
- 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 +45 -35
- 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 +236 -2
- 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 +6 -4
- package/tests/capacitor/capacitor-icon.spec.ts +7 -5
- package/tests/capacitor/capacitor-init.spec.ts +120 -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/device.spec.ts +147 -0
- 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/orchestrators/dev-watch-orchestrator.spec.ts +21 -93
- package/tests/utils/vite-config.spec.ts +144 -90
- package/tests/workers/client-worker.spec.ts +690 -0
- package/tests/workers/server-build-worker.spec.ts +3 -3
|
@@ -1373,8 +1373,8 @@ describe("DevWatchOrchestrator", () => {
|
|
|
1373
1373
|
});
|
|
1374
1374
|
}
|
|
1375
1375
|
|
|
1376
|
-
// Acceptance: Scenario "Capacitor
|
|
1377
|
-
it("runs Capacitor.create + initialize
|
|
1376
|
+
// Acceptance: Scenario "Capacitor 초기화만 수행 (run 미호출)"
|
|
1377
|
+
it("runs Capacitor.create + initialize but NOT run in dev mode", async () => {
|
|
1378
1378
|
setupDefaults(createConfig({
|
|
1379
1379
|
packages: {
|
|
1380
1380
|
"my-client": {
|
|
@@ -1396,11 +1396,11 @@ describe("DevWatchOrchestrator", () => {
|
|
|
1396
1396
|
undefined,
|
|
1397
1397
|
);
|
|
1398
1398
|
expect(mockCapacitorInstance.initialize).toHaveBeenCalled();
|
|
1399
|
-
expect(mockCapacitorInstance.run).
|
|
1399
|
+
expect(mockCapacitorInstance.run).not.toHaveBeenCalled();
|
|
1400
1400
|
});
|
|
1401
1401
|
|
|
1402
|
-
// Acceptance: Scenario "Electron
|
|
1403
|
-
it("
|
|
1402
|
+
// Acceptance: Scenario "dev 모드에서 Electron 미처리"
|
|
1403
|
+
it("does not run Electron in dev mode even when electron config exists", async () => {
|
|
1404
1404
|
setupDefaults(createConfig({
|
|
1405
1405
|
packages: {
|
|
1406
1406
|
"my-client": {
|
|
@@ -1416,17 +1416,13 @@ describe("DevWatchOrchestrator", () => {
|
|
|
1416
1416
|
await orchestrator.initialize();
|
|
1417
1417
|
await orchestrator.start();
|
|
1418
1418
|
|
|
1419
|
-
expect(Electron.create).
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
undefined,
|
|
1423
|
-
);
|
|
1424
|
-
expect(mockElectronInstance.initialize).toHaveBeenCalled();
|
|
1425
|
-
expect(mockElectronInstance.run).toHaveBeenCalledWith("http://localhost:4200");
|
|
1419
|
+
expect(Electron.create).not.toHaveBeenCalled();
|
|
1420
|
+
expect(mockElectronInstance.initialize).not.toHaveBeenCalled();
|
|
1421
|
+
expect(mockElectronInstance.run).not.toHaveBeenCalled();
|
|
1426
1422
|
});
|
|
1427
1423
|
|
|
1428
|
-
// Acceptance: Scenario "Capacitor + Electron 동시
|
|
1429
|
-
it("
|
|
1424
|
+
// Acceptance: Scenario "Capacitor + Electron 동시 설정 시 Capacitor만 초기화"
|
|
1425
|
+
it("initializes Capacitor but ignores Electron when both are configured", async () => {
|
|
1430
1426
|
setupDefaults(createConfig({
|
|
1431
1427
|
packages: {
|
|
1432
1428
|
"my-client": {
|
|
@@ -1444,9 +1440,9 @@ describe("DevWatchOrchestrator", () => {
|
|
|
1444
1440
|
await orchestrator.start();
|
|
1445
1441
|
|
|
1446
1442
|
expect(Capacitor.create).toHaveBeenCalled();
|
|
1447
|
-
expect(mockCapacitorInstance.
|
|
1448
|
-
expect(
|
|
1449
|
-
expect(
|
|
1443
|
+
expect(mockCapacitorInstance.initialize).toHaveBeenCalled();
|
|
1444
|
+
expect(mockCapacitorInstance.run).not.toHaveBeenCalled();
|
|
1445
|
+
expect(Electron.create).not.toHaveBeenCalled();
|
|
1450
1446
|
});
|
|
1451
1447
|
|
|
1452
1448
|
// Acceptance: Scenario "네이티브 설정 없는 dev 모드"
|
|
@@ -1466,11 +1462,9 @@ describe("DevWatchOrchestrator", () => {
|
|
|
1466
1462
|
expect(Electron.create).not.toHaveBeenCalled();
|
|
1467
1463
|
});
|
|
1468
1464
|
|
|
1469
|
-
// Acceptance: Scenario "dev 모드 종료 시
|
|
1470
|
-
//
|
|
1471
|
-
|
|
1472
|
-
// This scenario verifies that shutdown() completes without error when native apps are running.
|
|
1473
|
-
it("shutdown completes when native apps were launched", async () => {
|
|
1465
|
+
// Acceptance: Scenario "dev 모드 종료 시 Capacitor 초기화 후 정상 종료"
|
|
1466
|
+
// Capacitor.initialize()만 호출되므로 별도 정리 불필요.
|
|
1467
|
+
it("shutdown completes when Capacitor was initialized", async () => {
|
|
1474
1468
|
setupDefaults(createConfig({
|
|
1475
1469
|
packages: {
|
|
1476
1470
|
"my-client": {
|
|
@@ -1493,8 +1487,8 @@ describe("DevWatchOrchestrator", () => {
|
|
|
1493
1487
|
}
|
|
1494
1488
|
});
|
|
1495
1489
|
|
|
1496
|
-
// Unit:
|
|
1497
|
-
it("logs error but does not crash when Capacitor.
|
|
1490
|
+
// Unit: Capacitor.initialize 에러는 로그만 남기고 크래시하지 않음
|
|
1491
|
+
it("logs error but does not crash when Capacitor.initialize throws", async () => {
|
|
1498
1492
|
setupDefaults(createConfig({
|
|
1499
1493
|
packages: {
|
|
1500
1494
|
"my-client": {
|
|
@@ -1505,81 +1499,15 @@ describe("DevWatchOrchestrator", () => {
|
|
|
1505
1499
|
},
|
|
1506
1500
|
}));
|
|
1507
1501
|
setupEngineWithPort(4200);
|
|
1508
|
-
mockCapacitorInstance.
|
|
1502
|
+
mockCapacitorInstance.initialize.mockRejectedValue(new Error("init failed"));
|
|
1509
1503
|
|
|
1510
1504
|
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1511
1505
|
await orchestrator.initialize();
|
|
1512
1506
|
// Should not throw
|
|
1513
1507
|
await orchestrator.start();
|
|
1514
1508
|
|
|
1515
|
-
expect(mockCapacitorInstance.
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
// Unit: Electron.run is fire-and-forget (does not block dev mode start)
|
|
1519
|
-
it("does not await Electron.run (fire-and-forget)", async () => {
|
|
1520
|
-
let electronRunResolved = false;
|
|
1521
|
-
mockElectronInstance.run.mockImplementation(() => {
|
|
1522
|
-
return new Promise<void>((resolve) => {
|
|
1523
|
-
// Simulate long-running Electron process — never resolves during test
|
|
1524
|
-
setTimeout(() => {
|
|
1525
|
-
electronRunResolved = true;
|
|
1526
|
-
resolve();
|
|
1527
|
-
}, 10_000);
|
|
1528
|
-
});
|
|
1529
|
-
});
|
|
1530
|
-
|
|
1531
|
-
setupDefaults(createConfig({
|
|
1532
|
-
packages: {
|
|
1533
|
-
"my-client": {
|
|
1534
|
-
target: "client",
|
|
1535
|
-
server: 4200,
|
|
1536
|
-
electron: { appId: "com.test.electron" },
|
|
1537
|
-
},
|
|
1538
|
-
},
|
|
1539
|
-
}));
|
|
1540
|
-
setupEngineWithPort(4200);
|
|
1541
|
-
|
|
1542
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1543
|
-
await orchestrator.initialize();
|
|
1544
|
-
await orchestrator.start();
|
|
1545
|
-
|
|
1546
|
-
// start() returned without waiting for Electron.run to resolve
|
|
1547
|
-
expect(electronRunResolved).toBe(false);
|
|
1548
|
-
expect(mockElectronInstance.run).toHaveBeenCalled();
|
|
1549
|
-
});
|
|
1550
|
-
|
|
1551
|
-
// Unit: DESIGN-004 — Electron run failure registers error in ResultCollector
|
|
1552
|
-
it("registers error in ResultCollector when Electron.run fails", async () => {
|
|
1553
|
-
mockElectronInstance.run.mockRejectedValue(new Error("electron crashed"));
|
|
1554
|
-
|
|
1555
|
-
setupDefaults(createConfig({
|
|
1556
|
-
packages: {
|
|
1557
|
-
"my-client": {
|
|
1558
|
-
target: "client",
|
|
1559
|
-
server: 4200,
|
|
1560
|
-
electron: { appId: "com.test.electron" },
|
|
1561
|
-
},
|
|
1562
|
-
},
|
|
1563
|
-
}));
|
|
1564
|
-
setupEngineWithPort(4200);
|
|
1565
|
-
|
|
1566
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1567
|
-
await orchestrator.initialize();
|
|
1568
|
-
await orchestrator.start();
|
|
1569
|
-
|
|
1570
|
-
// Wait a tick for the fire-and-forget async to settle
|
|
1571
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
1572
|
-
|
|
1573
|
-
const resultCollector = vi.mocked(ResultCollector).mock.instances[0];
|
|
1574
|
-
expect(resultCollector.add).toHaveBeenCalledWith(
|
|
1575
|
-
expect.objectContaining({
|
|
1576
|
-
name: "my-client",
|
|
1577
|
-
target: "client",
|
|
1578
|
-
type: "build",
|
|
1579
|
-
status: "error",
|
|
1580
|
-
message: expect.stringContaining("electron crashed"),
|
|
1581
|
-
}),
|
|
1582
|
-
);
|
|
1509
|
+
expect(mockCapacitorInstance.initialize).toHaveBeenCalled();
|
|
1510
|
+
expect(mockCapacitorInstance.run).not.toHaveBeenCalled();
|
|
1583
1511
|
});
|
|
1584
1512
|
});
|
|
1585
1513
|
|
|
@@ -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,32 @@ 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
|
-
});
|
|
265
|
-
|
|
266
|
-
// Unit: enforce: "post" 설정 확인 (D4)
|
|
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
256
|
});
|
|
277
257
|
|
|
278
|
-
//
|
|
279
|
-
it("sd-legacy-import-meta plugin replaces import.meta.url with module URL", async () => {
|
|
280
|
-
const config = await createClientViteConfig({
|
|
281
|
-
...createDefaultOptions(),
|
|
282
|
-
legacyModule: true,
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
const plugins = config.plugins as Array<{ name: string; enforce?: string; transform?: Function }>;
|
|
286
|
-
const legacyPlugin = plugins.find((p) => p.name === "sd-legacy-import-meta");
|
|
287
|
-
expect(legacyPlugin).toBeDefined();
|
|
288
|
-
|
|
289
|
-
const code = 'const url = import.meta.url;';
|
|
290
|
-
const id = "/packages/my-client/src/app.ts";
|
|
291
|
-
const result = legacyPlugin!.transform!(code, id);
|
|
258
|
+
// --- legacyModule esbuild.supported override (Feature 1.4) ---
|
|
292
259
|
|
|
293
|
-
|
|
294
|
-
|
|
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 () => {
|
|
260
|
+
// Acceptance: Scenario "legacyModule: true일 때 esbuild.supported에 import-meta/dynamic-import false 설정"
|
|
261
|
+
it("sets esbuild.supported to disable import-meta and dynamic-import when legacyModule is true", async () => {
|
|
300
262
|
const config = await createClientViteConfig({
|
|
301
263
|
...createDefaultOptions(),
|
|
302
264
|
legacyModule: true,
|
|
303
265
|
});
|
|
304
266
|
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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
|
+
"dynamic-import": false,
|
|
272
|
+
}),
|
|
273
|
+
);
|
|
332
274
|
});
|
|
333
275
|
|
|
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);
|
|
276
|
+
// Acceptance: Scenario "legacyModule 미설정 시 esbuild.supported 변경 없음"
|
|
277
|
+
it("does not set esbuild.supported when legacyModule is not specified", async () => {
|
|
278
|
+
const config = await createClientViteConfig(createDefaultOptions());
|
|
347
279
|
|
|
348
|
-
|
|
280
|
+
const esbuildOpts = config.esbuild as Record<string, unknown> | undefined;
|
|
281
|
+
expect(esbuildOpts?.["supported"]).toBeUndefined();
|
|
349
282
|
});
|
|
350
283
|
|
|
351
284
|
// --- PWA (Feature 5.2) ---
|
|
@@ -505,6 +438,127 @@ describe("createClientViteConfig", () => {
|
|
|
505
438
|
);
|
|
506
439
|
});
|
|
507
440
|
|
|
441
|
+
// --- watch option (Feature 1.2: legacy dev mode) ---
|
|
442
|
+
|
|
443
|
+
// Acceptance: Scenario "watch: true 시 build.watch 설정 및 emptyOutDir: false"
|
|
444
|
+
it("sets build.watch and emptyOutDir: false when watch is true in build mode", async () => {
|
|
445
|
+
const config = await createClientViteConfig({
|
|
446
|
+
...createDefaultOptions(),
|
|
447
|
+
mode: "build",
|
|
448
|
+
watch: true,
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
expect(config.build?.watch).toEqual({});
|
|
452
|
+
expect(config.build?.emptyOutDir).toBe(false);
|
|
453
|
+
expect(config.logLevel).toBeUndefined();
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Acceptance: Scenario "watch: true + replaceDeps 시 sdScopeWatchPlugin 포함"
|
|
457
|
+
it("includes sdScopeWatchPlugin when watch is true with replaceDeps in build mode", async () => {
|
|
458
|
+
const { sdScopeWatchPlugin } = await import("../../src/utils/vite-scope-watch-plugin");
|
|
459
|
+
|
|
460
|
+
const config = await createClientViteConfig({
|
|
461
|
+
...createDefaultOptions(),
|
|
462
|
+
mode: "build",
|
|
463
|
+
watch: true,
|
|
464
|
+
replaceDeps: [{ packageName: "@scope/core", sourcePath: "/packages/core" }],
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
const plugins = config.plugins as Array<{ name: string }>;
|
|
468
|
+
const scopePlugin = plugins.find((p) => p.name === "sd-scope-watch-plugin");
|
|
469
|
+
expect(scopePlugin).toBeDefined();
|
|
470
|
+
expect(sdScopeWatchPlugin).toHaveBeenCalled();
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
// Acceptance: Scenario "watch 미설정 시 기존 build 동작 유지"
|
|
474
|
+
it("sets emptyOutDir: true and logLevel: silent when watch is not set in build mode", async () => {
|
|
475
|
+
const config = await createClientViteConfig(createDefaultOptions());
|
|
476
|
+
|
|
477
|
+
expect(config.build?.emptyOutDir).toBe(true);
|
|
478
|
+
expect(config.logLevel).toBe("silent");
|
|
479
|
+
expect(config.build?.watch).toBeUndefined();
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
// Unit: watch: true without replaceDeps does not add sdScopeWatchPlugin
|
|
483
|
+
it("does not add sdScopeWatchPlugin in watch mode without replaceDeps", async () => {
|
|
484
|
+
const config = await createClientViteConfig({
|
|
485
|
+
...createDefaultOptions(),
|
|
486
|
+
mode: "build",
|
|
487
|
+
watch: true,
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
const plugins = config.plugins as Array<{ name: string }>;
|
|
491
|
+
const scopePlugin = plugins.find((p) => p.name === "sd-scope-watch-plugin");
|
|
492
|
+
expect(scopePlugin).toBeUndefined();
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
// Unit: watch: true still sets outDir
|
|
496
|
+
it("sets outDir in watch mode", async () => {
|
|
497
|
+
const config = await createClientViteConfig({
|
|
498
|
+
...createDefaultOptions(),
|
|
499
|
+
mode: "build",
|
|
500
|
+
watch: true,
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
expect(config.build?.outDir).toContain("my-client");
|
|
504
|
+
expect(config.build?.outDir).toMatch(/dist$/);
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
// --- exclude (Feature 1.1: vite-exclude-passthrough) ---
|
|
508
|
+
|
|
509
|
+
// Acceptance: Scenario "exclude에 패키지를 지정하면 pre-bundling에서 제외된다"
|
|
510
|
+
it("sets optimizeDeps.exclude when exclude is provided", async () => {
|
|
511
|
+
const config = await createClientViteConfig({
|
|
512
|
+
...createDefaultOptions(),
|
|
513
|
+
mode: "dev",
|
|
514
|
+
exclude: ["jeep-sqlite"],
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
expect(config.optimizeDeps?.exclude).toEqual(["jeep-sqlite"]);
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
// Acceptance: Scenario "exclude 미설정 시 기존 동작과 동일하다"
|
|
521
|
+
it("does not set optimizeDeps.exclude when exclude is not provided", async () => {
|
|
522
|
+
const config = await createClientViteConfig({
|
|
523
|
+
...createDefaultOptions(),
|
|
524
|
+
mode: "dev",
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
expect(config.optimizeDeps?.exclude).toBeUndefined();
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// Acceptance: Scenario "exclude와 replaceDeps가 모두 있으면 둘 다 제외된다"
|
|
531
|
+
it("sets optimizeDeps.exclude from exclude while sdScopeWatchPlugin handles replaceDeps", async () => {
|
|
532
|
+
const { sdScopeWatchPlugin } = await import("../../src/utils/vite-scope-watch-plugin");
|
|
533
|
+
|
|
534
|
+
const config = await createClientViteConfig({
|
|
535
|
+
...createDefaultOptions(),
|
|
536
|
+
mode: "dev",
|
|
537
|
+
exclude: ["jeep-sqlite"],
|
|
538
|
+
replaceDeps: [{ packageName: "@scope/core", sourcePath: "/packages/core" }],
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
// Base config에 exclude 설정
|
|
542
|
+
expect(config.optimizeDeps?.exclude).toEqual(["jeep-sqlite"]);
|
|
543
|
+
// sdScopeWatchPlugin도 호출됨 (replaceDeps용 exclude는 plugin이 처리)
|
|
544
|
+
expect(sdScopeWatchPlugin).toHaveBeenCalled();
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
// Acceptance: Scenario "exclude만 있고 replaceDeps가 없으면 exclude만 제외된다"
|
|
548
|
+
it("sets optimizeDeps.exclude from exclude when no replaceDeps", async () => {
|
|
549
|
+
const config = await createClientViteConfig({
|
|
550
|
+
...createDefaultOptions(),
|
|
551
|
+
mode: "dev",
|
|
552
|
+
exclude: ["jeep-sqlite"],
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
expect(config.optimizeDeps?.exclude).toEqual(["jeep-sqlite"]);
|
|
556
|
+
// sdScopeWatchPlugin은 호출되지 않음
|
|
557
|
+
const plugins = config.plugins as Array<{ name: string }>;
|
|
558
|
+
const scopePlugin = plugins.find((p) => p.name === "sd-scope-watch-plugin");
|
|
559
|
+
expect(scopePlugin).toBeUndefined();
|
|
560
|
+
});
|
|
561
|
+
|
|
508
562
|
// Acceptance: Scenario "pwa 필드 미설정 시 기본값"
|
|
509
563
|
it("uses default manifest values from pkgName when pwa is undefined", async () => {
|
|
510
564
|
await createClientViteConfig(createDefaultOptions());
|