Skip to content

Commit

Permalink
feat: add access constans.*.js method to @ddn/core
Browse files Browse the repository at this point in the history
  • Loading branch information
imfly committed Aug 2, 2024
1 parent 68a53ed commit 8c4c7bd
Show file tree
Hide file tree
Showing 7 changed files with 589 additions and 26 deletions.
8 changes: 6 additions & 2 deletions examples/fun-tests/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const path = require('path')
const fs = require('fs')
const DdnCore = require('@ddn/core')
const DdnPeer = require('@ddn/peer').default
const constants = require('./constants.mainnet')

/**
* 整理系统配置文件生成输入参数
Expand Down Expand Up @@ -48,7 +47,6 @@ async function genOptions () {
configObject.version = packageFile.version
configObject.basedir = baseDir
configObject.buildVersion = packageFile.version
configObject.net = process.env.NET || 'testnet'
configObject.publicDir = path.join(baseDir, 'public')
configObject.dappsDir = command.dapps || path.join(baseDir, 'dapps')
if (command.port) {
Expand Down Expand Up @@ -81,6 +79,12 @@ async function genOptions () {
configObject.loading.verifyOnLoading = true
}

// 获取用户配置的常量,依赖于用户的配置
const constants = await DdnCore.getUserConstants({ cwd: baseDir, net: configObject.net })

console.log('configObject:', configObject)
console.log('constants: ', constants)

return {
baseDir,
configObject,
Expand Down
2 changes: 1 addition & 1 deletion examples/fun-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"build-localnet": "./node_modules/.bin/gulp linux-build-local"
},
"dependencies": {
"@ddn/asset-aob": "^1.2.3",
"@ddn/asset-aob": "workspace:^",
"@ddn/asset-base": "workspace:^",
"@ddn/asset-dao": "workspace:^",
"@ddn/asset-dapp": "workspace:^",
Expand Down
42 changes: 29 additions & 13 deletions packages/core/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# @DDN/core

用于对 DDN 区块链 相关的配置等相关的基本操作,让系统支持 .ddnrc.js 等根据环境不同的配置文件
用于对 DDN 区块链 相关的配置等相关的基本操作,让系统支持 .ddnrc.js、constants.js 等根据环境不同的配置文件

# 开发配置
## 配置文件

DDN 允许在 `.ddnrc.t|js``config/config.json``config/config.t|js`(五选一,`.ddnrc.t|js` 优先)中进行配置,支持 ES6 语法。
DDN 允许在 `.ddnrc.t|js``config/config.json``config/config.t|js`(五选一,`.ddnrc.t|js` 优先),以及基于该配置的 `constants.t|js`, `config/constants.t|js`(四选一,`constants.t|js`优先) 中进行配置,支持 ES6 语法。

**注意**:不要将上述配置混合使用,按照优先级,其他的配置不起作用
**注意**:不要将上述配置混合使用,按照优先级,只能保留一个

> 为简化说明,后续文档里只会出现 `.ddnrc.t|js`
> 为简化说明,后续文档里只会出现 `.ddnrc.js`
比如:

```js
// .ddnrc.js
export default {
publicPath: 'http://bar.com/foo',
assets: [
Expand All @@ -25,27 +26,42 @@ export default {

具体配置项详见[配置](/zh/config/)

## .ddnrc.local.js
## 优先级

总的原则是,`NODE_ENV`区分生产环境、开发环境,`DDN_ENV`区分物理环境(文件)。生产环境下,`*.mainnet.*`文件优先,其他环境下,优先级为 `*.local.*` > *.{DDN_ENV}.* > `*.testnet.*`

- 1、production: constants.mainnet.* [生产环境下最优先]
- 2、local: constants.local.*
- 3、custom: constants.{DdnEnv}.*
- 4、development: constants.testnet.*;

## 本地配置

.ddnrc.local.js

`.ddnrc.local.js` 是本地的配置文件,**不要提交到 git**,所以通常需要配置到 `.gitignore`

`.ddnrc.local.js` 默认有效。如果存在,会自动覆盖 `.ddnrc.js` 的同名配置,再返回。所以,你如果有个性化的本地配置,可以添加该文件,从而避免对正式配置文件的污染。

`.ddnrc.local.js` 是本地的配置文件,**不要提交到 git**,所以通常需要配置到 `.gitignore`。如果存在,会和 `.ddnrc.js` 合并后再返回。
## 环境变量

`.ddnrc.local.js` 需要配合环境变量 `NODE_ENV=development` 才有效。
### 1. NODE_ENV

## NODE_ENV
程序默认是开发环境,即:非生产环境,`.ddnrc.local.js``.ddnrc.testnet.js` 起作用,且前者覆盖后者,`.ddnrc.mainnet.js` 不起作用。

程序默认是生产环境,即:非开发环境,`.ddnrc.mainnet.js` 将被自动合并到最终的配置中去。如果设置 `NODE_ENV=development`程序将运行在开发环境下`.ddnrc.local.js``.ddnrc.testnet.js` 将都被合并到配置中去,同时,前者覆盖后者
如果设置 `NODE_ENV=production`程序将运行在生产环境下`.ddnrc.local.js``.ddnrc.testnet.js` 将被`.ddnrc.mainnet.js`自动覆盖

## DDN_ENV
### 2. DDN_ENV

可以通过环境变量 `DDN_ENV` 区分不同物理环境(比如:cloud, custom)来指定配置。
如果需要临时或定制化的环境配置,可以通过环境变量 `DDN_ENV` 区分,例如:针对不同物理环境(比如:cloud, custom)来指定配置。

举个例子,

```js
// .ddnrc.js
export default { a: 1, b: 2 };

// .ddnrc.cloud.js
// DDN_ENV=cloud -> .ddnrc.cloud.js
export default { b: 'cloud', c: 'cloud' };

// .ddnrc.local.js
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ddn/core",
"version": "2.4.5",
"version": "2.4.6",
"description": "DDN core.",
"main": "./dist/index.js",
"types": "dist/index.d.ts",
Expand Down
96 changes: 89 additions & 7 deletions packages/core/src/getUserConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import extend from 'extend2'
import winPath from './winPath'

/**
* 获取指定目录下的配置文件
* 如果环境变量 DDN_CONFIG_FILE 存在,通常是 .ddnrc.* 系列文件,将使用它的值来确定配置文件。否则,将检查默认的配置文件名列表。
* 获取指定目录下的配置文件(并确保唯一)
* 如果环境变量 CONFIG_FILE 存在,通常是 .ddnrc.* 系列文件,将使用它的值来确定配置文件。否则,将检查默认的配置文件名列表。
* 可以通过逗号分隔配置文件名列表,并且可以通过配置环境变量来指定配置文件。
*
* @param {string} cwd - 当前工作路径
* @returns {string|undefined} - 如果找到配置文件,返回配置文件的完整路径;否则返回 undefined
* @throws {Error} 如果找到多个配置文件,抛出错误
*/
export function getConfigFile (cwd) {
const files = process.env.DDN_CONFIG_FILE
? process.env.DDN_CONFIG_FILE.split(',').filter(v => v && v.trim())
const files = process.env.CONFIG_FILE
? process.env.CONFIG_FILE.split(',').filter(v => v && v.trim())
: ['.ddnrc.ts', '.ddnrc.js', 'config/config.json', 'config/config.ts', 'config/config.js']

// const validFiles = files.filter(f => {})
Expand All @@ -30,6 +30,38 @@ export function getConfigFile (cwd) {
}
}

/**
* 获取指定目录下的常量配置文件(确保唯一)
* 如果环境变量 CONSTANTS_FILE 存在,通常是 constants.* 系列文件,将使用它的值来确定配置文件。否则,将检查默认的配置文件名列表。
* 可以通过逗号分隔配置文件名列表,并且可以通过配置环境变量来指定配置文件。
*
* @param {string} cwd - 当前工作路径
* @returns {string|undefined} - 如果找到配置文件,返回配置文件的完整路径;否则返回 undefined
* @throws {Error} 如果找到多个配置文件,抛出错误
*/
export function getConstantsFile (cwd) {
const files = process.env.CONSTANTS_FILE
? process.env.CONSTANTS_FILE.split(',').filter(v => v && v.trim())
: ['constants.ts', 'constants.js', 'config/constants.ts', 'config/constants.js']

// const validFiles = files.filter(f => {})
const validFiles = files.filter(f => existsSync(join(cwd, f)))

assert(
validFiles.length <= 1,
`Multiple config files (${validFiles.join(', ')}) were detected, please keep only one.`
)
if (validFiles[0]) {
return winPath(join(cwd, validFiles[0]))
}
}

/**
* 在文件名字符串的末尾添加指定的后缀
* @param {string} file - 要修改的文件名
* @param {string} affix - 要添加的后缀
* @returns {string} - 添加后缀后的文件名
*/
export function addAffix (file, affix) {
const ext = extname(file)
return file.replace(new RegExp(`${ext}$`), `.${affix}${ext}`)
Expand Down Expand Up @@ -67,21 +99,51 @@ export async function getConfigByConfigFile (configFile, opts = {}) {
const requireOpts = { onError }

/**
* development: config.testnet.* and config.local.*;
* production: mainnet
* 优先级:
* 1、production: .ddnrc.mainnet.* [生产环境下最优先]
* 2、local: .ddnrc.local.*
* 3、custom: .ddnrc.{DdnEnv}.*
* 4、development: .ddnrc.testnet.*;
*/
const configs = [
defaultConfig,
await requireFile(configFile, requireOpts),
ddnEnv && (await requireFile(addAffix(configFile, ddnEnv), requireOpts)),
!isProd && (await requireFile(addAffix(configFile, 'testnet'), requireOpts)),
ddnEnv && (await requireFile(addAffix(configFile, ddnEnv), requireOpts)),
!isProd && (await requireFile(addAffix(configFile, 'local'), requireOpts)),
isProd && (await requireFile(addAffix(configFile, 'mainnet'), requireOpts))
]

return mergeConfigs(...configs)
}

export async function getConstantsByFile (constantsFile, opts = {}) {
const { defaultConstants, onError, net } = opts
console.log('net', net)
const isMainnet = net === 'mainnet'
const ddnEnv = process.env.DDN_ENV

const requireOpts = { onError }

/**
* 优先级:
* 1、production: constants.mainnet.* [生产环境下最优先]
* 2、local: constants.local.*
* 3、custom: constants.{DdnEnv}.*
* 4、development: constants.testnet.*;
*/
const configs = [
defaultConstants,
await requireFile(constantsFile, requireOpts),
!isMainnet && (await requireFile(addAffix(constantsFile, 'testnet'), requireOpts)),
ddnEnv && (await requireFile(addAffix(constantsFile, ddnEnv), requireOpts)),
!isMainnet && (await requireFile(addAffix(constantsFile, 'local'), requireOpts)),
isMainnet && (await requireFile(addAffix(constantsFile, 'mainnet'), requireOpts))
]

return mergeConfigs(...configs)
}

// Use DDN_ENV to add yourself config, e.g: DDN_ENV=prod config.prod.js
export function getConfigPaths (cwd) {
const env = process.env.DDN_ENV
Expand Down Expand Up @@ -127,3 +189,23 @@ export async function getUserConfig (opts = {}) {
return {}
}
}

/**
* 配置调用
* 默认 .ddnrc.js,config/config.json, config/config.j(t)s是主要配置文件,
* 当 DDN_ENV 给定值的时候,主配置文件不变,但是 在 .{DDN_ENV}.js 中的配置覆盖
* 主配置文件而生效。
* @param opts {cwd: cwd, defaultConstants: constants.default.js }
*/
export async function getUserConstants (opts = {}) {
const { cwd, defaultConstants, net } = opts
const absConfigFile = getConstantsFile(cwd)

if (absConfigFile) {
return await getConstantsByFile(absConfigFile, {
defaultConstants, net
})
} else {
return {}
}
}
4 changes: 2 additions & 2 deletions packages/core/src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import getPaths from './getPaths'
import { getUserConfig, requireFile, mergeConfigs } from './getUserConfig'
import { getUserConfig, getUserConstants, requireFile, mergeConfigs } from './getUserConfig'

export { getPaths, getUserConfig, requireFile, mergeConfigs }
export { getPaths, getUserConfig, getUserConstants, requireFile, mergeConfigs }
Loading

0 comments on commit 8c4c7bd

Please sign in to comment.