---
# System prepended metadata

title: RL-08 前端打包/模組化/套件
tags: [Rails]

---

# 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（不建議）

![](https://i.imgur.com/9iP29QA.png)

* 在另一個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`