如何釋出你自己的React模組至NPM

飛翔的荷蘭人發表於2019-02-16

文章介紹如何建立釋出一個npm包,包括專案搭建、釋出流程、注意事項等。 演示程式碼GitHub地址

1. 初始化專案

首先在建立好的專案資料夾下面執行

npm init

根據對應提示完成package.json檔案初始化。

  • package name 為你建立的npm包的名稱,在釋出後被安裝使用即該名字,npm規定包名首字母需要為小寫。如import App from `your-module`;
  • version 即為包版本,每次釋出前都需要更新包版本,否則會失敗,包版本應該遵守語義化規範。語義化版本號分為三位0.0.0主版本號:當進行了大都改動或者對api有很多不相容修改時應該進行版本號升級。次版本號:增加了部分特性或者優化時升級該版本。修訂號:當修改了專案bug或者小的改動時升級該版本。
  • entry point 專案的入口路徑,當使用者使用包的時候,會根據該入口也就是package.jsonmain中的路徑來進行索引
  • git repository 關聯的git倉庫
  • keywords 會在npm中展示你的專案關鍵字

2. 專案構建

開發環境webpack.config.js配置

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

module.exports = {
  mode: `development`,
  entry: path.resolve(__dirname, `app.js`),
  output: {
    path: path.join(__dirname, `dist`),
    filename: "main.js",
  },
  module: {
    rules: [
      {
        test: /(.jsx|.js)$/,
        exclude: /node_modules/,
        loader: `babel-loader`
      },
      {test: /.css$/, loader: `style-loader!css-loader`},
      {
        test: /.(png|jpg|gif|svg)$/,  //對圖片檔案,使用 url-loader裡的載入器處理
        loader: `url-loader`,
        options: {
          limit: 8192,   //限制圖片檔案位元組,大於8KB則不生成base64 用路徑引用替代(相當於file-loader)
          name: `[name].[ext]?[hash]` //檔名
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      hash: true,
      template: `./index.html`,
    }),
    new webpack.HotModuleReplacementPlugin(), // 熱更新外掛
  ],
  devtool: `inline-source-map`, // map檔案追蹤錯誤提示
  devServer: {                  // 啟動本地開發的node伺服器環境(webpack-dev-server)
    port: 8080,                 // 埠
    contentBase: `./dist`,      // 開發環境的服務目錄
    historyApiFallback: true,
    host: `0.0.0.0`,
    inline: true,
    hot: true,
  },
};

在開發環境中就是一些很常見的配置,保證我們可以進行本地的元件模組開發即可。

打包模組webpack.prd.js配置

const path = require(`path`);
const webpack = require(`webpack`);
const BundleAnalyzerPlugin = require(`webpack-bundle-analyzer`).BundleAnalyzerPlugin;

const NODE_ENV = process.env.NODE_ENV;
const prdWebpackConfig= {
  mode: `production`,
  entry: path.resolve(__dirname, `src/index.js`),
  output: {
    path: path.join(__dirname, `lib`),
    filename: "chat-react.js",
    libraryTarget: `commonjs2`  //模組輸出方式
  },
  externals: {
    react: `react` //打包時候排除react
  },
  module: {
    rules: [
      {
        test: /(.jsx|.js)$/,
        exclude: /node_modules/,
        loader: `babel-loader`
      },
      {test: /.css$/, loader: `style-loader!css-loader`},
      {
        test: /.(png|jpg|gif|svg)$/,
        loader: `url-loader`,
        options: {
          limit: 8192,
          name: `[name].[ext]?[hash]`
        }
      }
    ]
  },
  plugins: []
};

if (NODE_ENV !== `publish`) {
  prdWebpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = prdWebpackConfig;

打包模組與我們寫應用邏輯程式碼有些不同,由於大部分使用者使用模組都不會去再對模組進行es5轉換,所有我們釋出的模組也應該是已經被轉換之後的程式碼,而且需要提供模組的引用入口以及排除模組自己以外的程式碼。

  1. entry 在完成模組打包時,修改了專案的入口路徑entry。配置打包的entry路徑為該釋出模組的檔案,而不是開發環境中的專案入口。
  2. output path為生成的目錄位置以及目錄名,filename 為打包後的模組檔案。libraryTarget 為生成模組的引入方式,因為我們寫的react元件基本為模組化打包開發方式,選擇使用commonjs2配置,最後打包會生成符合commonjs規範的模組,具體配置規則可見output.libraryTarget
  3. externals 因為我們是基於react的元件,但是在完成打包的時候如果將react也打包進去,庫的體積就會變大,而且react庫通常會在使用元件的時候被外部引入,所以我們要排除react。externals 配置
  4. BundleAnalyzerPlugin 在非釋出命令下打包時候,我們可以用該外掛審查一下打包完成的包體積大小。所以只需判斷下在npm scripts中設定的NODE_ENV環境變數,按需使用該外掛即可。
  5. mode 在webpack4中設定mode為production,會自己啟用生產環境的部分配置優化,此時UglifyJsPlugin壓縮外掛也會啟用,幫助完成我們的library的程式碼壓縮。

3. 釋出前配置

1.釋出前需要正確配置package.json中的main內容,使用時會根據該內容自動索引模組內容

  "main": "lib/chat-react.js"

2.在釋出前我們需要完成打包,為了確保我們釋出的版本為編譯完成後的版本,可以利用npm scripts中的prepublishOnly鉤子。這個鉤子可以保證我們在執行npm publish的前進行打包操作。

  "scripts": {
    "prepublishOnly": "NODE_ENV=`publish` npm run build"
  }

prepublish鉤子也會在執行npm publish前觸發該週期,我使用的是npm v5.5版本,在使用npm install的時候prepublish週期也會被觸發,翻到了一篇阮老師的文章,其中提到npm5版本時候會改掉這一狀態,prepublish將只在npm publish命令之前執行,不過看起來跟預期不一致。在15年的npm官方討論issue裡說將來可能會廢棄prepublish或者prepublishOnly某一個,不過翻看了官方npm script文件對兩個鉤子的用法都有說明,看起來是都保留了。

3.配置.npmignore,.npmignore的用法與.gitignore一致。因為我們在執行npm publish釋出命令時會將專案下掉所有檔案都發布至npm,.npmignore可以忽略掉我們不需要釋出都檔案

node_modules
example
src
.babelrc
app.js
index.html
package-lock.json
webpack.config.js
webpack.prd.js

4.編寫使用文件(readme)。為我們的模組元件編寫使用文件是必不可少的,README.md使用的是markdown語法,記不住語法的小夥伴也可以使用我的線上markdown編輯器

4. 完成釋出

釋出流程

  1. 首先註冊你的npm帳號
  2. 命令列執行npm login登入你的npm賬號
  3. 進入你專案目錄下npm publish即可完成釋出

回撤版本

如果你意外的釋出錯了包,使用npm unpublish +包名即可刪除該包。如:

npm unpublish chat-react

如果你想撤回指定版本,執行npm unpublish + 包名@版本號。如:

npm unpublish chat-react@1.0.0

Tips:npm為了保證包不會影響到使用者,釋出的版本只能在24小時內進行撤回。

文章程式碼演示GitHub地址

相關文章