精通 MEAN 了解一个 MEAN 应用程序(4)了解配置和环境
 
- UID
- 1066743
|

精通 MEAN 了解一个 MEAN 应用程序(4)了解配置和环境
了解配置和环境看一下清单 12 所示的 config/env/all.js,其中包含 title、description 和 keywords 变量。(我对目录结构进行了搜索,查找这定义这些变量的位置 — 在了解 MEAN 堆栈的过程中您可能希望将这个技巧添加到您的工具箱中)。
清单 12. config/env/all.js1
2
3
4
5
6
7
8
9
10
| 'use strict';
module.exports = {
app: {
title: 'Test',
description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
keywords: 'MongoDB, Express, AngularJS, Node.js'
},
port: process.env.PORT || 3000,
templateEngine: 'swig',
|
除了模板期望的关键字外,该文件还包含其他一些有趣的值,比如 port 和 templateEngine。
环境变量您可以在应用程序以外的地方设置一些变量来修改应用程序的行为,比如 PORT 和 NODE_ENV。例如,注意 config/env/all.js 中的 port 设置:
1
| port: process.env.PORT || 3000,
|
该设置告诉应用程序 “将内部的 port 变量设置为环境变量 PORT 的值,或在未找到 PORT 的情况下设置为默认值 3000”。
要对这一设置进行测试,请按下 Ctrl+C 停止应用程序。要重启应用程序,可以尝试使用 PORT=4000 grunt,而不是使用 grunt 命令。您的应用程序现在在端口 4000 上运行。
您可以对 Node.js 进行编码,从而根据不同的运行时环境(开发、生产、准备、测试等等)表现出不同的行为。与 PORT 一样,如果没有显式地指定运行时环境,那么 Express 将为 NODE_ENV 提供一个默认值 —development。这解释了在重启应用程序时它发出的一个警告:
1
| NODE_ENV is not defined! Using default development environment
|
为了增加一些灵活性,可以在环境变量中具体化运行时配置。在命令行中,可以临时设置 PORT 和 NODE_ENV 等变量。这样,在进行开发和测试时就可以很容易地改变变量的值。(当然,您可以将它们添加到 .bash_profile,或者在 Windows® 中的 Control Panel 中设置它们,使它们具有更长的寿命)。
您可能会因为安全性而使用环境变量。在环境变量中保存用户名、密码和连接 URL,而不是将它们放到容易受破坏的配置文件中(或者扩展到源控制)。这种方法也便于跨多个开发人员或生产机器部署通用的配置文件,并允许每个机器通过本地环境变量插入惟一值或凭证。
并不只限制使用 PORT 和 NODE_ENV 环境变量。您的 Platform as a Service (PaaS) 提供商通常会提供若干个特定于服务的变量。
命名环境(Named environment)设置单独的环境变量固然不错,但是您可能需要对一些相关的变量进行统一修改。例如,您希望避免修改用户名但忘记修改对应密码之类的简单错误。幸运的是,这个 MEAN 应用程序支持 命名环境 的概念。(这个概念并不是 MEAN 应用程序所独有的。Rails、Grails 和许多其他流行的 Web 框架也提供了类似的功能)。
查看清单 13 的目录树中的 config/env,您将在其中看到一些命名环境文件。
清单 13. config 目录结构1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| $ tree config/
config/
|--- config.js
|--- env
|�� |--- all.js
|�� |--- development.js
|�� |--- production.js
|�� |--- test.js
|--- express.js
|--- init.js
|--- passport.js
|--- strategies
|--- facebook.js
|--- google.js
|--- linkedin.js
|--- local.js
|--- twitter.js
2 directories, 13 files
|
在 config/env、development.js、production.js 和 test.js 中,都指定了命名环境。如果您认为 all.js 包含对所有环境通用的值,那么您的理解就是正确的。
要查看这些文件的读取和合并位置,请查看清单 14 所示的 config/config.js。
清单 14. config/config.js1
2
3
4
5
6
7
8
9
10
11
12
| /**
* Module dependencies.
*/
var _ = require('lodash');
/**
* Load app configurations
*/
module.exports = _.extend(
require('./env/all'),
require('./env/' + process.env.NODE_ENV) || {}
);
|
Lo-Dash 和 Underscore.js
是一个 CommonJS 模块,为数组、对象和 JSON 结构提供了方便的函数。在 中,开发人员试图在 all.js 中设置一些基本值,并允许它们被 development.js(或 production.js 或 test.js)中的值覆盖。
您已经查看了 中的 config/env/all.js。清单 15 显示了 config/env/development.js。
清单 15. config/env/development.js1
2
3
4
5
6
7
| 'use strict';
module.exports = {
db: 'mongodb://localhost/meanjs-dev',
app: {
title: 'MeanJS - Development Environment'
},
|
理想情况下,lodash.extend 函数将合并两个 JSON 块来生成这个结果:
1
2
3
4
5
| app: {
title: 'MeanJS - Development Environment',
description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
keywords: 'MongoDB, Express, AngularJS, Node.js'
}
|
不幸的是,这并不是您获得的输出。添加一行代码将合并后的结构输出到 config/config.js,如清单 16 所示:
清单 16. 将实际合并后的结果合并到控制台 1
2
3
4
5
6
7
8
| /**
* Load app configurations
*/
module.exports = _.extend(
require('./env/all'),
require('./env/' + process.env.NODE_ENV) || {}
);
console.log(module.exports)
|
输入 PORT=4000 NODE_ENV=development grunt,返回应用程序。控制台将显示:
1
| app: { title: 'MeanJS - Development Environment' }
|
如控制台中所示,config/env/development.js 中的 JSON 结构覆盖了 config/env/all.js 中的结构,而不是与之合并。幸运的是,您可以快速修改 config/config.js 以获得期望的结果。
将函数调用从 _.extend 修改为 _.merge。当再次返回应用程序时,应该可以看到期望的结果:
1
2
3
4
| app:
{ title: 'MeanJS - Development Environment',
description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
keywords: 'MongoDB, Express, AngularJS, Node.js' },
|
如果在浏览器中单击主页面上的 View > Source,就可以看到 config 值已经与 HTML 模板合并,如清单 17 所示。
清单 17. HTML 显示正确的合并结果1
2
3
4
5
6
| <head>
<title>MeanJS - Development Environment</title>
<!-- Semantic META -->
<meta name="keywords" content="MongoDB, Express, AngularJS, Node.js">
<meta name="description" content="Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js">
|
现在,我们将从服务器端移动到客户端,完成此次 MEAN 应用程序之旅。 |
|
|
|
|
|