Javascript 你如何在 NodeJS 模块中共享常量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8595509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you share constants in NodeJS modules?
提问by Tower
Currently I'm doing this:
目前我正在这样做:
foo.js
foo.js
const FOO = 5;
module.exports = {
FOO: FOO
};
And using it in bar.js
:
并在bar.js
:
var foo = require('foo');
foo.FOO; // 5
Is there a better way to do this? It feels awkward to declare the constant in the exports object.
有一个更好的方法吗?在exports对象中声明常量感觉很尴尬。
采纳答案by Alex Wayne
You can explicitly export it to the global scope with global.FOO = 5
. Then you simply need to require the file, and not even save your return value.
您可以使用 将其显式导出到全局范围global.FOO = 5
。然后你只需要 require 文件,甚至不保存你的返回值。
But really, you shouldn't do that. Keeping things properly encapsulated is a good thing. You have the right idea already, so keep doing what you're doing.
但实际上,你不应该那样做。把事情妥善地封装起来是一件好事。你已经有了正确的想法,所以继续做你正在做的事情。
回答by Spain Train
In my opinion, utilizing Object.freeze
allows for a DRYer and more declarative style. My preferred pattern is:
在我看来,利用Object.freeze
允许 DRYer 和更具声明性的风格。我的首选模式是:
./lib/constants.js
./lib/constants.js
module.exports = Object.freeze({
MY_CONSTANT: 'some value',
ANOTHER_CONSTANT: 'another value'
});
./lib/some-module.js
./lib/some-module.js
var constants = require('./constants');
console.log(constants.MY_CONSTANT); // 'some value'
constants.MY_CONSTANT = 'some other value';
console.log(constants.MY_CONSTANT); // 'some value'
Outdated Performance Warning
过时的性能警告
The following issue was fixed in v8 in Jan 2014 and is no longer relevant to most developers:
以下问题已于 2014 年 1 月在 v8 中修复,并且不再与大多数开发人员相关:
Be aware that both setting writable to false and using Object.freeze have a massive performance penalty in v8 - https://bugs.chromium.org/p/v8/issues/detail?id=1858and http://jsperf.com/performance-frozen-object
请注意,将 writable 设置为 false 和使用 Object.freeze 在 v8 中都有巨大的性能损失 - https://bugs.chromium.org/p/v8/issues/detail?id=1858和http://jsperf.com /性能冻结对象
回答by Dominic Barnes
Technically, const
is not part of the ECMAScript specification. Also, using the "CommonJS Module" pattern you've noted, you can change the value of that "constant" since it's now just an object property. (not sure if that'll cascade any changes to other scripts that require the same module, but it's possible)
从技术上讲,const
它不是 ECMAScript 规范的一部分。此外,使用您注意到的“CommonJS 模块”模式,您可以更改该“常量”的值,因为它现在只是一个对象属性。(不确定这是否会将任何更改级联到需要相同模块的其他脚本,但有可能)
To get a real constant that you can also share, check out Object.create
, Object.defineProperty
, and Object.defineProperties
. If you set writable: false
, then the value in your "constant" cannot be modified. :)
要获得真正的常数,你也可以分享,看看Object.create
,Object.defineProperty
和Object.defineProperties
。如果您设置writable: false
,则无法修改“常量”中的值。:)
It's a little verbose, (but even that can be changed with a little JS) but you should only need to do it once for your module of constants. Using these methods, any attribute that you leave out defaults to false
. (as opposed to defining properties via assignment, which defaults all the attributes to true
)
它有点冗长,(但即使可以用一点 JS 来改变),但你应该只需要为你的常量模块做一次。使用这些方法,您省略的任何属性都默认为false
。(与通过赋值定义属性相反,它将所有属性默认为true
)
So, hypothetically, you could just set value
and enumerable
, leaving out writable
and configurable
since they'll default to false
, I've just included them for clarity.
因此,假设您可以只设置value
and enumerable
,writable
而configurable
忽略它们,因为它们将默认为false
,为了清楚起见,我只是将它们包括在内。
Update- I've create a new module (node-constants) with helper functions for this very use-case.
更新- 我为这个用例创建了一个带有辅助函数的新模块(node-constants)。
constants.js -- Good
constants.js -- 好
Object.defineProperty(exports, "PI", {
value: 3.14,
enumerable: true,
writable: false,
configurable: false
});
constants.js -- Better
constants.js -- 更好
function define(name, value) {
Object.defineProperty(exports, name, {
value: value,
enumerable: true
});
}
define("PI", 3.14);
script.js
脚本.js
var constants = require("./constants");
console.log(constants.PI); // 3.14
constants.PI = 5;
console.log(constants.PI); // still 3.14
回答by Diego Mello
ES6 way.
ES6 方式。
export in foo.js
在 foo.js 中导出
const FOO = 'bar';
module.exports = {
FOO
}
import in bar.js
在 bar.js 中导入
const {FOO} = require('foo');
回答by xmak
I found the solution Dominic suggested to be the best one, but it still misses one feature of the "const" declaration. When you declare a constant in JS with the "const" keyword, the existence of the constant is checked at parse time, not at runtime. So if you misspelled the name of the constant somewhere later in your code, you'll get an error when you try to start your node.js program. Which is a far more better misspelling check.
我发现 Dominic 建议的解决方案是最好的解决方案,但它仍然遗漏了“const”声明的一项功能。当您在 JS 中使用“const”关键字声明一个常量时,会在解析时而不是在运行时检查该常量是否存在。因此,如果您在代码的后面某处拼错了常量的名称,则在尝试启动 node.js 程序时会出现错误。这是一个更好的拼写错误检查。
If you define the constant with the define() function like Dominic suggested, you won't get an error if you misspelled the constant, and the value of the misspelled constant will be undefined (which can lead to debugging headaches).
如果您像 Dominic 建议的那样使用 define() 函数定义常量,那么如果您拼错了常量,就不会出现错误,并且拼错的常量的值将是未定义的(这会导致调试问题)。
But I guess this is the best we can get.
但我想这是我们能得到的最好的。
Additionally, here's a kind of improvement of Dominic's function, in constans.js:
此外,这是对多米尼克功能的一种改进,在 constans.js 中:
global.define = function ( name, value, exportsObject )
{
if ( !exportsObject )
{
if ( exports.exportsObject )
exportsObject = exports.exportsObject;
else
exportsObject = exports;
}
Object.defineProperty( exportsObject, name, {
'value': value,
'enumerable': true,
'writable': false,
});
}
exports.exportObject = null;
In this way you can use the define() function in other modules, and it allows you to define constants both inside the constants.js module and constants inside your module from which you called the function. Declaring module constants can then be done in two ways (in script.js).
通过这种方式,您可以在其他模块中使用define() 函数,它允许您在constants.js 模块中定义常量以及在调用该函数的模块中定义常量。然后可以通过两种方式(在 script.js 中)声明模块常量。
First:
第一的:
require( './constants.js' );
define( 'SOME_LOCAL_CONSTANT', "const value 1", this ); // constant in script.js
define( 'SOME_OTHER_LOCAL_CONSTANT', "const value 2", this ); // constant in script.js
define( 'CONSTANT_IN_CONSTANTS_MODULE', "const value x" ); // this is a constant in constants.js module
Second:
第二:
constants = require( './constants.js' );
// More convenient for setting a lot of constants inside the module
constants.exportsObject = this;
define( 'SOME_CONSTANT', "const value 1" ); // constant in script.js
define( 'SOME_OTHER_CONSTANT', "const value 2" ); // constant in script.js
Also, if you want the define() function to be called only from the constants module (not to bloat the global object), you define it like this in constants.js:
此外,如果您希望仅从常量模块调用 define() 函数(而不是使全局对象膨胀),您可以在 constants.js 中像这样定义它:
exports.define = function ( name, value, exportsObject )
and use it like this in script.js:
并在 script.js 中像这样使用它:
constants.define( 'SOME_CONSTANT', "const value 1" );
回答by Manohar Reddy Poreddy
From previous project experience, this is a good way:
从以前的项目经验来看,这是一个很好的方法:
In the constants.js:
在 constants.js 中:
// constants.js
'use strict';
let constants = {
key1: "value1",
key2: "value2",
key3: {
subkey1: "subvalue1",
subkey2: "subvalue2"
}
};
module.exports =
Object.freeze(constants); // freeze prevents changes by users
In main.js (or app.js, etc.), use it as below:
在 main.js(或 app.js 等)中,使用如下:
// main.js
let constants = require('./constants');
console.log(constants.key1);
console.dir(constants.key3);
回答by Luis Martins
I think that const
solves the problem for most people looking for this anwwer. If you really need an immutable constant, look into the other answers.
To keep everything organized I save all constants on a folder and then require the whole folder.
我认为这const
解决了大多数寻找这个答案的人的问题。如果您真的需要一个不可变的常量,请查看其他答案。为了保持一切井井有条,我将所有常量保存在一个文件夹中,然后需要整个文件夹。
src/main.js file
src/main.js 文件
const constants = require("./consts_folder");
src/consts_folder/index.js
src/consts_folder/index.js
const deal = require("./deal.js")
const note = require("./note.js")
module.exports = {
deal,
note
}
Ps. here the deal
and note
will be first level on the main.js
附言。这里deal
和note
将是 main.js 的第一级
src/consts_folder/note.js
src/consts_folder/note.js
exports.obj = {
type: "object",
description: "I'm a note object"
}
Ps. obj
will be second level on the main.js
附言。obj
将是 main.js 的第二级
src/consts_folder/deal.js
src/consts_folder/deal.js
exports.str = "I'm a deal string"
Ps. str
will be second level on the main.js
附言。str
将是 main.js 的第二级
Final result on main.js file:
main.js 文件的最终结果:
console.log(constants.deal);
Ouput:
console.log(constants.deal);
输出:
{ deal: { str: 'I\'m a deal string' },
{ 交易: { str: '我是交易字符串' },
console.log(constants.note);
Ouput:
console.log(constants.note);
输出:
note: { obj: { type: 'object', description: 'I\'m a note object' } }
注意:{ 对象:{ 类型:'对象',描述:'我是一个笔记对象'}}
回答by atreeon
import
and export
(prob need something like babel as of 2018 to use import)
import
和export
(可能需要像 2018 年的 babel 一样使用导入)
types.js
类型.js
export const BLUE = 'BLUE'
export const RED = 'RED'
myApp.js
我的应用程序
import * as types from './types.js'
const MyApp = () => {
let colour = types.RED
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
回答by herman
As an alternative, you can group your "constant" values in a local object, and export a function that returns a shallow clone of this object.
作为替代方案,您可以将“常量”值分组到一个本地对象中,并导出一个返回该对象的浅层克隆的函数。
var constants = { FOO: "foo" }
module.exports = function() {
return Object.assign({}, constants)
}
Then it doesn't matter if someone re-assigns FOO because it will only affect their local copy.
那么是否有人重新分配 FOO 并不重要,因为它只会影响他们的本地副本。
回答by alessioalex
Since Node.js is using the CommonJS patterns, you can only share variables between modules with module.exports
or by setting a global var like you would in the browser, but instead of using window you use global.your_var = value;
.
由于 Node.js 使用的是 CommonJS 模式,因此您只能module.exports
像在浏览器中一样使用或通过设置全局变量来在模块之间共享变量,但您使用global.your_var = value;
.