釋出你的第一個 React 元件到 npm

xinkule發表於2019-03-04

前言

平時總會在專案中引用各種社群的 React 元件,也會在自己的專案中封裝可重用的元件,但是一直不知道怎麼把元件釋出到 npm。正好最近專案對 Toast 的需求比較大,搜尋後也沒發現可用的輕量級元件,於是乾脆自己擼一個發到 npm 練手。

準備

  • 在編寫一個社群元件之前,最重要的一點是要先構思好元件的 API,因為我們的元件是給別人用的,所以怎麼用最方便,最優雅,都是需要提前考慮好的。我相信大家都遇到過搜到一個元件的文件後由於其冗長的篇幅和難用性而放棄使用的,因此這是最最重要的一點,與人方便與己方便。
  • 其次,想好元件的名字,一個簡單有辨識度的名字也是元件易用性的標準之一。

步驟

這篇文章只記錄我在釋出時覺得關鍵的步驟,完整的程式碼可以去我的 github 檢視。

  1. 兩個資料夾
    src 下放元件對應的程式碼,通常是一個單入口的 index.js 還有其他子元件。
    example 下放使用元件的示例程式碼,通常會是一個靜態的網頁,用於展示效果

  2. webpack 編譯
    元件基於 es6 + jsx 語法,所以編譯是在所難免的,由於我的專案最終需要編譯部署到 github pages,所以我用了兩套 webpack 配置,一套用於本地起 dev server,一套部署上線。下面只貼起本地服務的配置:

const path = require(`path`);
const HtmlWebpackPlugin = require(`html-webpack-plugin`);
const webpack = require(`webpack`);

module.exports = {
  mode: `development`,
  entry: `./example/src/index.js`,
  output: {
    filename: `[name].bundle.js`,
    path: path.resolve(__dirname, `dist`)
  },
  devtool: `cheap-module-source-map`,
  devServer: {
    contentBase: `./example`,
    compress: true,
    clientLogLevel: `none`,
    hot: true,
    port: 3001
  },
  resolve: {
    extensions: [`.js`, `.jsx`]
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        loader: `babel-loader`,
        options: {
          cacheDirectory: true
        }
      },
      {
        test: /.css$/,
        use: [`style-loader`, `css-loader`]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      inject: true,
      template: path.resolve(__dirname, `example/index.html`)
    }),
    new webpack.HotModuleReplacementPlugin()
  ],
  performance: false
};
複製程式碼

由於我的專案只有 css 和 js,沒有圖片等其他靜態資源,所以只需要簡單的兩個 loader,其他的按需引用。

  1. eslint 程式碼校驗
    程式碼校驗現在已經是前端工程化的標配了,不僅能及早的發現一些低階錯誤,也能規範自己的程式碼風格,顯著提升開發體驗。下面是我的 eslint 配置檔案:
module.exports = {
  // 程式碼執行環境,如在瀏覽器端可以不提示 document, window 等全域性物件未定義
  env: {
    browser: true,
    es6: true,
    node: true
  },
  plugins: [`react`],
  extends: [`eslint:recommended`, `plugin:react/recommended`],
  // 由於 react 用到了部分不在 es 標準中的語法,因此需要 babel 解析
  parser: `babel-eslint`,
  parserOptions: {
    sourceType: `module`,
    ecmaFeatures: {
      jsx: true
    }
  }
};
複製程式碼
  1. babel 編譯成待發布模組
    程式碼寫好了之後,測試也沒問題,那麼如何將寫好的模組編譯後釋出呢?我搜了好多文章有直接用 webpack 打包的也有用 babel cli 編譯的,然後翻了下社群流行元件的原始碼多是用 babel 直接編譯的,所以就參考了一篇文章(參考見文末)開擼。

執行以下命令安裝所需模組:

npm install --save-dev babel-cli babel-core babel-preset-env babel-preset-react-app
複製程式碼

babel 配置檔案:

{
  "presets": ["env", "react-app"]
}
複製程式碼

最後,在 package.json 里加這麼一段 npm script:

{
  "scripts": {
    "compile": "NODE_ENV=production babel src --out-dir lib"
  }
}
複製程式碼

NODE_ENV=production 這段語句是 babel-preset-react-app 要求的,指明 node 的執行環境,方便內部進行優化處理;後面的 babel 命令則是把 src 資料夾下對應的程式碼編譯後輸出到同層的 lib 目錄下。
現在在命令列輸入 npm run compile 就可以看到編譯後的程式碼了,這些程式碼就是最終我們釋出到 npm 上的元件。

  1. 使用 npm link 測試你的元件
    當你的元件編譯完成之後,在釋出到 npm 上之前,還可以在本地的其他專案中對此元件進行測試。首先在 package.json 裡指定元件的入口檔案:
{
  "main": "lib/index.js"
}
複製程式碼

然後執行 npm link,這樣你的元件會被關聯到本地的全域性 node_modules 中去,然後在另一個專案裡執行 npm link light-toastlight-toast 替換為你的元件名),這樣你就可以在本地的專案裡 import 你的元件了。

  1. Readme
    元件是給自己和別人用的,那麼一個簡潔且易懂的 readme 是必不可少的,作為他人瞭解你程式碼的視窗,切記要寫的通俗,一段冗長的說明文件會瞬間降低一個人使用此元件的興趣。

  2. 釋出
    首先我們需要一個 .npmignore 檔案來指定哪些檔案是不需要釋出到 npm 上的,可根據自身需要修改。

example
src
.babelrc
.eslintrc.js
.gitignore
.prettierignore
webpack.config.js
webpack.config.prod.js
複製程式碼

其次新增一個 LICENSE 檔案,至於為啥需要這個瞭解下前段時間 react 因為協議鬧出的不愉快就知道了,不過開源大部分都用 MIT 協議,直接找一份現成的拷過來就行了。

然後,修改下我們剛剛的 script:

{
  "scripts": {
    "prepublishOnly": "NODE_ENV=production babel src --out-dir lib"
  }
}
複製程式碼

prepublishOnly 是 npm 提供的一個鉤子,在執行 npm publish 之前執行,這裡方便我們每次釋出的時候自動編譯程式碼。

最後,修改下 package.json 裡的相關資訊,比如元件的版本號,關鍵詞,git 倉庫等等,最重要的一點,把 react 和 react-dom 這兩個依賴移到 peerDependencies 裡去,這樣不會導致依賴重複解析的問題。

現在,你終於可以釋出你的第一個 react 元件了!等等,釋出前你還需要先註冊一個 npm 賬號,執行 npm adduser 根據提示進行操作,然後執行 npm publish,提示釋出成功後你就可以在 npm 倉庫裡搜到你自己的元件啦~

  1. 用 Github Pages 託管 demo
    如果你的專案是一個 UI 元件,那麼最好你可以提供一個線上預覽的地址,這樣他人可以直觀的看到執行效果,也會為你的專案加分不少。假設我們打包後靜態 demo 的目錄是在 dist 下面,裡面包含一個 index.html 模板和一個 index.js 入口,執行 npm install --save-dev gh-pages,這是一個可以將我們的程式碼推到 gh-pages 分支的包。然後在 package.json 裡新增以下指令碼:
{
  "scripts": {
    "deploy": "gh-pages -d dist"
  }
}
複製程式碼

執行 npm run deploy 就可以把 demo 釋出到 Github Pages 上去了。

總結

本文是我自己第一次釋出一個 React 元件的總結,其中也搜尋了很多資料,希望能給大家一些幫助,讓大家少走彎路,多多為開源社群做貢獻。

Light Toast
順便也厚臉皮的貼上我自己寫的輕量級 Toast 元件的地址,求個 star ~
如果你正在尋找一個小巧、不需要任何附加樣式的 Toast 元件,那麼這就是對的人。

參考文章:
Lessons Learned From Publishing a React Component to npm
A guide to building a React component with webpack 4, publishing to npm, and deploying the demo to GitHub Pages

相關文章