Skip to content

Commit

Permalink
feat: update scaffolding for project
Browse files Browse the repository at this point in the history
  • Loading branch information
unix committed Jan 15, 2022
1 parent 6b5a1d7 commit 38dccc8
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 633 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,17 @@ The project uses Prisma as the intelligent ORM tool by default. Supports `Postgr

#### About Environments

- **Development Mode** (`NODE_ENV=development`): read configurations from `configs/constants/development.ts` file, but it will still be overwritten by `.env` file.
When nodejs is running, `ENV` does not mean `NODE_ENV`:

- **Production Mode** (`NODE_ENV=production`): read configurations from `configs/constants/production.ts` file, but it will still be overwritten by `.env` file.
- After NodeJS project is built, we always run it as `NODE_ENV=PRODUCTION`, which may affect some framework optimizations.
- `NODE_ENV` only identifies the NodeJS runtime, independent of the business.
- You should use `ENV` to identify the environment.

For the data settings of each environment, you can refer to the following:

- **Development Mode** (`ENV=development`): read configurations from `configs/constants/development.ts` file, but it will still be overwritten by `.env` file.

- **Production Mode** (`ENV=production`): read configurations from `configs/constants/production.ts` file, but it will still be overwritten by `.env` file.

---

Expand Down
12 changes: 10 additions & 2 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,17 @@

### 关于环境变量

- **在开发环境中** (`NODE_ENV=development`):自动从文件 `configs/constants/development.ts` 读取配置。
在 NodeJS 运行中,`ENV` 并不等于 `NODE_ENV`

- **在生产环境中** (`NODE_ENV=production`): 自动从文件 `configs/constants/production.ts` 读取配置。
- 当 NodeJS 项目被 build 后 (如在服务端运行),总是设置 `NODE_ENV=PRODUCTION`,这会影响一些第三方库的优化。
- `NODE_ENV` 只用于鉴别 NodeJS 运行,与你的业务环境无关。
- 推荐你总是使用 `ENV` 来鉴别当前的环境。

对于每个环境的数据设置,可以参考如下:

- **在开发环境中** (`ENV=development`):自动从文件 `configs/constants/development.ts` 读取配置。

- **在生产环境中** (`ENV=production`): 自动从文件 `configs/constants/production.ts` 读取配置。

- **任何环境**: 如果 `.env` 文件内存在同名常量,会覆盖上述 2 个环境配置文件。优先级最高。

Expand Down
19 changes: 19 additions & 0 deletions build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const { nodeExternalsPlugin } = require('esbuild-node-externals')

require('esbuild')
.build({
entryPoints: ['app.ts'],
bundle: true,
outfile: 'dist/index.js',
platform: 'node',
plugins: [
nodeExternalsPlugin({
dependencies: false,
}),
],
external: ['cors', 'kcors'],
})
.catch(err => {
console.log(err)
process.exit(1)
})
7 changes: 0 additions & 7 deletions build.sh

This file was deleted.

5 changes: 5 additions & 0 deletions configs/constants/envs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum ENVS {
DEVELOPMENT = 'DEVELOPMENT',
STAGING = 'STAGING',
PRODUCTION = 'PRODUCTION',
}
51 changes: 21 additions & 30 deletions configs/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,34 @@ import { bootstrapBefore } from '../bootstrap'
import development, { EevRecord } from './development'
import staging from './staging'
import production from './production'
import { ENVS } from './envs'

const parsedEnvs = bootstrapBefore()

export type Envs = {
DEVELOPMENT: boolean
STAGING: boolean
PRODUCTION: boolean
}

const getCurrentEnv = (): Envs => {
const getCurrentEnv = (): ENVS => {
const env = process.env?.ENV
const up = `${env}`.toUpperCase()
const currentEnvs: Envs = {
DEVELOPMENT: false,
STAGING: false,
PRODUCTION: false,
}
if (up === 'PRODUCTION')
return {
...currentEnvs,
PRODUCTION: true,
}
if (up === 'STAGING')
return {
...currentEnvs,
STAGING: true,
}
return {
...currentEnvs,
DEVELOPMENT: true,
if (typeof env === 'undefined') {
console.warn(`/n> ENV is not set, fallback to ${ENVS.DEVELOPMENT}.`)
}
const upperCaseEnv = `${env}`.toUpperCase()
if (upperCaseEnv === ENVS.PRODUCTION) return ENVS.PRODUCTION
if (upperCaseEnv === ENVS.STAGING) return ENVS.STAGING
return ENVS.DEVELOPMENT
}

export type CurrentConstants = EevRecord

const getCurrentConstants = (envs: Envs): EevRecord => {
const getCurrentConstants = (ident: ENVS): EevRecord => {
let constants = development
const source = envs.PRODUCTION ? production : envs.STAGING ? staging : development
const source =
ident === ENVS.PRODUCTION
? production
: ident === ENVS.STAGING
? staging
: development
Object.keys(development).forEach(key => {
const sourceValue = source[key]
const processValue = process.env[key]
const parsedValue = parsedEnvs[key]

if (typeof sourceValue !== 'undefined') {
constants[key] = sourceValue
}
Expand All @@ -55,9 +41,14 @@ const getCurrentConstants = (envs: Envs): EevRecord => {
}
})

constants.ENV_LABEL = source.ENV_LABEL

return constants
}

export const CURRENT_ENV = getCurrentEnv()

export const isProd = () => CURRENT_ENV === ENVS.PRODUCTION
const CONSTANTS = getCurrentConstants(CURRENT_ENV)

export default CONSTANTS
6 changes: 4 additions & 2 deletions configs/koa.middlewares.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import Koa from 'koa'
import logger from 'koa-logger'
import bodyParser from 'koa-bodyparser'
import Environment from './constants'
import { isProd } from './constants'

export const useMiddlewares = <T extends Koa>(app: T): T => {
Environment.ENV_LABEL === 'PRODUCTION' && app.use(logger())
if (isProd()) {
app.use(logger())
}

app.use(bodyParser())

Expand Down
15 changes: 7 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"description": "The best practice of building Koa2 with TypeScript",
"main": "app.ts",
"scripts": {
"dev": "export NODE_ENV=development; nodemon --config nodemon.json",
"dev": "export NODE_ENV=development; ts-node-dev -r tsconfig-paths/register app.ts",
"dev:db": "docker compose -f docker-compose.yml up -d",
"prettier": "prettier --write '**/*.{js,ts}'",
"test": "jest --config .jest.config.js --no-cache --detectOpenHandles",
"prod:build": "bash ./build.sh",
"prod:start": "prisma generate && prisma migrate deploy && export NODE_ENV=production; node ./releases/app.js"
"prod:build": "node ./build.js",
"prod:start": "prisma generate && prisma migrate deploy && export NODE_ENV=production; node ./dist/index.js"
},
"author": "unix ([email protected])",
"bugs": {
Expand All @@ -27,17 +27,16 @@
"@types/koa": "^2.13.4",
"@types/koa-bodyparser": "^4.3.5",
"@types/node": "^17.0.8",
"esbuild": "^0.14.11",
"esbuild-node-externals": "^1.4.1",
"jest": "^26.6.3",
"nodemon": "^2.0.15",
"prettier": "^2.5.1",
"prisma": "^3.8.1",
"supertest": "^4.0.2",
"ts-jest": "^26.5.3",
"ts-node": "^10.4.0",
"ts-node-dev": "^1.1.8",
"tsconfig-paths": "^3.12.0",
"ttypescript": "^1.5.13",
"typescript": "^4.5.4",
"typescript-transform-paths": "^3.3.1"
"typescript": "^4.5.4"
},
"dependencies": {
"@prisma/client": "^3.8.1",
Expand Down
9 changes: 3 additions & 6 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
"allowJs": true,
"moduleResolution": "Node",
"module": "commonjs",
"outDir": "./releases",
"outDir": "./dist",
"lib": ["ESNext"],
"removeComments": true,
"skipLibCheck": true,
"noImplicitAny": false,
"esModuleInterop": true,
"preserveConstEnums": true,
Expand All @@ -17,12 +18,9 @@
],
"baseUrl": ".",
"paths": {
"configs": ["configs"],
"configs/*": ["./configs/*"],
"app": ["app"]
},
"plugins": [
{ "transform": "typescript-transform-paths" }
]
},
"compileOnSave": false,
"includes": [
Expand All @@ -33,7 +31,6 @@
],
"files": [
"app.ts",
"configs/connection.ts"
],
"exclude": [
"node_modules",
Expand Down
Loading

0 comments on commit 38dccc8

Please sign in to comment.