Currently I\'m doing this:
foo.js
const FOO = 5;
module.exports = {
FOO: FOO
};
And using it in bar.js
:<
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.
In my opinion, utilizing Object.freeze
allows for a DRYer and more declarative style. My preferred pattern is:
./lib/constants.js
module.exports = Object.freeze({
MY_CONSTANT: 'some value',
ANOTHER_CONSTANT: 'another value'
});
./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'
The following issue was fixed in v8 in Jan 2014 and is no longer relevant to most developers:
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=1858 and http://jsperf.com/performance-frozen-object
From previous project experience, this is a good way:
In the 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
let constants = require('./constants');
console.log(constants.key1);
console.dir(constants.key3);
import
and export
(prob need something like babel as of 2018 to use import)
types.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
ES6 way.
export in foo.js
const FOO = 'bar';
module.exports = {
FOO
}
import in bar.js
const {FOO} = require('foo');
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.
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).
But I guess this is the best we can get.
Additionally, here's a kind of improvement of Dominic's function, in 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).
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:
exports.define = function ( name, value, exportsObject )
and use it like this in script.js:
constants.define( 'SOME_CONSTANT', "const value 1" );