0.0.1-alpha.7 • Published 3 years ago

@manekinekko/swa-emu v0.0.1-alpha.7

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

Introducing SWA EMU, the Azure Static Web Apps Emulator that serves as a local emulator for Azure Static Web Apps. It can:

  • Auto-build your local APP and API
  • Emulate Authentication
  • Serve API requests
  • Serve static APP assets

High-level architecture

swa emulator architecture

The SWA EMU is built on top of the following components:

  • The Reverse Proxy: this is the heart of the SWA EMU, it's the piece that forwards all HTTP requests to the appropriate components:
    • /.auth/** requests are forwarded to the Auth Emulator server.
    • /api/** requests are forwarded to the localhost API function (if available).
    • /** all other requests are forwarded to the static assets server (serving the front-end app).
  • The Auth Emulator server: emulates the whole authentication flow.
  • The Static content server: serves the local app static content.
  • The Serverless API server (baked by the Azure Function App).

Before SWA EMU bootstraps, it also can read (using the --build options) the local SWA github workflow file (created by Azure Static Web Apps) and builds both the static app and the api according to the user's config. And pretty much like SWA, if the user isn't using an API, SWA EMU will skip the API build.

Authentication emulation flow

The Authentication flow is illustrated in the following sequence diagram (or open in a new tab):

SWA Auth flow diagram

Disclaimer

SWA EMU is still in developer preview and not yet ready for prime time. You will encounter issues, so please report them or help us fix them. Your contributions will be very appreciated 🙏

Quick start

Using npm or yarn:

  • Install the emulator: npm install -g @manekinekko/swa-emu@latest
  • Open a SWA app folder at the root (outside any /api or /app folders): cd my-awesome-swa-app
  • Start the emulator: swa
  • Access your SWA app from http://localhost

Using npx:

  • Open a SWA app folder at the root (outside any /api or /app folders): cd my-awesome-swa-app
  • Start the emulator: npx @manekinekko/swa-emu@latest
  • Access your SWA app from http://localhost

Start the emulator from a specific folder

By default, SWA EMU will start from the current directory ./. But if you have multiple SWA projects, you can start SWA EMU with a specific folder, and the emulator will use that folder as the app_location.

If your SWA project is under ./my-app, then run the SWA EMU and provide that folder:

swa ./my-app

Please also note, that running swa ./my-app is equivalent to swa --app-location=./my-app.

In case the SWA EMU cannot determine the right frontend application artifact (dist) folder to serve, you can override this configuration by providing the --app-artifact-location flag:

swa ./my-app --app-artifact-location ./my-app/dist/

Use with a local API dev server

When developing locally on your back-end application, it might be useful to use your local API dev server, to serve your API content and benefit from the built-in features like debugging. In order to use SWA EMU with your local API dev server, follow these two steps:

  1. Start your local API dev server (as usual). For example: func start host.
  2. Run swa with the --use-api flag of the URI provided by the API dev server, in the following format:
swa --use-api=http://<api-dev-server-host>:<api-dev-server-port>

Use with a local APP dev server

When developing locally on your front-end application, it might be useful to use your local application dev server, that comes with your application CLI, to serve your app content and benefit from the built-in feature like the livereload or HMR (hot module reload) features.

In order to use SWA EMU with your local dev server, follow these two steps:

  1. Start your local dev server (as usual). For example: ng serve
  2. Run swa with the --use-app flag of the URI provided by the dev server, in the following format:
swa --use-app=http://<app-dev-server-host>:<app-dev-server-port>

Here is a list of the default ports used by popular dev servers:

ToolPortCommand
Angular4200swa --use-app=http://localhost:4200
Vue8080swa --use-app=http://localhost:8080
Vite3000swa --use-app=http://localhost:3000
Create React App3000swa --use-app=http://localhost:3000
Webpack Dev Server8080swa --use-app=http://localhost:8080
Parcel1234swa --use-app=http://localhost:1234
Stencil3333swa --use-app=http://localhost:3333
Hugo1313swa --use-app=http://localhost:1313
Elm (live server)8000swa --use-app=http://localhost:8000
Ionic8100swa --use-app=http://localhost:8100
Svelte (sirv-cli)5000swa --use-app=http://localhost:5000
Sapper3000swa --use-app=http://localhost:3000
Scully.io1668swa --use-app=http://localhost:1668
Gatsby8000swa --use-app=http://localhost:8000
Nuxt.js3000swa --use-app=http://localhost:3000
Next.js3000swa --use-app=http://localhost:3000

Configuration

SWA EMU binds to these default hosts:

  • http://localhost:4242: for emulated authentication.
  • http://localhost:7071: for the API (baked by the Azure Function App)
  • http://localhost:4200: for app assets (the front-end app)

If you need to override the default values, provide the following options:

OptionsDescriptionDefaultExample
--api-prefixthe API URL prefixapiswa --api=prefix=my-api-route
--auth-urithe Auth URIhttp://localhost:4242swa --auth-uri=http://localhost:8083
--api-urithe API URIhttp://localhost:7071swa --api-uri=http://localhost:8082
--app-urithe app URIhttp://localhost:4200swa --app-uri=http://localhost:8081
--use-appuse the app dev servernullswa --use-app=http://localhost:8080
--use-apiuse the api dev servernullswa --use-api=http://localhost:3000
--hostthe emulator host address0.0.0.0swa --host=192.168.68.80
--portthe emulator port value80swa --port=8080
--buildbuild the api and app before startingfalseswa --build
--verboseenable debug logsfalseswa --verbose
--uienable dashboard UIfalseswa --ui

Local Emulation

The emulator supports local authentication flow and mocks the following providers:

ProviderEndpointLocal Emulation
GitHub.auth/login/github
Twitter.auth/login/twitter
Google.auth/login/google
Facebook.auth/login/facbook
AAD.auth/login/aad

When requesting the .auth/me endpoint, a mocked user clientPrincipal will be returned by the emulator. Here is an example:

{
  "clientPrincipal": {
    "identityProvider": "twitter",
    "userId": "59cd31faa8c34919ac22c19af50482b8",
    "userDetails": "manekinekko",
    "userRoles": ["anonymous", "authenticated"]
  }
}

NOTE: user roles and ACL are not fully supported (see #7).

Caveats

  • Custom routes are not yet supported (see #6)
  • Authorization and roles are not fully supported (see #7).
  • The emulator is serving all traffic over HTTP (HTTPS support will be added soon) (see #4).
  • When using GitHub, the OAuth client ID and client secret are provided as-is for dev purposes ONLY. You should create your own OAuth GitHub app!

Troubleshooting

Port 4242 is unavailable

This means that there is already an instance of Azure Functions Core Tools (assigned to the Auth Emulator) that is running and bound to the default port 4242.

To fix it, either:

  • close the other running instance, and run the emulator again.
  • run the emulator using a different port: --auth-uri=http://localhost:4243
  • force close the other instance by killing its processes: lsof -t -i tcp:4242 | xargs kill

Error: listen EADDRINUSE: address already in use 0.0.0.0:80

This error indicates that another app is running and bound to the default port of the emulator: 80.

To fix it, either:

  • close the other running instance, and run the emulator again.
  • run the emulator using a different port: --port=8081
  • force close the other instance by killing its processes: lsof -t -i tcp:80 | xargs kill

Want to help? contributions welcome

Want to file a bug, contribute some code, or improve the documentation? Excellent! Read up on our guidelines for contributing and then check out one of our issues in the list: community-help.