# 手把手將vue component打包成套件,丟到gitlab package registry-內網篇
###### tags: `gitlab` `package registry` `npm package`
因公司專案需求,不同的專案要有風格類似(或同一組)的套件,所以來記錄是怎麼把做的vue component包成package丟到公司內部私有的gitlab上!(╯✧∇✧)╯
## :memo: 事前檢查以下東西準備了沒
- [ ] 一個vue的專案
- [ ] 私有Gitlab 帳號
- [ ] Gitlab 空的專案
- [ ] Gitlab CI/CD Runner(如果要自動化部屬,一定要有它!一定喔⎝(◕u◕)⎠)
## 建立元件
現在,先建立一個元件然後學習如何打包,我們用最簡單的button套件當作本次的練習
所以要新增一個專案來練習打包元件:
```
vue create <project>
```
### 新增component
新增一個專案之後打開它,然後在`components`的資料夾底下新增一個`button.vue`檔,內容如下:
```htmlembedded=
<template>
<div class="smd-button">
{{ value }}
</div>
</template>
```
```javascript=
<script>
export default {
props: {
value: {
type: String,
default: "",
},
},
};
</script>
```
```css=
<style scoped>
.smd-button {
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
cursor: pointer;
width: 120px;
padding: 8px;
background: yellow;
}
</style>
```
### 元件安裝檔
在componens資料夾內新增`index.js`檔,並import剛剛的`button.vue`檔
```javascript=
import Button from './button.vue'
Button.install = function (Vue) {
Vue.component('my-button', Button)
}
export default Button
```
### vue.config.js設定
因為是把css寫在`.vue`檔裡面,為了要在打包的時候能不要把裡面的css獨立變成一包`.css`檔,要在`vue.config.js`檔內加入以下設定:
```javascript=
module.exports = {
css: { extract: false }
}
```
### build指令異動
修改package.json內,script底下的build properties:
```
vue-cli-service build --target lib --name <libname> <entry>
```
* libname: 打包後的檔名
* entry: 要打包的入口,這邊就是剛剛在components底下新增的`index.js`

### 進行打包
```
npm run build
```
打包完之後可以看到專案底下多了一個`dist`的資料夾,展開來看看會看到以下幾個檔案:

這時候我們第一個元件就完成了!接下來就要來設定要上傳到gitlab package registry的一些設定了。
## Gitlab package registry 設定
### gitlab deploy token
**Gitlab專案 > Settings > Repository > Deploy tokens**
新增Token的名稱,並將`read_package_registry ` `write_package_registry`打勾

送出之後會得到一組Token

### 專案內部檔案設定
#### .npmrc
要在套件專案底下新增一個`npmrc`檔,並加入以下內容
```npm
# Set URL for your scoped packages.
# For example package with name `@foo/bar` will use this URL for download
@<scope>:registry <your domain name>/api/v4/projects/<project id>/packages/npm/
# Add the token for the scoped packages URL. Replace <your_project_id>
# with the project where your package is located.
//<your domain name>/api/v4/projects/<project id>/packages/npm/:_authToken=<your token>
```
::: info
:round_pushpin: scope就是看gitlab專案是隸屬何者項目來命名
* group project: {scope} 就是 group name
* personal project: {scope} 就是 user name
:round_pushpin: your domain name:私有gitlab的網域
:round_pushpin: project id :gitlab專案上的project id
:round_pushpin: your token :剛剛在gitlab設定的deploy token
:::

再來要改一些`package.json`內的設定
```json=
{
"name": "@<scope>/<package name>",
"version": "0.1.1",
"main": "dist/smd-package.common.js",
"publishConfig": {
"@<scope>:registry": "<your gitlab domain>/api/v4/projects/<project id>/packages/npm/"
}
}
```
要調整的property有以下這些
* name: 要改成符合Gitlab package registry的命名格式
* version: 本次要部署的版本號
* private: 這個屬性要拿掉
* main: 主要的檔案入口,剛打包後的`<lib Name>.common.js`檔
* publishConfig: 要發布的設定
::: info
:round_pushpin: package name 一定要是 @{scope}/ 開頭
* group project: {scope} 就是 group name
* personal project: {scope} 就是 user name
:::
#### .gitignore
沒錯~就是要把.npmrc放進去,這個傢伙等等不用一起上到gitlab,就讓它在這邊待著ヽ( ° ▽°)ノ
```
.npmrc
```
#### .gitlab-ci.yml(如果有需要用自動化部屬在寫)
這個檔案的內容[官網](https://docs.gitlab.com/ee/user/packages/npm_registry/#publish-an-npm-package-by-using-cicd)就有提供了,image這邊因為內網拉不到官方的repo,所以有先將node image丟到公司內部的harbor上。
```yaml=
image: <harbor domain image url>/node:latest
stages:
- deploy
deploy:
stage: deploy
script:
- echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}">.npmrc
- npm publish
```
好的,現在萬事俱備只欠部署了(ง๑ •̀_•́)ง
## :rocket: 部署GOGO
### 專案內加入git (已經有remote repo的話可省略此步驟)
```
cd existing_folder
git init
git remote add origin <gitlab project url>
git add .
git commit -m "Initial commit"
```
### 將專案推上至gitlab
```
git push -u origin master
```
這時候可以看到剛剛的專案已經成功推至gitlab上
### 發布
因為私有的Gitlab CI/CD自動部署時有點問題,所以這邊先用手動部署代替
在專案底下輸入:
```
npm publish
```
npm就會開始幫我們打包東東,執行完之後就會看到類似以下的訊息,就代表已經發布成功了⁽⁽٩(๑˃̶͈̀ ᗨ ˂̶͈́)۶⁾⁾

### 查看結果 do re mi so *ଘ(੭*ˊᵕˋ)੭* ੈ✩‧₊˚
前往Gitlab的專案底下,點開**Package Registry**,就可以看到裡面有一個熱騰騰的套件了

## Package & Registries上的套件用法
既然已經將套件上傳成功,當然是要在專案內拉下來用看看,過程需要設定一些東東,所以在這邊也順便紀錄一下。
### npm config setting
在terminal輸入以下指令
```
npm config set @<scope>:registry <your domain name>/api/v4/packages/<project id>/npm/
npm config set -- '//<your domain name>/api/v4/packages/npm/:_authToken' "<your_token>"
```
* scope: group name 或 user name
* token: gitlab 專案下的deploy token
* project id: 專案id
* your domain name: 要改成內部私有的網域
設定完之後,可以在要使用這個套件的專案底下輸入:
```
npm install --save @<scope>/<package name>
```
如果不知道要輸入什麼的話,可以去專案底下**package registry > package裡面**也有安裝的指令可以複製

安裝完之後,就可以看到`node_module`底下,有剛剛安裝的套件包

## 引入套件
再來就跟一般在用npm install下來之後的套件的引入方式一樣了,在main.js內部使用以下指令:
```javascript=
import Vue from 'vue'
import Button from '@<scope>/<package name>'
Vue.use(Button)
```
就可以在Vue的全域底下使用自己的套件囉!
```
<my-button value="我是按鈕1">
```

## 尾聲
內網安裝 vue component方式就到這邊結束,希望大家也能夠成功將自己的套件推到gitlab package registry上面,有問題的話也都歡迎指教,謝謝大家!٩(。・ω・。)و
參考文獻
* [我的第一個 npm 套件:把 vue component 打包到 npm 吧](https://medium.com/@debbyji/%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E5%80%8B-npm-%E5%A5%97%E4%BB%B6-%E6%8A%8A-vue-component-%E6%89%93%E5%8C%85%E5%88%B0-npm-%E5%90%A7-e5f9a6901c5c)
* [GitLab NPM Registry Demo](https://www.youtube.com/watch?v=yvLxtkvsFDA&t=892s)