2014-01-15 4 views
0

Я пытаюсь понять функции assign/extend в 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(), является ссылкой на объект module.exports, который был изменен _.assign(), поэтому, когда я вызываю require() снова, я получаю ссылку на тот же объект экспорта измененного модуля ... это правильно? –

+0

Да, именно :-) – Bergi

ответ

0

Это был дан ответ в комментариях уже, но вот попытка на более квалифицированный ответ и закрыть эту тему:

вы получаете эффект обусловлен совместным действием node.js загрузки модуля и lodash _.extend():

  • Включенные модули только объекты, и они кэшируются, поэтому каждый последующий вызов 'требуют(), относящиеся к тому же пути физической файловой системы будет возвращать объект, который
  • Lodash расширим/assign раздражает деструктивным, он управляет переданным объектом напрямую inst чтобы вернуть новый объект (например, 'Hash # слияния()' Rubys бы)

Таким образом, у вас есть один объект, представляющий all.js и _.assign() манипулирует этим. Любые дополнительные require() будут просто возвращать тот же измененный объект.

Если это нежелательно (и во многих ситуациях), только временное решение я не знаю до сих пор это:

var someOptions = {/*...*/}; 
var extended = _.extend(_.clone(someOptions)) 
Смежные вопросы