譯:如何構造個人JavaScript文件?

前言

看到英文技術文檔、快哭了。含着淚也要把他讀完。 原文How I Structure My JavaScript Filejavascript

內容

不少人都在問我怎麼寫個人JavaScript——好吧,這是一個謊話,沒人問我,可是若是他們這麼作了,我想指出這篇文章。在使用了多年的PHP以後,在閱讀了乾淨代碼(和其餘書籍)以後,我在多年中採用了個人代碼風格。是的,PHP,不要敲它,它有一個偉大的社區和偉大的編碼標準。固然,多年來和別人一塊兒寫做,跟隨不一樣公司的風格。java

結構並不依賴於JS模塊,但我如今傾向於只編寫JS模塊,因此我將使用這些模塊。數據庫

結構,總結以下:瀏覽器

入口

在文件的頂部是導入。這是有道理的,他們比其餘任何東西都要高。進口的順序可有可無,除非你使用一些掛鉤(好比babel hook),因此我傾向於選擇:babel

  1. 本地模塊-節點本地的東西。函數

  2. 庫模塊- lodash, knex,等等。工具

  3. 本地庫——好比../db。測試

  4. 本地文件- like ./helper或相似的。fetch

讓個人模塊保持有序,讓我更容易看到我在導入什麼,以及我實際上在使用什麼。當我開始編寫代碼時,我也傾向於以這種方式編寫依賴關係。this

我傾向於不關心字母排序(除了破壞導入以外),我也沒有看到它的一個點。

本地模塊 我傾向於將本地模塊放在最上面,並以這樣的主題保持一個清晰的組織:

若是我在瀏覽器中,顯然跳過這一步。

庫模塊

我儘量只從庫中導入我須要的東西,可是,我又一次將它們分組到某個主題中。

我還注意到,若是我正在執行一個默認的導入(例如。我傾向於把它放在個人庫模塊的頂部,並將被破壞的導入下降。沒有必要,但我喜歡它的視覺效果。

Local/Internal libraries

在本地庫中,我指的是本地共享的模塊,好比db。設置與書架鏈接的js文件。或者,在個人工做中,咱們有幾個庫處理咱們產品中使用的數字和計算。

Local files 最後,我導入本地文件,這些文件一般與我正在處理的文件或一個目錄(最多)在同一個文件夾中。例如,我爲Redux寫了一個減速器,並把它放在一個單獨的文件夾中。在該文件夾中,我還保留了一個助手文件,一般命名爲[reducer name]Helpers.js:

Constants

在導入全部依賴項以後,我一般會作一些前期工做,這些工做將在模塊的其他部分中使用。例如,我從書架實例中提取了knex。或者我能夠設置值常數。

使用很是量一般表示我依賴於某種類型的單例。我儘可能避免使用它們,但有時它是必要的,由於沒有簡單的其餘方法來完成它,或者它不重要(好比一次性命令行腳本)。 Exports

在我基本設置了全部模塊級別的依賴項以後:不管它們是常量值仍是導入庫,我都試着將個人導出分組到文件的頂部。基本上,這就是我把功能做爲模塊的粘合劑,實現模塊的最終目的。

在Redux的狀況下,我可能導出一個單一的減速器,而後將工做分解並調用相關的邏輯。在ExpressJS的狀況下,我可能在這裏導出全部的路由,而實際的路由邏輯在下面。

我想說的是,這並非我出口功能的惟一部分。

我感受模塊系統的工做方式使得在暴露最窄的API和導出函數在測試中使用它們之間的界限變得有點困難。

例如,在上面的例子中,我歷來不想在模塊以外使用calculateSomething。我不徹底肯定OOP語言是如何處理測試私有函數的,但這是一個相似的問題。 Core Logic

這看起來很奇怪,但核心邏輯對我來講是最重要的。我徹底理解當人們翻轉導出和核心邏輯時,但這對我來講頗有效,緣由有不少。

當我打開一個文件時,頂層函數會告訴我抽象步驟中將會發生什麼。我很喜歡這樣。我一眼就能看出文件的做用。我作了大量的CSV操做,並將其插入到DB中,而頂級函數始終是一個容易理解的流程,它有一個相似的流程:fetchCSV aggregateData insertData terminate script。

核心邏輯老是包括從上到下的出口。在內聯的例子中,咱們有這樣的東西:

注意,readCSV沒有。這聽起來很普通,我應該把它放到一個helper文件中,而後將它導入上面。除此以外,你能夠看到個人出口,而不是進退兩難。我不但願在模塊外部提供聚合數據,但我仍然但願測試它。

在此以外,我傾向於把「meatier」函數放在上面,下面的函數更小。若是我有一個特定於模塊的實用函數,一個我在多個地方使用的函數,但只在模塊中使用,我將把它們放在底部。基本上,個人命令是:複雜性+使用。

因此順序是:

  1. 核心邏輯函數——由頂級導出使用的函數。

  2. 更簡單/更小的函數——核心邏輯函數使用的函數。

  3. 實用函數——模塊周圍多個地方使用的小函數(但不導出)

Core-logic functions 核心邏輯函數就像我導出的函數的「sub-glue」。根據模塊的複雜性,這些可能存在,也可能不存在。功能的分解不是必需的,可是若是一個模塊足夠大,核心邏輯函數就像主函數中的步驟。

若是你寫的是反應或角度,這些你的組件將是我上面提到的出口函數。可是,核心邏輯函數將是各類偵聽器或數據處理器的實現。用Express,這些將是您的特定路線。在一個Redux減速器中,這些將是在鏈條上足夠遠的單獨的減速器,沒有一個開關/case語句。

若是您處於角度,那麼在類中組織這些函數而不是在整個文件的範圍內是徹底公平的。

Simpler/Smaller functions

這些函數一般是核心邏輯和純實用程序之間的中間步驟。你可能會用到它們,或者它們可能只是一個比效用函數更復雜的tad。我可能會刪除這個類別,並說「寫你的功能,以減小複雜性或工做量」。

這裏沒有說起。也許onHandleInput事件監聽器須要一些邏輯來處理$event數據,因此若是它是純的,您能夠將它從類中刪除,若是不是,您能夠在類中保留它:

Utility functions

最後,效用函數。我傾向於組織最接近我使用它們的工具。在相同的文件中,或者相同的文件夾(必要時),相同的模塊,等等。每次使用從文件中擴展到項目的根或它本身的NPM模塊時,我都將函數移出一個級別。

在我看來,效用函數應該始終是一種純方法,這意味着它不該該在它的範圍以外訪問變量,並且應該只依賴傳遞到它的數據,並且不須要任何形式的反作用。除非使用實用程序函數來訪問API或訪問數據庫。由於這些被認爲是反作用,因此我認爲它們是惟一的例外。

Anything else? 固然!我認爲每一個人都有本身獨特的書寫方式。上面所描述的結構在我多年來天天編寫大量代碼的過程當中很是有效。最終,許多細微的差異開始出現,我發現本身編寫代碼更快,更喜歡它,而且更容易調試和測試。

在我完成這篇文章以前,我想和你們分享一些我已經習慣了的編碼,它們與文檔結構的關係更少,更多的是在編寫實際代碼時更傾向於使用小的偏好。

早期的回報

當我發現早期的回報時,那是一瞬間。當您能夠提早返回時,爲何要在else語句中封裝大量代碼?

個人經驗法則是,若是早期的返回條件小於其他的代碼,那麼我將寫早期的返回,可是若是不是,我將顛倒代碼,這樣較小的代碼塊老是提早返回。

早期的回報在交換機上也很出色,我是Redux的超級粉絲。

分號塊

雖然我再也不使用它(沒有更漂亮的支持),但我老是用分號來終止函數連接,在一個單獨的行上,一個縮進到鏈的縮進的左邊。這就建立了一個整潔的代碼塊,代碼不僅是掛在那裏。

固然,這意味着我也喜歡用分號來代替。

Or better written, it might look like this:

總結

使用的是有道在線翻譯,若有不正確之處還望大佬指出。

相關文章
相關標籤/搜索