# 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]