npm配合gitlab-runner避免分支設定不同步

gitlab CI/CD script(.gitlab-ci.yml)理想上要一個版本應付所有分支,且npm install/build的專案建立的資料夾(dist, node_modules)不該被放到repositoy中,但通常又希望拿build好的專案結果直接部屬在正式環境,可以透過下面這些方式來完成。

local開發環境排除不必要目錄

因為如果npm install/build產生的dist, node_modules目錄也跟著被commit到repository,雖然對於deploy很方便,但是無形中浪費空間,而且js script被minify之後,等於每次commit都會是一堆difference。所以從開發的branch(develop branch)開始就應該加上 .gitignore

$ more .gitignore
# dependencies
/node_modules
/dist

Build for production

在production環境部屬已經build好的專案是有些好處的,例如不用在production安裝nodejs, npm 等工具,也可以避免build fail問題。所以可以寫 .gitlab-ci.yml利用gitlab-runner來對master branch做build的工作,並將結果放到release儲存空間(或者直接開個 release branch)。

build_for_prod:
  stage: build_and_save_to_prod_branch
  tags:
    - YOUR-RUNNER-TAG
  only:
    - master
  script:
    - git checkout PROD_BRANCH
    - git pull http://YOUR_GIT_REPOSITORY PROD_BRANCH
    - git pull http://YOUR_GIT_REPOSITORY master
    - cd WebClient
    - npm ci
    - npm run build:prod
    - echo "Finish build!"
    - cd ..
    - git add .
    - 'git commit -m "TEST message to PROD_BRANCH"'
    - git push -f http://YOUR_GIT_REPOSITORY PROD_BRANCH

但是因為 .gitignore 把 dist 排除,所以會變成 build 完沒有東西可以commit。因次要把 .gitignore 修改

$ more .gitignore
# dependencies
/node_modules
#/dist

但這樣會變成 master branch 與 develop branch 的 .gitignore 並不一致,日後若在 develop branch 有做修改,merge 進 master 後,整個 ci/cd 又會掛掉。所以會希望從 develop branch 就把 .gitignore 修改,留下 dist 路徑,u並新增 dist/.gitignore

$ more dist/.gitignore 
# Ignore everything in this directory
*
# Except this file
!.gitignore

npm build固定清除目錄資料

可是當每次執些 npm build的時候,dist目錄固定會被清空,.gitignore也不能倖免。這樣會導致本機開發時dist目錄會不小心又被加入 repository中。
解決方法是從webpack.config.common.js下手,設定CleanWebpackPlugin的 cleanOncdeBeforeBuildPatterns,把 dist/.gitignore排除。

// other codes
 plugins: [
        new CleanWebpackPlugin({
            cleanOnceBeforeBuildPatterns: ["!dist/.gitignore"],
        }),
//other codes

Ref: https://stackoverflow.com/questions/56762087/why-does-my-webpack-cleanup-plugin-delete-my-exclude-files