The package is a Express.js CLI to initialize your Express Project interactively with info, log4js, database and so on.
Change language: 中文文档 | English Doc
Latest 5 versions reports:
v1.2.2
- New feature:
SET PORT=<port number>
beforenpm start
is supported
v1.2.1
- fix config init bug
- update
show
command
v1.2.0
- support TypeScript
- provide zod template
v1.1.1
- provide websocket template
v1.1.0
- refactor exhandler and support exception classification
- refactor Resp structure
Install CLI to local directory
npm i evp-express-cli
Or install to global environment
npm i evp-express-cli -g
Here are some examples.
evp-express
:
-v
,--version
: show version-i
,--info
: show information-h
,--help
: display help for commandnew <projectName>
: create a new Express.js project with the specified namestart
: start and lauch the project dev server.clean <path>
: clean up all files in this path if exists.add <template>
: add certain template or devtool.
Directly with npx from npm repository :
npx evp-express-cli new <projectName>
Cli locally installed:
npx evp-express new <projectName>
Cli globally installed:
evp-express new <projectName>
Change directory to your project's root directory, and start running the server with: Cli locally installed:
npx evp-express start
Cli globally installed:
evp-express start
Or just start with npm script:
npm run start
Or start with node directly:
node index
validator middleware is at /midwares/valider.js
It exports these midware functions:
module.exports = {
validator,
ValidRace,
ValidAll,
ValidQueue,
ValidQueueAll
}
- validator is package of "express-validator".
- ValidRace is to valid chains concurrently and throws the fastest one.
- ValidAll is to valid chains concurrently and throws all result.
- ValidQueue is to valid chains sequentially and throws the first one.
- ValidQueueAll is to valid chains sequentially and throws all result.
example:
const { validator, ValidQueue } = require('../midwares/valider');
router.get('/',
ValidQueue([
validator.query('name').trim().notEmpty().withMessage("name cannot be empty"),
validator.query('age').trim()
.notEmpty().withMessage("age cannot be empty").bail()
.isInt().withMessage("age must be Int").bail().toInt()
]),
(req, res, next) => {
res.send(`Hello ${req.query.name}, you are ${req.query.age} years old!`);
});
And you will get response like this:
{
"code":500,
"msg":"name cannot be empty",
"data":null,
"symbol":-1,
"type":"Bad Request"
}
The Zod template is another validator, you can use both the Zod and Validator. Template provide a midware factory, allow you to check headers
, body
, query
, params
,and you can use it like this:
const { Router } = require('express');
const logger = require('../utils/logger');
const Resp = require('../model/resp');
const { ZodValid } = require('../midwares/zod');
const { z } = require('zod');
const { Json } = require('../midwares/bodyParser');
const router = Router();
router.get('/', ZodValid({
query: z.object({ name: z.string().nonempty("name cannot be empty") })
}), async (req, res, next) => {
const name = req.query.name;
logger.info(`Hello World! ${name}`);
res.json(Resp.ok(`Hello World! ${name}`, 1, null));
});
router.post('/', Json, ZodValid({
body: z.object({
name: z.string().nonempty("name cannot be empty").min(8, "name at least 8 length"),
pass: z.string().nonempty("password cannot be empty").min(8, "password at least 8 lenght"),
email: z.string().email("email is invalid") })
}), async (req, res, next) => {
const name = req.body.name;
logger.info(`Hello World! ${name}`);
res.json(Resp.ok(`Hello World! ${name}`, 1, null));
});
module.exports = router;
The Database Template use mysql as default datasource mysql2 as default mysql driver and knex.js as default sqlClient.
You can require the knex-sqlClient by const { sqlClient } = require('utils/knex');
.
You can change to use any other database, driver and sqlClient. But I strongly suggest you not to delete the utils/knex
because this framework uses it to init the database.
More about its configuration can be found in config.yaml.
The Redis Template depends on redis.js and does not with auth, if you need it, you can modify the utils/redisProxy
.
You can require the redisProxy by const { instance } = require('utils/redisProxy');
. You can use instance.client
to get the redis client instance.
More about its configuration can be found in config.yaml.
The Auth Template only installs the package passport.js and you should customize it by yourself.
The RabbitMQ Template depends on ampqlb.js and use "guest:guest" as default user.
You can require the future rabbitmqProxy by const { instance } = require('utils/rabbitmqProxy');
. You can use instance.conn
to get the RabbitMQ connection.You can use instance.channel
to get the default channel of RabbitMQ connection.
Notice that it is a promise, when imported anywhere else please await in async funtion or then-flow to initialize a var of its instance.
const { instance } = require('../utils/rabbitmqProxy');
app.get('/', async(req, res)=>{
const rbmqProxy = await instance;
const { channel: rbmq } = rbmqProxy;
rbmq.sendToQueue("queue", "hello");
})
Or like this:
const RabbitmqProxy = require('../utils/rabbitmqProxy');
app.get('/', async(req, res)=>{
const rbmqProxy = await RabbitmqProxy.instance;
const { channel: rbmq } = rbmqProxy;
rbmq.sendToQueue("queue", "hello");
})
Or like this:
const amqplib = require('amqplib');
const RabbitmqProxy = require('../utils/rabbitmqProxy');
//@type {amqplib.Channel}
let rbmq = null;
RabbitmqProxy.instance.then(rabbitmq=>{
rbmq = rabbitmq.channel;
})
app.get('/', async(req, res)=>{
rbmq.sendToQueue("queue", "hello");
})
More about its configuration can be found in config.yaml.
The Websocket Template ws.js and mounts Websocket Server on express-http-server.
Your can require wsProxy by const { instance } = require('utils/wsProxy');
. You can use instance.server
to get Websocket Server instance。
Warning: Do not use WebSocket Template and SocketIO Template together.
The SocketIO Template depends on socket.io and mounts SockerIO Server on express-http-server.
You can require the socketioProxy by const { instance } = require('utils/socketioProxy');
. You can use instance.server
to get the SocketIO Server instance.
More about its configuration can be found in config.yaml.
The Nacos Template depends on nacos.js and use your project's package.json's name as service name.
You can require the nacosClient by const { instance } = require('utils/nacosProxy');
. You can use instance.client
to get the Nacos Client instance.
More about its configuration can be found in config.yaml.
The Babel DevTool only installs basic dependencies and creates a basic babel.config.js file.
You should customize babel more by yourself.
The Eslint DevTool only installs basic dependencies.
You should customize it more by yourself.
The Jest DevTool only installs basic dependencies and creates a basic jest.config.js file. Besides, the package.json's scripts.test
is replaced with "jest", you can quickly test by jest with command "npm test".
You can customize jest more by yourself.
The Pkg DevTool is for building to a executable exe file. The build output directory is dist.
The package.json's scripts.build
is replaced with "npx pkg . --out-path dist -t node16-win-x64". You can quickly start build with command "npm build". The default target is node16-win-x64, you can modify it in package.json and you should download the target node from github personally commonly.
The PM2 DevTool is a process manager that driven by node. It creates a basic ecosystem.config.js file.
You can customize pm2 more by yourself.
The framework use assets as default static resources folder. Please don't change it!
Most of the configuration are written in assets/config.yaml. And you can get the config by require global.__config
or __config
. Or you can get config from config.js by require('path/to/config.js').get()
.
logger tool is at /utils/logger.js
Framework set a Resp of this:
class Resp {
ok: boolean;
msg: string;
data: any;
symbol: number;
type: string;
}
Resp provides three builder methods of ok, fail, bad.
exhandler is at /midwares/exhandler.js
There are two middlewares: excatcher and exlogger.
Excather catch the exception and try to parse err.message as json string, if successful, it means it's our customized exception, if not, it will treat it as common exception and just return "System Error" to request source.
As said, after catching global errors, the default response is Resp.bad with "System Error", if we want more, we can throw a exception by this structure:
throw new Error(
JSON.stringify({
code: 400, // exception code
msg: "Invalid arguments." // description
symbol: 20000, // service code or error code if you need it
data: {}, // type of data is any
back: true, // whether to return the msg, if not, will return "System Error"
status: 500, // http status code, default is 200
}
);
For some examples:
throw new Error(JSON.stringify({code:400,msg:"Invalid arguments."});
When we don't need to retuen the msg, we can give "false" to "back".
throw new Error(JSON.stringify({code:400,msg:"Invalid arguments.",back:false});
The framework just supports exception code of 200 and 400, but you can customize it more.
If you generate evp-express project of TypeScript. There are several things that needed to be noticed:
- types declaration
cli predefined some types for config, exhandler etc in
src/types/index.d.ts
. You can modify and expand it, but before doing this should you know what are you doing and what maybe caused. - npm scripts
cli predefined some different scripts from the JavaScript project:
npm run tsc:build
: execute this to compile your codes to .js to dist directorynpm run start
: execute this to run the compiled codes in dist directorynpm run restart
: execute this to compile and then run codes in dist directory
since v1.2.1, in the root directory of project, there will be a evpconfig.json
file. In it has one option: lang
, it should be "typescript"
or "javascript"
and same with your project language. It works when you execute command evp-express add <template>
to judge is your project based on TypeScript or JavaScript.
In future, there will be more options in it.
Thanks for using!😊🥰