iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 29
0
Modern Web

想成為超級開源貢獻者嗎 ? 新手也能用Javascript寫出專業高效能的"新世代"開源庫系列 第 29

大型項目管理工具Lerna

甚麼是Lerna呢?

Lerna是一種工具,用於優化使用git和npm管理多包存儲庫的工作流程。
lernaJs是由Babel團隊出的一個大型項目管理工具。因為Babel包含很多子包,以前都是放在多個倉庫裡的,管理比較困難,

接下來我們就直接實作喔

  • 安裝
npm install --global lerna

  • 建立一個git存庫
git init lerna-repo && cd lerna-repo
  • Lerna倉庫初始化
lerna init

小提醒 : package.json檔案裡,有一個 "private": true 他的意思是檔案部會發部(publish)喔。發布時可以將它做修改

{
  "name": "XXX",
  "private": true,
  "devDependencies": {
    "lerna": "^3.22.1"
  }
}
  • 再來我們先創建一個子庫八
lerna create firstRepo

然後我們會得到這樣的目錄

lerna-repo/
  packages/          // 子包都放在这个目录中
      firstRepo/
          _tests_
            firstRepo.test.js
          lib
            firstRepo.js
          package.json
          read.me
  package.json
  lerna.json         // lerna js的配置文件
  

在這裡可以把firstRepo當成一個庫,裡面會有單元這是為編譯的原始碼和read.me

接下來我們開始繼續時做了喔

  • 先在lerna.json 添加 自動添加CHANGELOG.md 設置
"command": {
  "publish": {
    "conventionalCommits": true
  }
}

記得先 下載套件喔 npm i rollup @rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-terser --save-dev,以下是我的範例

script/build.js

const rollup = require('rollup'); // 引入rollup
const terser =require('@rollup/plugin-terser').terser // 壓縮代碼的插件
const commonjs = require('@rollup/plugin-commonjs') // rollup默認支持es6的模塊系統,需要支持commonjs的話需要這個插件
const babel = require('@rollup/plugin-babel') // rollup的babel 插件
const args = process.argv[2] // 拿到 npm run build packName 中的packName

const projectPath = `./packages/${args}` // 子包所在的路勁

// 輸入的文件配置
const inputOptions = {
  input: `${projectPath}/src/index.js`,
  plugins: [
    babel({ // babel文件的設置,會讀取根目錄的babel.config.js文件配置
      runtimeHelpers: true,
      exclude: 'node_modules/**'
    }),
    commonjs(),
    terser()
  ]
};
// 輸出的配置
const outputOptions = {
  file: `${projectPath}/lib/index.js`,
  format: 'esm', // 引出的方式為es6的方式
  name: `${args}` // 輸出可引用名為package的名字
};

async function build() {
  // create a bundle
  const bundle = await rollup.rollup(inputOptions); // inputOptions放在這裡

  console.log(bundle.watchFiles); // an array of file names this bundle depends on

  await bundle.write(outputOptions); // outputOptions放在這裡
}

build();
  • 而測試也一樣會放在script 資料夾底下,因為我們要運行所又package的測試,所以我們會用到jest api
const rawArgs = process.argv[2] // 獲取包名
const testFile = process.argv[3]|| '' // 獲取測試文件名
const path = require('path')
let rootDir = path.resolve(__dirname, '../')


rootDir = rootDir + '\\packages\\' + rawArgs // 拼出包的路勁

const jestArgs = [
  '--runInBand',
  '--rootDir', rootDir, // 傳入包路徑
  testFile?`${testFile}.spec.js`:'' //
] // jest 的一些配置

console.log(`\n===> running: jest ${jestArgs.join(' ')}`)

require('jest').run(jestArgs) // 執行

  • 然後在package.json加入以下script:
"scripts": {
    "build": "node script/build.js",
    "test": "node script/test.js"
}
  • 最後在eslint和commitlint直接在跟木入設置就可以了喔

其他重要指令

  • 依賴相關
    • lerna bootstrap //所有子包更新依賴
    • lerna add // 所有子包都添加這個依賴
    • lerna add --scope = // 給pkgname添加moduleName的依賴
    • lerna add --scope = // 給pkgName2中添加pkgName1,包內的互相引用,會復制pkgName1到pkgName2中
  • 版本發布相關
    • lerna changed //查看哪些package 發生過更改
    • lerna diff //更改的具體內容
    • Lerna publish 版本發布

小提醒 如果發布前(Lerna publish)發生錯誤,可以檢查看看是不是沒有git commit喔

補充

如有興趣的朋友,這裡提供我的Lerna模板 https://github.com/tp953704/lerna-babel-rollup-ts__template
給你們參考,裡面有配置好rollup babel typescript 等等相關配置。
有任何問題或有更好的方式都可以在下方留言區一起討論喔

總結

今天就大概講到這裡喔,剩下的就交給大家完成了喔,最近天氣開始轉涼,要注意保暖。
畢竟有好的身體才可以專心寫CODE

參考資料

上一篇
大型項目管理 MonoLith Multi-Repo Mono-Repo
下一篇
心得
系列文
想成為超級開源貢獻者嗎 ? 新手也能用Javascript寫出專業高效能的"新世代"開源庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言