Skip to content

Commit

Permalink
✨ Add the server main features.
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieutu committed Oct 6, 2018
1 parent d15ec62 commit 32d3800
Show file tree
Hide file tree
Showing 26 changed files with 8,475 additions and 35 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
templates/
17 changes: 17 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = {
// Use only this configuration
root: true,
// Environment global objects
env: {
es6: true,
jest: true,
},
extends: [
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
'standard',
],
rules: {
'comma-dangle': ['error', 'always-multiline'],
'semi': ['error', 'always'],
},
};
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/

.tmp*
6 changes: 6 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
.eslintignore
.eslintrc.js
yarn.lock
logo.psd
src/**/.tmp*
67 changes: 32 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# vue-cli-plugin-apollo
# vue-cli-plugin-express

[![npm](https://img.shields.io/npm/v/vue-cli-plugin-express.svg) ![npm](https://img.shields.io/npm/dm/vue-cli-plugin-express.svg)](https://www.npmjs.com/package/vue-cli-plugin-express)
[![npm](https://img.shields.io/npm/v/vue-cli-plugin-express.svg) ![npm](https://img.shields.io/npm/dt/vue-cli-plugin-express.svg)](https://www.npmjs.com/package/vue-cli-plugin-express)
[![vue-cli3](https://img.shields.io/badge/vue--cli-3.x-brightgreen.svg)](https://github.com/vuejs/vue-cli)

**:rocket: Add an API in your Vue application in 2 minutes!**
Expand All @@ -9,30 +9,24 @@ This is a vue-cli 3.x plugin to add an Node Express server in your Vue project.

<br>

![screenshot](./screenshot.png)

<br>

**:star: Features:**

- Included fully customizable Express Server:
- You just have to add your api routes into your project (with import/export support)
- Optional and customisable automatic fallback to the Vue app, to serve both the api and the application with only one command.
- Just add your api routes into your project (with import/export support) without thinking to something else.
- Optional automatic fallback to the Vue app, to serve both the api and the application with only one command.
- (soon) Included optional example routes and components.

## Table of contents

- [Getting started](#getting-started)
- [Usage](#usage)
- [Usage](#usage)
- [Injected Commands](#injected-commands)
- [Configuration](#configuration)
- [Client state](#client-state)
- [Authorization Header](#authorization-header)
- [Plugin options](#plugin-options)
- [Mocks](#mocks)
- [Directives](#directives)
- [Apollo Engine](#apollo-engine)
- [Express middlewares](#express-middlewares)
- [Env variables](#env-variables)
- [Injected webpack-chain Rules](#injected-webpack-chain-rules)
- [Running the GraphQL server in production](#running-the-graphql-server-in-production)
- [Manual code changes](#manual-code-changes)
- [Use your app in production](#use-your-app-in-production)

---

Expand All @@ -56,26 +50,31 @@ Navigate to the newly created project folder and add the cli plugin:
cd my-new-app
vue add express
```

Soon:
*:information_source: An example `APIExample.vue` component will be added into your sources if you chose to include the examples.*

### Usage
## Usage

To start your application for development purpose, use theses commands:
To start your server for development purpose, use this commands:

```
yarn run express:watch
yarn serve
yarn express:watch
```

The server will be automatically restarted when a change is detected.

To run the server only once, use this command:
You just then have to start the app:

```
yarn serve
```

To run the server only once for production use, run:
```
yarn run express:run
yarn express:run
```

**Updating `vue-cli-plugin-express` will update the Express Server service :+1:**
**Updating `vue-cli-plugin-express` will update the Express server service :+1:**

## Injected Commands

Expand All @@ -89,35 +88,33 @@ yarn run express:run

## Configuration

### Plugin options

The Express Server can be configured via the `pluginOptions` in `vue.config.js`:

``` js
```js
module.exports = {
// Other options...
pluginOptions: {
// Express-related options
express: {
// TODO
shouldServeApp: true,
serverDir: './srv',
},
},
},
}
```

## Running the Express server in production

### Production app

```
cross-env NODE_ENV=production yarn run express:run --mode production
## Use your app in production
```bash
yarn build
yarn express:run
```

Example in your package.json, for most of hosting services:
```json
{
"scripts": {
"start": "cross-env NODE_ENV=production yarn run express:run --mode production"
"start": "yarn express:run"
}
}
```
1 change: 1 addition & 0 deletions generator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./src/generator');
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// eslint-disable-next-line no-global-assign
require = require('esm')(module);

module.exports = require('./src/servicePlugin');
Binary file added logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added logo.psd
Binary file not shown.
28 changes: 28 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
"name": "vue-cli-plugin-express",
"version": "0.0.1",
"description": "vue-cli 3 plugin to add an Express Api",
"main": "index.js",
"scripts": {
"prepublishOnly": "npm run test ",
"test": "npm run test:eslint",
"test:eslint": "eslint --ext .js ."
},
"repository": {
"type": "git",
"url": "git+https://github.com/mathieutu/vue-cli-plugin-express.git"
Expand All @@ -18,7 +24,29 @@
"url": "https://github.com/mathieutu/vue-cli-plugin-express/issues"
},
"homepage": "https://github.com/mathieutu/vue-cli-plugin-express#readme",
"dependencies": {
"chalk": "^2.4.1",
"cli-table": "^0.3.1",
"connect-history-api-fallback": "^1.5.0",
"esm": "^3.0.84",
"express": "^4.16.3",
"express-list-endpoints": "^3.0.1",
"nodemon": "^1.18.4",
"portfinder": "^1.0.17",
"ts-node": "^7.0.1"
},
"devDependencies": {
"@vue/cli-service": "^3.0.0",
"@vue/cli-shared-utils": "^3.0.0",
"eslint": "^4.10.0",
"eslint-config-standard": "^10.2.1",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-node": "^6.0.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1"
},
"peerDependencies": {
"@vue/cli-service": "^3.0.0",
"@vue/cli-shared-utils": "^3.0.0"
}
}
1 change: 1 addition & 0 deletions prompts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./src/prompts');
Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const serverDir = './srv';

export const commandOptionsDefaults = {
delay: false,
host: '0.0.0.0',
port: 3000,
https: false,
};

export const commandOptionsDoc = {
'--delay': `delays run by a small duration (default: ${commandOptionsDefaults.delay})`,
'--host': `specify host (default: ${commandOptionsDefaults.host})`,
'--port': `specify port (default: ${commandOptionsDefaults.port})`,
'--https': `use https (default: ${commandOptionsDefaults.https})`,
};

export const shouldServeApp = true;

export default {
serverDir,
commandOptionsDefaults,
commandOptionsDoc,
shouldServeApp,
};
22 changes: 22 additions & 0 deletions src/generator/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = (api, options, rootOptions) => {
api.extendPackage({
scripts: {
'express': 'vue-cli-service express:watch',
'express:run': 'vue-cli-service express:run',
},
vue: {
pluginOptions: {
express: {
shouldServeApp: options.shouldServeApp,
serverDir: options.serverDir,
},
},
},
});

api.render('./templates/srv');

if (options.addExamples) {
// TODO
}
};
13 changes: 13 additions & 0 deletions src/generator/templates/srv/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import express from 'express';

export default app => {
app.use(express.json());

app.get('/foo', (req, res) => {
res.json({msg: 'foo'});
});

app.post('/bar', (req, res) => {
res.json(req.body);
});
}
18 changes: 18 additions & 0 deletions src/prompts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { serverDir, shouldServeApp } = require('../config');

module.exports = [
{
type: 'confirm',
name: 'shouldServeApp',
message: `Should serve vue app? (default: ${shouldServeApp})`,
description: 'This will allow you to serve the vue app via the express server. So only one server for the app and the api.',
default: shouldServeApp,
},
{
type: 'input',
name: 'serverDir',
message: `Where will be located your server? (default: "${serverDir}")`,
description: 'The location of your server code, relative to the root of your project.',
default: serverDir,
},
];
37 changes: 37 additions & 0 deletions src/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import express from 'express';
import { load } from './utils/misc';
import listEndpoints from 'express-list-endpoints';

import history from 'connect-history-api-fallback';

export default ({
port,
srvPath,
distPath,
hasTypescript,
shouldServeApp,
isInProduction,
}) => {
return new Promise((resolve, reject) => {
const app = express();

if (hasTypescript) {
require('ts-node/register/transpile-only');
}

load(srvPath)(app);

if (isInProduction && shouldServeApp) {
app.use(history());
app.use(express.static(distPath));
}

app.listen(port, err => {
if (err) {
reject(err);
} else {
resolve(listEndpoints(app));
}
});
});
};
63 changes: 63 additions & 0 deletions src/servicePlugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import config from '../config';
import serveCommand from './serveCommand';
import runCommand from './runCommand';
import webpackConfig from './webpackConfig';

module.exports = (api, options) => {
const expressOptions = (options.pluginOptions && options.pluginOptions.express) || {};
const shouldServeApp = expressOptions.shouldServeApp || config.shouldServeApp;
const isInProduction = process.env.NODE_ENV === 'production';
const srvPath = api.resolve(expressOptions.serverDir || config.serverDir);
const distPath = api.resolve(options.outputDir);
const hasTypescript = api.hasPlugin('typescript') || expressOptions.hasTypescript;

if (shouldServeApp && !isInProduction) {
addServerUrlToWebpackProxy(api);
}

registerServeCommand(api, { srvPath });

registerRunCommand(api, {
defaultOptions: config.commandOptionsDefaults,
srvPath,
shouldServeApp,
isInProduction,
distPath,
hasTypescript,
});
};

module.exports.defaultModes = {
'express:watch': 'development',
'express:run': 'production',
};

function registerServeCommand (api, options) {
api.registerCommand(
'express:watch',
{
description: 'Run the Express server and watch the sources to restart automatically',
usage: 'vue-cli-service express:watch [options]',
options: config.commandOptionsDoc,
details: 'For more info, see https://github.com/mathieutu/vue-cli-plugin-express',
},
serveCommand(options),
);
}

function registerRunCommand (api, options) {
api.registerCommand(
'express:run',
{
description: 'Run the Express server',
usage: 'vue-cli-service express:run [options]',
options: config.commandOptionsDoc,
details: 'For more info, see https://github.com/mathieutu/vue-cli-plugin-express',
},
runCommand(options),
);
}

function addServerUrlToWebpackProxy (api) {
api.chainWebpack(webpackConfig);
}
Loading

0 comments on commit 32d3800

Please sign in to comment.