2017-09-14 126 views
0

比方說,我有一個明確的Web應用程序針對我加入一些標準的中間件:Express:app.use()將middeware添加爲多個參數與單獨的語句?

app.use(express.static(config.staticRoot, { maxAge: 300000 })); 
app.use(compression()); 
app.use(cookieParser()); 

app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: true })); 

app.use(passport.initialize()); 
app.use(passport.session()); 

什麼是上面的區別,如果我把它稱爲是這樣的:

app.use(
    express.static(config.staticRoot, { maxAge: 300000 }), 
    compression(), 
    cookieParser(), 
    bodyParser.json(), 
    bodyParser.urlencoded({ extended: true }), 
    passport.initialize(), 
    passport.session() 
); 
+0

'app.use'只是[Router#use()']的代理(https://github.com/expressjs/express/blob/master/lib/application.js#L178)。 – lifeisfoo

+0

通過文檔查看它看起來像這兩者之間的唯一區別是,如果您想爲中間件功能指定單獨的路徑,則可以使用單個app.use調用。 app.use('/ path1',compression());否則,如果他們都將在相同的路徑上,那麼app.use函數允許您定義一系列中間件函數,就像您在第二個示例中所做的一樣。 – Rnice4christ

回答

1

是有區別的

看看Express文檔

app.use([path,] callback [, callback...]) 

callback - 回調函數可以是:

  • 中間件功能。
  • 一系列中間件功能(以逗號分隔)。
  • 一系列中間件功能。
  • 以上所有組合。

可以提供表現就像中間件多個回調函數,除了這些回調可以調用下一個(「路徑」),以繞過其餘航線回調(S)。您可以使用此機制在路線上施加先決條件,並在沒有理由繼續使用當前路線時將控制權交給後續路線。

所以要相信,你的中間件執行,寫他們作爲你的第一個版本

還要注意,默認情況下,路由器使用/路線,當你單獨叫app.use每個中間件,你有更多的控制哪些路線他們應該插

// GOOD 
app.use('/', express.static(config.staticRoot, { maxAge: 300000 })); 
app.use('/', compression()); 

// BAD 
app.use('/', express.static(config.staticRoot, { maxAge: 300000 }), compression(), cookieParser()); 

不好,因爲compression()中間件可以稱之爲next('/someOtherPage');這將跳過結合其他middlwares到/

+1

你確定最後一部分?我認爲調用next('/ someOtherPage');'會被視爲傳遞錯誤到'next'。我相信,當文檔中提到next('route')'它實際上意味着字符串''route'',而不是其他路徑的路徑。 – skirtle

+0

好點,將盡快檢查並更新答案 –

+0

我確實看到了有關'next'('route')'的一點 - 我想它並不常用。如果我們假設(或更好地驗證)那些中間件從來不會調用next('route')'是否等價?對於沒有路徑的中間件路由,效果如何?(如我在示例中所用的那樣?) –

0

用單獨的語句調用app.use()要比多個參數多得多flexible。以下是一些示例:

  1. 如果某些中間件僅在特定條件下應用會怎樣?像:

    if (isProductionMode) { 
        app.use(middlewareOnlyInProduction); 
    } else { 
        app.use(middlewareOnlyInDevelopment); 
    } 
    

    當然你也可以實現類似的邏輯與app.use.apply(...)和傳遞正確的中間件陣列,但這樣會增加複雜性。

  2. 如果某些中間件僅在異步調用後應用,該怎麼辦?

    app.use(middlewareA); 
    aPromise.then(function() { 
        app.use(middlewareB); 
    }).catch(function() { 
        app.use(middlewareC); 
    }); 
    

    對於「多參數」解決方案,沒有辦法實現這樣的邏輯。

使用「獨立語句」解決方案,無論何時何地都可以添加中間件。使用「多種參數」解決方案,您只能添加一次中間件,這是非常有限的。