# 1217 JS模組化(依照功能切割)
傳統 JavaScript 沒有內建取得別的 JavaScript 的功能
於是人們就自己發明各式各樣的工具:
browserify / rails assets pipeline / gulp.js / rollup.js / webpack
## 模組化寫法
### 模組化寫法 – commonJS
* NodeJS 的引入方式
* pkg = require('pkg_name') //
//取用,(pkg是相對路徑或套件名稱)
* module.export = ...
//提供,寫在被require的檔案
---
### 模組化寫法 – ES module(已經標準化)
[MDN 文件](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
[ES module: A cartoon deep dive](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/)
import / export 是關鍵字,不是function
---
#### 用 ES module 改寫
`<script src='main.js'></script>`
想引入module,要在html加上type="module"
改寫為`<script type="module" src='main.js'></script>`
將main.js以ES module解析,才可以進行require,同時main.js會變嚴格模式限縮範圍不能隨意指定全域變數(譬如aaa=123)。
```
<script type="module" src='main.js'></script>
<script src='none-es.js'></script>
```
可以同時使用非模組化的JS檔。
#### 語法:
* import moduleDefault from './another.js'
* [MDN docs](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/import#語法)
* export default moduleDefault
* [MDN docs](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/export#語法)
### 例題11
`import addOne from './addOne.js'`
上列為default function寫法,這裡的addOne不用{}且可以自由命名,會引入在addOne.js裡以`export default addOne`明確指定要引入的function,這裡的addOne則是addOne.js裡的一個function名稱
而
`import { timeoutPromise, removeGreeting } from './utils.js'`
在{}內的timeoutPromise, removeGreeting是非default function的名稱,必須以export宣告要引出的function,
如`export const timeoutPromise...`
---
#### 在瀏覽器上不使用 ES module 的狀況
* 直接 <script /> 引入,定義到 window 上(不推薦)
* AMD / UMD(少用)
---
1208
## [NodeJS](https://nodejs.org/)
* 在瀏覽器外面的 JavaScript
* 可以取用系統功能
* 目前最常被拿來處理前端 assets
* Express.js或簡稱Express,是針對Node.js的web應用框架
```
// const fs = require('fs/promises')
const fs = require('fs').promises //內建函式庫fs/promises node12版本不能用上面的寫法
const filename = process.argv[2];
if (!filename) {
console.error("Please provide json filename");
process.exit(127)
}
const main = async jsonFilename => {
// let's start coding
const jsonString = await fs.readFile(jsonFilename, "utf-8")
// console.log(jsonString)
const json = JSON.parse(jsonString)
// console.log(json)
process.stdout.write(JSON.stringify(json, null, 2))
}
main(filename);
```
* await:會暫停async函式執行,等待Promise物件解析,並在resolve時回復async函式的執行。await接著回傳被resolve的值。如果回傳值不是一個 Promise物件,則會被轉換為resolved狀態的Promise 物件。如果Promise物件被rejected,則await會丟出rejected的值
* async AsyncFunction 物件,代表著一個非同步函式,該函式會執行該函式內的程式碼
* fs.readFile(fileName [,options], callback)可以讀取檔案。參數:fileName: 檔案的完整路徑及檔名,格式字串。options: options 可能是一個物件或字串,包含"編碼"及"flag"。這裡預設的編碼是 utf-8 , flag是 “r"。call back: 是帶兩個參數的function,err及file data,當我們執行readFile完成時, 要做的事, 例如: 回傳file data。
* JSON.parse()把一個JSON字串轉換成JavaScript的數值或是物件。
* JSON.stringify將JSON物件(Object)轉成字串
* process.stdout.write
* process.argv
1250前
=======
例題12
12_node-project-json-to-csv
把 JSON 轉換成 CSV
* 建立 NodeJS 專案: npm init 建立package.json
* npm install --save fast-csv :用--save可以紀錄安裝的套件fast-csv在package.json檔,套件都只安裝在專案內
安裝後產生出來的檔案
package-lock.json
node_modules
在package.json檔中修改"scripts": {
"main": " node main.js posts.json out.csv"
},終端機執行npm run main就會執行node main.js posts.json out.csv
=======
`Array(3).fill()`
`Array(3)`會生成一個長度為3的空陣列,[ , , ]
`fill(要塞入的東西)`會在每個位置塞入括弧內的東西
在這裡會變成=>[undefine,undefine,undefine]