Skip to content

Commit

Permalink
feat: serve frontend from a folder (#37)
Browse files Browse the repository at this point in the history
* feat: serve frontend from a folder

Closes #36

* ci: fix failing tests

* ci: fix tests on Windows
  • Loading branch information
manekinekko authored Dec 4, 2020
1 parent 1df0dd2 commit d1dba44
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 20 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "Azure Static Web Apps Emulator for Auth, API and static content",
"scripts": {
"release": "release-it --preRelease=alpha",
"pretest": "npm run build",
"test": "jest --detectOpenHandles --silent --verbose",
"build": "tsc",
"prebuild": "rm -fr dist",
Expand Down
34 changes: 26 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@ Using `npx`:
- 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:

```bash
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:

```bash
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:
Expand All @@ -79,8 +97,8 @@ 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:

| Tool | Port | Command |
| ---------------------------------------------------------------------------------- | ---- | -------------------------------------------- |
| Tool | Port | Command |
| ---------------------------------------------------------------------------------- | ---- | ------------------------------------- |
| [Angular](https://angular.io/cli) | 4200 | `swa --use-app=http://localhost:4200` |
| [Vue](https://cli.vuejs.org/) | 8080 | `swa --use-app=http://localhost:8080` |
| [Vite](https://github.com/vitejs/vite/) | 3000 | `swa --use-app=http://localhost:3000` |
Expand Down Expand Up @@ -127,12 +145,12 @@ If you need to override the default values, provide the following options:
The emulator supports local authentication flow and mocks the following providers:

| Provider | [Endpoint](https://docs.microsoft.com/azure/static-web-apps/authentication-authorization?WT.mc_id=javascript-0000-wachegha#login) | Local Emulation |
| -------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| GitHub | `.auth/login/github` ||
| Twitter | `.auth/login/twitter` ||
| Google | `.auth/login/google` ||
| Facebook | `.auth/login/facbook` ||
| AAD | `.auth/login/aad` ||
| -------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| 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:

Expand Down
2 changes: 1 addition & 1 deletion src/auth/routes/identity_auth_login_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const httpTrigger = async function (context: Context, req: ServerRequest) {

switch (provider) {
case "github":
client_id = process.env.GITHUB_CLIENT_ID || client_id;
client_id = process.env.GITHUB_CLIENT_ID || "";

//**** GITHUB NOTICE: start */
if (!client_id) {
Expand Down
13 changes: 9 additions & 4 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const APP_PORT = 4200;

program
.name("swa")
.usage("<command>")
.usage("[options] <command>")
.version(require("../package.json").version)

// SWA config
Expand Down Expand Up @@ -59,8 +59,13 @@ let [appLocation, appArtifactLocation, apiLocation] = [
program.apiLocation as string,
];

// if the user provides an app folder, use it as an app artifact location
if (program.args.length) {
appLocation = program.args[0];
}

// retrieve the project's build configuration
// provide any specific config that the user might provide
// use any specific config that the user might provide
const configFile = readConfigFile({
overrideConfig: {
appLocation,
Expand Down Expand Up @@ -117,7 +122,7 @@ const { command: hostCommand, args: hostArgs } = createRuntimeHost({
appArtifactLocation: configFile?.appArtifactLocation,
});

let serveApiContent = `[ -d '${apiLocation}' ] && (cd ${apiLocation}; func start --cors *) || echo 'No API found. Skipping.'`;
let serveApiContent = `([ -d '${configFile?.apiLocation}' ] && (cd ${configFile?.apiLocation}; func start --cors *)) || echo 'No API found. Skipping.'`;
if (program.useApi) {
serveApiContent = `echo 'using API dev server at ${program.useApi}'`;
}
Expand Down Expand Up @@ -150,7 +155,7 @@ const startCommand = [
];

if (process.env.DEBUG) {
shell.echo(startCommand.join("\n"));
console.log({startCommand})
}

if (program.build) {
Expand Down
11 changes: 6 additions & 5 deletions src/runtimeHost.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from "path";
import { createRuntimeHost } from "./runtimeHost";
import * as detectRuntime from "./runtimes";

Expand Down Expand Up @@ -25,7 +26,7 @@ describe("runtimeHost", () => {
});

expect(spyDetectRuntime).toHaveBeenCalledWith("./");
expect(rh.command).toContain("@manekinekko/swa-emulator/node_modules/.bin/http-server");
expect(rh.command).toContain(path.join("swa-emulator", "node_modules", ".bin", "http-server"));
expect(rh.args).toEqual(["./foobar", "--port", "8080", "--cache", "-1", "--proxy", "http://0.0.0.0:4242/?"]);
});

Expand All @@ -36,7 +37,7 @@ describe("runtimeHost", () => {
});

expect(spyDetectRuntime).toHaveBeenCalledWith("./");
expect(rh.command).toContain("@manekinekko/swa-emulator/node_modules/.bin/http-server");
expect(rh.command).toContain(path.join("swa-emulator", "node_modules", ".bin", "http-server"));
expect(rh.args).toEqual(["./", "--port", "8080", "--cache", "-1", "--proxy", "http://0.0.0.0:4242/?"]);
});

Expand All @@ -47,7 +48,7 @@ describe("runtimeHost", () => {
});

expect(spyDetectRuntime).toHaveBeenCalledWith("./");
expect(rh.command).toContain("@manekinekko/swa-emulator/node_modules/.bin/http-server");
expect(rh.command).toContain(path.join("swa-emulator", "node_modules", ".bin", "http-server"));
expect(rh.args).toEqual(["./", "--port", "8080", "--cache", "-1", "--proxy", "http://127.0.0.1:4242/?"]);
});

Expand All @@ -58,7 +59,7 @@ describe("runtimeHost", () => {
});

expect(spyDetectRuntime).toHaveBeenCalledWith("./");
expect(rh.command).toContain("@manekinekko/swa-emulator/node_modules/.bin/http-server");
expect(rh.command).toContain(path.join("swa-emulator", "node_modules", ".bin", "http-server"));
expect(rh.args).toEqual(["./", "--port", "8080", "--cache", "-1", "--proxy", "http://0.0.0.0:3000/?"]);
});

Expand All @@ -69,7 +70,7 @@ describe("runtimeHost", () => {
});

expect(spyDetectRuntime).toHaveBeenCalledWith("./foobar");
expect(rh.command).toContain("@manekinekko/swa-emulator/node_modules/.bin/http-server");
expect(rh.command).toContain(path.join("swa-emulator", "node_modules", ".bin", "http-server"));
expect(rh.args).toEqual(["./", "--port", "8080", "--cache", "-1", "--proxy", "http://0.0.0.0:4242/?"]);
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/runtimes.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import mockFs from "mock-fs";
import { detectRuntime, RuntimeType } from "./runtimes";

const appLocation = "/tmp";
const appLocation = "./tmp-swa-emulator";
describe("runtime", () => {
afterEach(() => {
mockFs.restore();
Expand Down
6 changes: 5 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ export const readConfigFile = ({ overrideConfig }: { overrideConfig?: Partial<Gi

if (fs.existsSync(githubActionFolder) === false) {
console.warn(warningMessage);
return overrideConfig;
return {
appLocation: path.normalize(path.join(process.cwd(), overrideConfig?.appLocation || `.${path.sep}`)),
apiLocation: path.normalize(path.join(process.cwd(), overrideConfig?.apiLocation || `${path.sep}api`)),
appArtifactLocation: path.normalize(path.join(process.cwd(), overrideConfig?.appArtifactLocation || `.${path.sep}`)),
};
}

// find the SWA GitHub action file
Expand Down

0 comments on commit d1dba44

Please sign in to comment.