Skip to content

Commit

Permalink
feat: support async listener
Browse files Browse the repository at this point in the history
  • Loading branch information
dongwa committed Aug 11, 2023
1 parent 70bced9 commit b58ec52
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 63 deletions.
39 changes: 18 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
# vercel-quasar

Vercel builder for Quasar with SSR enabled

Help you to deploy [Quasar](https://quasar.dev) application on [Vercel](https://vercel.com) in SSR mode

# usage

## 1. change the listen function in your `src-ssr/server.js` file
- remove all async and await. It is important,making sure the listen function will not return the content of the asynchronous

- return { handler: ssrHandler }
- example
![server.js.example.ng](https://raw.githubusercontent.com/dongwa/vercel-quasar/master/imgs/server.js.example.png)

``` js
```js
/**
* You need to make the server listen to the indicated port
* and return the listening instance or whatever you need to
* close the server with.
*
* The "listenResult" param for the "close()" definition below
* is what you return here.
*
* For production, you can instead export your
* handler for serverless use or whatever else fits your needs.
*/
export function listen({ app, port, isReady, ssrHandler }) {
export async function listen({ app, port, isReady, ssrHandler }) {
if (process.env.DEV) {
await isReady();
return app.listen(port, () => {
return await app.listen(port, () => {
if (process.env.PROD) {
console.log('Server listening at port ' + port);
}
Expand All @@ -41,9 +37,10 @@ export function listen({ app, port, isReady, ssrHandler }) {
}
```


## 2. Configure `vercel-quasar` as builder in `vercel.json`

### Add a `vercel.json` file to your project root path

```json
{
"version": 2,
Expand All @@ -54,14 +51,18 @@ export function listen({ app, port, isReady, ssrHandler }) {
}
]
}

```

## 3. Custom build command

### The default build command is `npx quasar build -m ssr`,if you want to use custom it,add a `build:ssr` or `build` script to your package.json

> Note that the priority of `build:ssr` is higher than that of `build`. If `build:ssr` exists, command `build` will not be executed in deploy.
- example
###
- example

###

```json
{
"name": "quasar-example",
Expand All @@ -70,13 +71,9 @@ export function listen({ app, port, isReady, ssrHandler }) {
"scripts": {
"dev": "quasar dev",
"dev:ssr": "quasar dev -m ssr",
"build:ssr":"node build/index.js && quasar build -m ssr",
},
"dependencies": {

},
"devDependencies": {

"build:ssr": "node build/index.js && quasar build -m ssr"
},
"dependencies": {},
"devDependencies": {}
}
```
99 changes: 57 additions & 42 deletions src/launcher.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,67 @@
import path from 'path';
import { Server } from 'http';

// Create bridge and start listening
const { Server } = require('http') as typeof import('http');
const { Bridge } =
require('./vercel__bridge.js') as typeof import('@vercel/node-bridge/bridge');
let listener: any;

try {
process.chdir(__dirname);
if (!process.env.NODE_ENV) process.env.NODE_ENV = 'production';
if (process.env.DEV) {
console.log('err dev mode,auto change to prod');
throw new Error('process.env.DEV is true');
}
async function createLauncher(event: any, context: any) {
//@ts-ignore
const { Bridge } = (await import('./vercel__bridge.js'))
.default as typeof import('@vercel/node-bridge/bridge');

listener = require(path.join(__dirname, 'index.js'));
if (listener.default) listener = listener.default;
if (typeof listener !== 'function' && listener.handler)
listener = listener.handler;
if (typeof listener?.then === 'function') {
listener.then((res: any) => {
listener = res;
});
} else {
const listenerType = typeof listener;
const oldListener = listener;
console.log('listener:', typeof listener, listener);
if (typeof listener !== 'function') {
listener = (req: any, res: any) => {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.write(`This is vercel-quasar, your Vercel builder. Turns out we couldn't find your server instance. Did you write \`module.exports = app\`?
typeof: ${listenerType} (expected 'function')
String: ${String(oldListener)}
Read the docs or create an issue: https://github.com/dongwa/vercel-quasar`);
res.end();
};
try {
process.chdir(__dirname);
if (!process.env.NODE_ENV) process.env.NODE_ENV = 'production';
if (process.env.DEV) {
console.log('err dev mode,auto change to prod');
throw new Error('process.env.DEV is true');
}
}
} catch (error) {
console.error('Server is not listening', error);
process.exit(1);
}

const server = new Server(listener);
const quasarServerModule = (await import(path.join(__dirname, 'index.js')))
.default;

listener = quasarServerModule;
if (listener.default) listener = listener.default;
if (typeof listener?.then === 'function') listener = await listener;
if (typeof listener !== 'function' && listener.handler)
listener = listener.handler;
else {
const listenerType = typeof listener;
const oldListener = listener;
if (typeof listener !== 'function') {
listener = (req: any, res: any) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write(`This is vercel-quasar, your Vercel builder. Turns out we couldn't find your server instance. Did you write \`module.exports = app\`?
typeof: ${listenerType} (expected 'function')
String: ${String(oldListener)}
Read the docs or create an issue: https://github.com/dongwa/vercel-quasar`);
res.end();
};
}
}

const bridge = new Bridge(server);
bridge.listen();
const server = new Server(listener);

const bridge = new Bridge(server);
bridge.listen();
return bridge.launcher(event, context);
} catch (error) {
console.error('Server is not listening', error);
listener = (req: any, res: any) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write(`This is vercel-quasar, your Vercel builder.
${error}
Read the docs or create an issue: https://github.com/dongwa/vercel-quasar`);
res.end();
};
const server = new Server(listener);

const bridge = new Bridge(server);
bridge.listen();
return bridge.launcher(event, context);
}
}

export const launcher: typeof bridge.launcher = bridge.launcher;
export const launcher = createLauncher;

0 comments on commit b58ec52

Please sign in to comment.