# RL-08 前端打包/模組化/套件
## 模組化方法(文章題目)
兩種輸出入方法
- CommonJS(主流)
> export default name
> import name from "aaaa"
- AMD
> var a = require("aaaa")
> a()
## module 模組匯入匯出
### package.json
package.json 相當於 ruby 的 gem file
跑script下的命令。
```json=
"scripts": {
"dev": "parcel src/index.html",
"build": "parcel build src/index.html"
}
```
**在終端機**
* 用 yarn run dev 可以執行dev後面那段
### JS的模組化
將相應功能分到不同JS檔案,相互import與export。
**main.js**
* 測試印 console.log("hi")
* 若無效,刪除parcel-cache與dist兩個資料夾。
**模組aaa.js**
* 變成變數的都可以export
* 三種export方法
* **export default** //預設匯出什麼
* **export { , }** //匯出複數的東西(函式、宣告後的常數都可以)
* 直接在function前面接export(不建議)

* 在另一個main.js可以匯入import進
> import hello from "./aaa.js"
> hello ()
```javascript=
function hello() {
console.log("hello")
}
function world() {
console.log("world")
}
function hi() {
console.log("hi")
}
// 下面沒寫 export there,所以 main.js 那邊收不到,只會收到有寫的
function there() {
console.log("there")
}
// 讓aaa.js預設匯出 hello
// 等等 import 的名字可隨意取,不管怎麼取名預設就是匯出 hello
// 一個檔案只能有一個預設值
export default hello
// 有寫 export 的才能匯出,import 名字要能搭得上
// there 相對來說是私有方法
// 除了{}寫法,也可以直接在 function 前面寫 export
// 只要是變數都可以匯出,不一定要是 function
export { world, hi }
```
**在網頁**
要引用模組的話,要指定型別為模組module
> <script src="scripts/main.js" type="module"></script>
**main.js**
就可以把aaa的內容import進來。像是
> import hello from "./aaa"
> hello()
```javascript=
import dayjs from "dayjs"
const dd = dayjs("2018-08-08")
console.log(dd.year())
console.log("hi")
import hello from "./aaa.js"
import aaa, { hi } from "./aaa.js" // 名字亂寫aaa也行,會輸入預設的(hello)
hello()
console.log(hi)
console.log(aaa)
import { createButton } from "./ui"
const btn = createButton("hello")
document.body.appendChild(btn)
```
**模組ui.js**
做一個按鈕,宣告function,建立元素 document.createElement
再匯出 export {createButton}
```javascript=
// 用JS產生一個btn
function createButton(wording) {
const btn = document.createElement("button")
btn.textContent = wording
return btn
}
export default createButton
```
**main 再匯入**
加到body的最尾端appendChild
為什麼用const呼叫?因為原本模組內就這樣寫,守原來規則。
> import { createButton } from "./ui"
>
> const btn = createButton("hello")
> document.body.appendChild(btn)
## 套件安裝
**npm install dayjs**
= **yarn add dayjs**
兩個都可以安裝套件
yarn 可以一次下載多個,下載速度快(fb做的)
**不要兩個混用**,兩個產生 package.lock 的方式不同,有可能會造成錯誤
- 參數:
--save只用在目前專案,開發過程跟上線都會用到
--saveDev:上線之後用不到,不需要上線(ex:parcel)
= -D
在package.js裡可看到安裝資訊,其中
* devDependencies 上線不需要
* dependencies 上線需要
安裝的套件會在node_moduel裡
### Day.js
[dayjs](https://www.npmjs.com/package/dayjs)
將字串=>時間的套件
* 安裝指令加參數 **--saveDev** 代表只在開發時用
* **安裝的套件會在node_moduel裡**
* 進dayjs的package.js,可看到scripts設定等。
再讓main匯入
> import dayjs from "dayjs"
宣告為dd再印出
> const dd = dayjs("2018-08-08")
>
> console.log(dd.year())
> 或
> console.log(`${dd.day()}/${dd.month()}`)
### Tailwindcss
推薦用,慢慢變主流了
[tailwindcss](https://tailwindcss.com/docs/installation#installing-tailwind-css-as-a-post-css-plugin)
- Tailwindui 收費的,用Tailwind幫你刻好很多東西
- tailwindui alternative
=> tailwindcomponent
- codepen 有支援 tailwindcss 方便自己練習:可以點css做設定
[tailwindplay](https://play.tailwindcss.com/) :可試玩
#### 安裝
* bootstrap給你大框架,整組包好
* tailwind給你小零件,一堆小工具
* 安裝
> yarn add -D tailwindcss@latest postcss@latest autoprefixer@latest
* 依照官方手冊
* 在根目錄建立 postcss.config.js
```javascript=
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
```
* 官方cdn有**非同源錯誤NotSameOrigin**,改用cdnjs版本做(貼在head裡)
* <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.8/tailwind.min.css" rel="stylesheet">
* **語法效果,可以直接實現RWD**
```htmlmixed=
<h1 class="text-4xl md:text-6xl">Hello World??</h1>
<a herf="#" class="bg-blue-300 px-4 py-3 rounded block w-16 text-white hover:text-red-400 hover:bg-blue-500">像是一個按鈕</a>
```
CodePen有直接支援。
#### @apply
@apply 可以組合多個css,寫一個就好,類似 funciton 把要的東西都包好,方便使用。
例: 讓網頁裡的標籤寫 **class=list-item** 就好,不用像inline一樣長。
```css=
.list-item {
@apply .py-1 .px-4 .font-light;
}
```
* **TailwindUI** 可嘗試要收費
* 壓縮檔案,把不會用到的 css 去掉:
在 tailwind.config.js 檔案的 purge 檢查:
purge: [
'./src/**/*.html',
'./src/**/*.js',
]
可參考:[優化生產模式
](https://tailwindcss.tw/docs/optimizing-for-production)
## 前端打包工具
### parcel <=用這個
打包工具,輕鬆設定,對新手友善
可以把多個相同格式檔案打包成一個檔案
前例:
* parcel src去讀index,會去讀一個main.js,連結到main.scss。
* 會後會打包成一個js。
### webpack
打包工具,設定上有點麻煩
垃圾一個
### electron
把 HTML CSS JS 打包成應用程式(如VSCode)
因為也把瀏覽器包進去所以很胖
### esbuild
很快
-----
## foreman 在本機用
開發過程才會用到
* 在Gemfile安裝foreman
* 記得跑 bundle install
### 啟動
* 終端機 foreman s
* 手動建立procfile 在根目錄,內容寫
> web: rails s -p 3000
> webpack: bin/webpack-dev-server
如此一來,啟動時2個一起開。
###### tags: `Rails`