【Express.js】全局变量与配置文件

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

全局变量与配置文件

通常我们会将一些项目的配置信息写在一个文件内然后读入内存并使用。在 express 中使用全局变量有多种方案我们一起看看有哪些常用的方案

准备工作

拷贝第一节的HelloWorld项目

准备一个Resp.js模块

module.exports = {
    Ok: (...args)=>{
        return {
            code: 200,
            msg: args[0]?args[0]:"Ok",
            data: args[1]?args[1]:null
        }
    }
}

global

global对象中挂载我们需要全局共享的量比如我们想要挂载一个全局的config作为整个express应用的配置就在项目的唯一入口文件如: index.js, app.js等的最顶上优先于任何模块设置一次

// index.js
global.config = {
    appname: "GlobalVar"
}
/** 更简洁的写法隐变量首次被执行到后会自动挂载到全局
config = {
    appname: "GlobalVar"
}
*/
//创建app应用...

这样我们就可以在其它任何地方调用config比如新建一个router.js挂载到express应用上去

// router.js
const routes = require('express').Router();
routes.get('/global', (req, res, next)=>{
    res.send(Resp.Ok("global中的全局变量", {"appname":config.appname}));
});

module.exports = routes;

// index.js
app.use(routes);

如果我们有很多需要全局共享的配置挤在index.js的上方多少有点不雅观那我们可以把它们写在一个文件里然后在index.js最顶上引入一下

// global.js
global.config = {
    appname: "GlobalVar"
}

// index.js
require('./global');

**注意**由于global中的变量是可以直接以变量名xxx调用的无需global.xxx如果变量名设置的比较普通就比如上面的config甚至更简单的a之类的很可能跟其它模块中定义的临时变量冲突造成变量污染因此在global上挂载变量时取名一定要特殊点比如之前的config替换为__config

global.__config = {
    appname: "GlobalVar"
}

优点

  • 调用很便捷

缺点

  • 可能变量污染
  • 没有代码提示不心安

module

自定义一个module存放一些变量在需要的地方进行引入
比如我们自建一个config.js

// config.js
module.exports = {
    appname: "GlobalVar"
}

在router.js中引入config.js

// router.js
const CONFIG = require('./config');

routes.get('/module', (req, res, next)=>{
    res.send(Resp.Ok("config模块当作全局变量", {"appname":CONFIG.appname}));
});

优点

  • 能有代码提示
  • 无变量污染

缺点

  • 每次都要引入比较麻烦

app.set

在 express 的应用设置表中设置应用内的全局变量

// index.js
app.set("appname", "GlobalVar");

在其它地方调用app如挂载在app上的router

// router.js
routes.get('/app', (req, res, next)=>{
    res.send(Resp.Ok("app中的'全局'变量", {"appname":req.app.get("appname")}));
});

在挂载在app下的子应用中调用父app中的设置当某字段在子应用中没有设置时会继承父应用中的字段

//subapp.js
const app = require('express')();
const Resp = require('./Resp');
//当子应用没有设置时会继承父应用中设置的字段
// app.set('appname', "subapp");
app.all('/', (req, res, next) => {
    res.send(Resp.Ok("子应用获取父应用中的全局变量", {
        appname: req.app.get("appname")
    }));
})

module.exports = app;

//index.js
const subapp = require('./subapp');
app.use('/subapp',subapp);

优点

  • 能有代码提示

process.env

在进程的环境变量中挂载全局变量

//index.js
process.env.appname = "GlobalVar";

在其它地方调用process.env.appname

// subapp2.js
const app = require('express')();
const Resp = require('./Resp');

app.all('/', (req, res, next) => {
    // console.log(app.settings.env);
    res.send(Resp.Ok("在process.env上挂载全局变量", {
        appname: process.env.appname
    }));
})

module.exports = app;

//index.js
const subapp2 = require('./subapp2');
app.use('/process.env',subapp2);

缺点

  • 没有代码提示不心安

json

以上的方案都是将配置信息写在js文件中的对于一个正规的项目来说多少有点儿戏毕竟写在js中的变量是很容易就能被改变的。绝大多数时候配置信息是需要变化也不允许变化的我们只需要静态的信息即可。在Js项目中经常用json文件作为静态配置文件。

新建一个config.json文件

{
	"appname": "GlobalVar"
}

在我们的router中新加一条测试一下不管你在哪里require在首次被require之后修改json文件内容将不会再产生影响

routes.get('/json', (req, res, next)=>{
    let configJson = require('./config.json');
    res.send(Resp.Ok("json静态配置文件", {"appname":configJson.appname}));
});

json文件不支持注释如果想要注释要么曲线救国(加与被备注键相关的键值对)要么使用Json5规范

npm install json5

新建一个config.json5文件

{
    "appname": "GlobalVar"  //应用名
}

接着在项目的入口文件中引入register会挂载到全局

require('json5/lib/register');

之后require就可以解析json5文件了

routes.get('/json5', (req, res, next)=>{
    let configJson5 = require('./config.json5');
    res.send(Resp.Ok("json5静态配置文件", {"appname":configJson5.appname}));
});

yaml

相比.json文件.yaml(或.yml)文件是更加现在的配置文件json文件有着严格的格式要求yaml(yml)书写起来则更加自然
新建一个config.yaml文件

# 应用名
appname: GlobalVar  # 应用名

在nodeJs中读取yaml需要借助fsjs-yaml

npm install fs
npm install js-yaml

把fs挂载到全局即可(之前的global.js)一般情况下也不会取fs这样的局部变量名如果需要频繁的操作文件挂载到全局后会方便很多

global.fs = require('fs');

在router.js中引入js-yaml并新建一个测试路由

const yaml = require('js-yaml');

routes.get('/yaml', (req, res, next)=>{
    /*Object */
    let configYaml = yaml.load(fs.readFileSync('./config.yaml'));
    res.send(Resp.Ok("yaml动态配置文件", {"appname":configYaml.appname}));
});

由于是通过fs读取yaml文件的因此在改变yaml文件中的内容后访问路由的结果也会变


本文总共介绍了6种方案在项目具体采用哪种并没有绝对的说法因地制宜即可。

下一节-错误分类和日志分级

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6