0%

如何將 React Component 發布到 npm

最近剛結束公司的一個 issue,要將 gss-webchat (React 專案) 裡面的 component 讓其他 React 專案也可以做使用,在過程中踩到了幾個雷跟大家分享一下

一開始定義的需求

原先我們這個專案就有用 webpack build 出一版 es5 的 js 檔提供其他專案(不是使用 react,一般 MVC 的那種)當作外部 js 引入即可直接做使用,這隻 js 有提供幾個功能

  1. GSSWebChat

    提供 createBasicWebChatcreateMinimizableWebChatclearStorage 三個方法來讓使用者

    • 建立一般 webchat (沒有外匡,可自定義大小)
    • MinimizableWebChat (可縮小放大的 webchat,縮小時會變成一個圓形小 icon 縮在螢幕角落)
    • clearStorage (清空 webchat 所用到的 session storage, webchat 會將 user 資料存在這邊方便得知 user 是誰來載入歷史資料,清空則等於開啟新對話)
  2. WebChatApi:

    提供使用者使用 BotFramework WebChat 原生方法

所以一開始希望我們 build 出來的這隻 js 檔可以同時被當作一般外部 js 引入,也可以當作 Component 被引入,所以做了以下的事情

  • 在 export default 中加入 ComponentsUtils

    index.ts:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    + const Components = {
    + WebChat
    + MinimizableWebChat
    + }

    + const Utils = {
    + Storage,
    + Store,
    + WebChatToggleStateObservable: {
    + ...WebChatToggleStateObservable,
    + notify
    + }
    + }

    + export {
    + Components,
    + Utils
    + };


    window.GSSWebChat = {
    createBasicWebChat,
    createMinimizableWebChat,
    clearStorage: Storage.clear
    };

    目的是希望別人引入時可以像這樣引入 Components 和 Utils 來做使用

    1
    2
    import * as GSSWebChat from 'build 出來的 js'
    const {Components,Utils} = GSSWebChat

    但是事與願違,這麼做會得到一片慘紅 QQ

    截圖 2020-09-25 上午10.44.40

    會這樣的原因是因為 webpack build 出來的 js 檔是不能用 import/export 這種方式引入的,也是過了好幾種不同的 webpack librarytarget 設定方式,像 commonjsumdamd 等都還是無法引入

    更新:

    後來發現如果將 webpack.config.jsmode 改為 development就可以引入了,這部分之後要在研究一下

尋找其他方法

後來想說那可不可以不要 build 成一包 js 檔,改放到 npm 上面給別人直接 npm install 下來當作一般套件做使用就可以了,但由於這項專案是公司產品,所以不能對外公開,但要自己架一個 private npm 好像有點麻煩,所以就上網查查有什麼別的方式,結果還真的被我找到了

npm install from GitLab/GitHub

先附上連結

這個方法簡單來說就是將專案 build 好之後放到 GitLab/GitHub 上面,其他人可以透過

1
npm install git+https://<token-name>:<token>@gitlab.com/Username/Repository#{branch|tag}

來安裝 GitLab 上面的某個專案,而且還可以預防外人安裝 xdd (因為要 access 到公司的 gitlab 需要有公司的帳號)

要達成上面的功能有幾件事要做

Build 出專案

首先,主管希望 build 出專案的工具用得越少越好,最好是原本 build gss-webchat會用到的工具就夠了,所以我只有利用 tsc(typescript compiler) 來做到這件事

  1. 建立 tsconfig.gen-lib.json:將 typescript 轉換成 es5 的 js 檔

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
    "compilerOptions": {
    "declaration": true, // 加入這行才會順便產生出 .d.ts 讓 import 時有類別檔可以參考
    "outDir": "./lib/", // 設定編譯完輸出的位址
    "module": "commonjs", // 使用 commonjs (node 支援的型態)
    "target": "es5", // 轉成 es5
    "jsx": "react",
    "esModuleInterop": true,
    "lib": [
    "dom",
    "es2016"
    ],
    "allowJs": true
    },
    "include": ["src/**/*"]
    }
  2. 在 package.json 的 script 中加入

    1
    2
    3
    4
    5
     "scripts": {
    ...
    + "build:lib": "tsc -p tsconfig.gen-lib.json && npm run build:copy",
    + "build:copy": "cpx \"src/**/*.!(ts|tsx|js)\" \"./lib\" "
    },

    “build:lib”:將 ts 編譯成 js 檔

    “build:copy”: 由於 tsc 只能處理 js/ts 檔,所以像 css、json 這類的就需要自己複製過去,這邊使用 cpx 這個套件,使用前請先 npm install 到 devdependence 裡面

  3. 執行 npm run build:lib 來編譯,執行結果應該會像下面,將 ts 轉成 js,並且附上 .d.ts 檔

    截圖 2020-09-26 上午9.56.25

  4. 告訴 npm 這個套件的起始程式位址,在 package.json 中加入 module types

    1
    2
    3
    4
    5
    6
    7
    {
    "name": "gss-webchat",
    "version": "3.1.0",
    "description": "",
    "main": "index.js",
    + "module": "lib/index.js",
    + "types": "lib/index.d.ts",
  5. Push 到 gitlab 上面就可以讓大家安裝了

  6. 安裝下來後應該就可以看到有 auto complete 的選項了

截圖 2020-09-26 上午10.25.27