0

我试图理解 lodash 中的分配/扩展函数,因为我通过 mean.io 堆栈设置遇到了一个非常令人困惑的结果。

这里:

'use strict';

var _ = require('lodash');

// Load app configuration
var foo = require(__dirname + '/../config/env/all.js');
console.log('-.-.-.-.-.-.-.-.-.-. foo before _.assign .-.-.-.-.-.-.-.-.-.-');
console.log(foo)

module.exports = _.assign(
    require(__dirname + '/../config/env/all.js'),
    require(__dirname + '/../config/env/' + process.env.NODE_ENV + '.js') || {}
    );

var bar = require(__dirname + '/../config/env/all.js');

console.log('-.-.-.-.-.-.-.-.-.-. foo after _.assign .-.-.-.-.-.-.-.-.-.-');
console.log(foo);
console.log('-.-.-.-.-.-.-.-.-.-. bar .-.-.-.-.-.-.-.-.-.-');
console.log(bar);
console.log('-.-.-.-.-.-.-.-.-.-. A direct require call .-.-.-.-.-.-.-.-.-.-');
console.log(require(__dirname + '/../config/env/all.js'));

我得到的是:

-.-.-.-.-.-.-.-.-.-. foo before _.assign .-.-.-.-.-.-.-.-.-.-
{ root: '/home/bax/Code/lab/mean/test1',
  port: 3000,
  db: undefined }
-.-.-.-.-.-.-.-.-.-. foo after _.assign .-.-.-.-.-.-.-.-.-.-
{ root: '/home/bax/Code/lab/mean/test1',
  port: 3000,
  db: 'mongodb://localhost/mean-dev',
  app: { name: 'MEAN - A Modern Stack - Development' },
  facebook: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/facebook/callback' },
  twitter: 
   { clientID: 'CONSUMER_KEY',
     clientSecret: 'CONSUMER_SECRET',
     callbackURL: 'http://localhost:3000/auth/twitter/callback' },
  github: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/github/callback' },
  google: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/google/callback' } }
-.-.-.-.-.-.-.-.-.-. bar .-.-.-.-.-.-.-.-.-.-
{ root: '/home/bax/Code/lab/mean/test1',
  port: 3000,
  db: 'mongodb://localhost/mean-dev',
  app: { name: 'MEAN - A Modern Stack - Development' },
  facebook: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/facebook/callback' },
  twitter: 
   { clientID: 'CONSUMER_KEY',
     clientSecret: 'CONSUMER_SECRET',
     callbackURL: 'http://localhost:3000/auth/twitter/callback' },
  github: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/github/callback' },
  google: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/google/callback' } }
-.-.-.-.-.-.-.-.-.-. A direct require call .-.-.-.-.-.-.-.-.-.-
{ root: '/home/bax/Code/lab/mean/test1',
  port: 3000,
  db: 'mongodb://localhost/mean-dev',
  app: { name: 'MEAN - A Modern Stack - Development' },
  facebook: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/facebook/callback' },
  twitter: 
   { clientID: 'CONSUMER_KEY',
     clientSecret: 'CONSUMER_SECRET',
     callbackURL: 'http://localhost:3000/auth/twitter/callback' },
  github: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/github/callback' },
  google: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: 'http://localhost:3000/auth/google/callback' } }
Express app started on port 3000

问题是:我不应该每次都得到相同的结果:console.log(require(__dirname + '/../config/env/all.js'));

4

1 回答 1

0

这已经在评论中得到了回答,但这里尝试了一个更合格的答案并关闭这个话题:

您得到的效果是由于 node.js 模块加载和 lodash _.extend() 的综合影响:

  • 包含的模块只是对象并且它们被缓存,因此每次对与相同物理文件系统路径相关的“require()”的调用都将返回该对象
  • Lodash 的扩展/分配具有令人讨厌的破坏性,它直接操作传递的对象而不是返回一个新对象(例如 Rubys 'Hash#merge()' 会这样做)

所以你有一个对象来代表all.js_.assign()操纵它。任何进一步require()的 's 只会返回相同的修改对象。

如果这是不希望的(在许多情况下确实如此),那么到目前为止我所知道的唯一解决方法是:

var someOptions = {/*...*/};
var extended = _.extend(_.clone(someOptions))
于 2014-08-18T03:07:15.367 回答