今天來聊聊如果你的code變得越來越大怎麼辦?你不想要放在同一個檔案裡啊, 其實之前我們也有稍微提到過,就是使用 module
,常常我們也在code裡寫到 import
, export
對這些就是module。
如果有注意到的話,之前的文章也有提到module這個詞不少次,都在定義一個檔案一開始的時候,譬如:
module Optional exposing (..)
type Optional a = Some a | None
isNone : Optional a -> Bool
isNone optional =
case optional of
Some _ ->
False
None ->
True
這個就是我這個檔案要全部給外界讀取,就會有 exposing (..)
, 這個module的名字就叫做 Optional
。
如果你要使用這個module,可以這樣:
import Optional
noService : Optional.Optional a -> Optional.Optional a -> Bool
noService shoes shirt =
Optional.isNone shoes && Optional.isNone shirt
用 import Optional
就可以了,使用裡面的type或function 前面就要加上 Optional
, 譬如Optional.Optional a
。但是這樣有點太長了,通常我們會用一個關鍵詞: as
。
import Optional as Opt
noService : Opt.Optional a -> Opt.Optional a -> Bool
noService shoes shirt =
Opt.isNone shoes && Opt.isNone shirt
如上例,我們用 as
就可以取一個在這個檔案裡的名字來替代這個module的本名。
但是如果還是覺得這樣太長太麻煩怎麼辦?沒關係,我們還有一個關鍵字叫 exposing
:
import Optional exposing (Optional)
noService : Optional a -> Optional a -> Bool
noService shoes shirt =
Optional.isNone shoes && Optional.isNone shirt
用了這個 exposing
, 你就可以直接使用 Optional
的type了。我們寫 Optional a
就可以簡單很多。可是你發現那function怎麼還是要寫個 Optional.isNone
?因為這裡我們只有exposing type而已,如果要全部的,而且不要有前綴詞,就要 import Optional exposing (..)
以下的例子,你看看,能不能看出為什麼這樣寫是合理的?
import Optional as Opt exposing (Optional)
noService : Optional a -> Optional a -> Bool
noService shoes shirt =
Opt.isNone shoes && Opt.isNone shirt
在你的 elm-package.json
有一行:
"source-directories": [
"src",
],
也就是說如果你 import Optional
, 那他會去找 /src/Optional.elm
, 所以如果你有放在譬如"hello/src"
你也要把這個加到source-directories裡。
"dependencies": {
"elm-lang/core": "4.0.2 <= v < 5.0.0",
"elm-lang/html": "1.1.0 <= v < 2.0.0"
},
因為有些module不是你自己寫的,那就要用別人寫的,就要放在 dependencies
裡,elm會幫你裝好找好。
我們在之前有一個 elm SPA的例子,就是一個很大的檔案,裡面有很多module。譬如他有一個Views
的資料夾,裡面有 Views.Form
, Views.User.Follow
就是一個個獨立的module,之間就是用這些 import
和export
的方法。詳細的分割和想法的邏輯都在文章裡可以一看。