Skip to main content

[Angular] Angular with MSW

MSW (Mock Service Worker) 是個模擬後端回傳 API 的工具,可以幫助開發者在前期資料結構尚未定義清楚、大幅變動的情況下,透過模擬 API 的方式協助開發。特別是在現在前後端分離為主流的環境中,前端可以透過 MSW 提升開發效率,在早期就可以模擬資料來完成畫面的互動與呈現。

安裝設置

將 msw 套件安裝在 devDependencies 之下,因為只有在開發時期會使用到

npm install msw@latest --save-dev

在 angular 專案之下,使用指令來新增 mockServiceWorker.js

npx msw init src

angular.json 之中,更新 architect -> build -> options 之中的 assets,這樣在開發跟打包時,都會夾帶此 js 檔

angular.json
"assets": [
"src/favicon.ico",
"src/assets",
"src/mockServiceWorker.js"
],

建立 mockAPI

在 src 之下建立 mocks 資料夾,去儲存我們要模擬的 API

src/mocks/browser.ts
import { http, HttpResponse } from 'msw';
import { setupWorker } from 'msw/browser';

export const handlers = [
http.get('http://localhost:4200/api/users', () => {
return HttpResponse.json(['thibe', 'steven', 'steventhibe'], {
status: 200,
});
}),
];

export const worker = setupWorker(...handlers);

再來是要注意的地方,就是匯入 worker 的時間點,以我目前測試的 Angular 16 版本的專案,我是在匯入 app.module.ts 啟動整個 app 之前匯入,這樣能確保所有 browser 的請求都會經過 MSW

src/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import './mocks/browser';
import { worker } from './mocks/browser';

worker.start().then(() => {
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
});

而在 worker.start() 之中,也可以帶入一些參數來去做調整

src/main.ts
worker
.start({
serviceWorker: {
// 在靜態網站時,有時候會需要將路徑指向 public 下打包出去的 js 檔案來去模擬資料
url: '/mockServiceWorker.js',
},
// 會跳過沒有被定義的請求,使 console 中不會出現警告
onUnhandledRequest: 'bypass',
})

實際測試

最後在 service 裡面寫入我們要使用的 API

getMockUsers(): Observable<string[]> {
return this.httpClient.get<string[]>('http://localhost:4200/api/users');
}

以及在任一 component.ts 進行呼叫 API 測試

this.userService
.getMockUsers()
.subscribe((users) => console.log({ users }));

會發現 console 出現 [MSW] Mocking enabled. 的字樣

msw_enabled

以及印出所有模擬的資料,那就大功告成了。

msw_mockusers

參考資料