2014-01-15 76 views
0

我試圖瞭解lodash中的賦值/擴展函數,因爲我碰到了一個非常混亂的結果,通過mean.io棧設置。Lo-dash擴展/分配默認行爲

這裏:

'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'));

+0

你得到相同的對象,但你已經修改了它之間? – Bergi

+0

嗯,哦。我想我明白了。我從require()得到的是對由_.assign()修改的module.exports對象的引用,所以當我再次調用require()時,我得到對同一個修改模塊導出對象的引用...是這個對? –

+0

是的,正好:-) – Bergi

回答

0

這已經回答了在評論了,但這裏有一個更合格的答卷,並關閉這個主題嘗試:

你得到的效果是由於Node.js的模塊加載的綜合效應和lodash _.extend():

  • 包含的模塊只是對象,他們被緩存,所以每個後續調用「要求()」與相同的物理文件系統路徑將返回對象
  • Lodash的延伸/ assign是令人討厭的破壞性的,它直接操縱傳入的對象inst返回一個新對象(例如, Rubys'Hash#merge()'會這樣做)

所以你有一個對象代表all.js_.assign()操縱。任何進一步的require()將只會返回相同的修改對象。

如果這是不期望的(並且在許多情況下,它是),唯一的解決辦法,我知道的,到目前爲止是這樣的:

var someOptions = {/*...*/}; 
var extended = _.extend(_.clone(someOptions))