從0到1,一步步開發React的loading元件,併發布到npm上

hello等風來發表於2019-02-26

沒有釋出過npm包的同學,可能會對NPM對開發有一種蜜汁敬畏,覺得這是一個很高大上的東西。甚至有次面試,面試官問我有沒有發過npm包,當時只用過還沒寫過,我想應該挺難的,就小聲說了沒有,然後就讓我回去了o(╯□╰)o。

其實,在現在的我看來,npm包就是一個我們平時經常寫的一個export出來的模組而已,只不過跟其它業務程式碼耦合性低,具有較高的獨立性。 當然,要釋出一個npm包,除了寫的模組元件外,還需要做一些基礎的包裝工作。 下面我就以最近開發的react-loading元件為例 原始碼地址,如果對你有幫助的話希望不要吝嗇你的 Star

本文主要記錄一下如何開發react元件(以react-loding為例),並在 npm 上釋出。廢話不多說,進入正題

建立元件

新建專案倉庫並初始化

在github上新建一個倉庫,名字可以自己取。確保你建立的元件名稱沒有在 npm 上被使用過, 這裡我們用 wsm-loading作為示例。開啟編輯器將專案拉到自己本地並初始化

git clone https://github.com/xxx/wsm-loading.git
cd wsm-loading
npm init
複製程式碼

執行npm init問題提示列表可以根據自己的個人愛好填寫,也可以採取預設的選項。

安裝專案的依賴

我麼需要開發的是一個React的loading元件,所以我們要先在專案中安裝react依賴

npm i react react-dom -D

我們的專案將通過webpack4進行構建,安裝專案所需的webpack依賴

npm i webpack webpack-cli webpack-dev-server html-webpack-plugin style-loader css-loader babel-core babel-loader babel-preset-env babel-preset-react -D

在專案中我們經常會用到scss作為css的編譯,因此我們在安裝webpack

npm install sass sass-loader node-sass webpack -D

這時上面安裝的依賴已經被新增到根目錄下的 package.json中了,接下來我們新增一個 start的指令碼,用於啟動我們本地開發的伺服器, start如下:

{
 "name": "wsm-loading",
  "version": "0.0.1",
  "description": "這是一個react-loading元件",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --mode development",
  },
複製程式碼

開發loading元件

現在讓在我們的專案中建立元件和示例程式碼目錄,目錄樹結構如下

├── examples // 示例程式碼存放目錄
│  └── src
├── node_modules
├── package.json
└── src // 元件原始碼和樣式存放目錄
└── .babelrc // es6及jsx語法編譯
└── .gitignore // git提交管理
└── package-lock.json
└── package.json
└── webpack.config.js webpack配置
複製程式碼

lodaing元件接收兩個props,一個size控制loading的大小,一個color控制loading的顏色

/*** src/index.js  ***/
import React, { Component } from "react";
import "./index.scss";
export default class MyComponent extends Component {
  render() {
    const { color, size } = this.props;
    const sizeStyle = {
      width: `${size}px`,
      height: `${size}px`
    };
    const colorStyle = {
      border: `1px solid ${color}`,
      borderColor: `${color} transparent transparent transparent`
    };
    const ringStyle = Object.assign({}, colorStyle, sizeStyle);

      return (
      <div className="loading" style={sizeStyle}>
        <div className="loading__ring" style={ringStyle} />
        <div className="loading__ring" style={ringStyle} />
        <div className="loading__ring" style={ringStyle} />
      </div>
    );
  }
}
MyComponent.defaultProps = {
    size: '36',
    color: '#000'
  }
複製程式碼

loading元件的樣式這裡就不給了,可以直接從我的程式碼庫中複製到你的專案裡css

接下來我們新增一個演示demo

<!-- examples/src/index.html -->
<html>
<head>
 <title>My Component Demo</title>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
 <div id="root"></div>
</body>
</html>
複製程式碼
/*** examples/src/index.js ***/
import React from 'react';
import { render} from 'react-dom';
import MyComponent from '../../src';
const App = () => (
 <MyComponent size='36' color='red' />
);
render(<App />, document.getElementById("root"));
複製程式碼

loading元件優化

以上就完成了一個基本的loading元件,但是我們還有一個疑問,就是現在引入的loading是在類名為root的元素之中,而一些被廣泛使用的UI框架中的loading元件確實在body層,無論你在哪裡引入,這樣就可以防止loading元件受到父元件的樣式的干擾。

從0到1,一步步開發React的loading元件,併發布到npm上
我們平時普通的元件的html結構如上圖,可見我們的loading是巢狀在我們的主體root元素中的。在仔細看下面這張圖。
從0到1,一步步開發React的loading元件,併發布到npm上
想要實現這種效果,我們必須得先了解React自帶的特性:Portals(傳送門)。這個特性是在16版本之後新增的。

我們哎src目錄下新建一個newPortal/newPortal.js檔案

import React from 'react';
import ReactDOM from 'react-dom';

class NewPortal extends React.Component {
  constructor(props) {
    super(props)
    this.node = document.createElement('div');
    document.body.appendChild(this.node);
  }
  render() {
    const { children } = this.props;
    return ReactDOM.createPortal(
      children,
      this.node,
    );
  }
}
export default NewPortal
複製程式碼

將其引入到我們的loading元件中

import NewPortal from './newPortal/newPortal'

並對元件進行一層包裹

  <NewPortal>
    <div className="loading" style={sizeStyle}>
      <div className="loading__ring" style={ringStyle} />
      <div className="loading__ring" style={ringStyle} />
      <div className="loading__ring" style={ringStyle} />
    </div>
  </NewPortal>
複製程式碼

這裡作者是參考這篇文章對元件進行優化的。大家感興趣可以去了解下。

配置webpack

接下來配置 webpack, 在專案根路徑下建立 webpack.config.js檔案。關於webpack配置不太瞭解或不熟悉的可以參考我之前之篇文章webpack詳細配置,這裡講不在一一講解。

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlWebpackPlugin = new HtmlWebpackPlugin({
  template: path.join(__dirname, "examples/src/index.html"),
  filename: "./index.html"
});
module.exports = {
  entry: path.join(__dirname, "examples/src/index.js"),
  output: {
    path: path.join(__dirname, "examples/dist"),
    filename: "bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: "babel-loader",
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      },
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"]
      }
    ]
  },
  plugins: [htmlWebpackPlugin],
  resolve: {
    extensions: [".js", ".jsx"]
  },
  devServer: {
    port: 3001
  }
};

複製程式碼

配置babelrc

最後需要指定 Babel 需要對哪些檔案進行編譯,毫無疑問 React 中使用的 JSX 檔案需要被編譯,讓它轉換成被主流瀏覽器都支援的 ES5 ,通用的配置也很簡單,只需要新增一對 presets,在專案根目錄下新增檔案.babelrc

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

接下來執行 demo

npm start 啟動完成後開啟瀏覽器輸入 http://localhost:3001,你將會在頁面上看到你寫的元件,你可以修改你的程式碼並儲存,頁面將會自動重新整理,我們的開發環境已經處於監控模式

釋出到npm上

我們要釋出被 babel 編譯且被壓縮後的版本,要讓沒有使用 babel 的專案也能夠正常的使用,比如不能出現 JSX 語法。 首先需要安裝 babel cli

npm i babel-cli -D

現在我們新增 transpile指令碼,以便使用 Babel 編譯我們的原始碼,同時拷貝一些靜態檔案(如:css 檔案)到目標打包目錄dist下 同時指定被編譯後的版本為元件的主入口,更改後的 package.json如下

{
  "name": "test",
  "version": "1.0.0",
  "description": "ceshi",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --mode development",
    "transpile": "babel src -d dist --copy-files"
  },
複製程式碼

嘗試編譯

npm run transpile

最後讓我們在專案的根目錄下新增.npmignore檔案,告訴 npm,我們專案中哪些檔案和資料夾是在釋出的包中被忽略掉的

# .npmignore 
src
examples
.babelrc
.gitignore
webpack.config.js
複製程式碼

釋出我們的元件到 npm 上

npm publish

提交npm之前需要去npm上開通自己的賬號,並驗證郵箱,這樣才能正常的提交上去。在終端使用npm login登陸自己的資訊

將程式碼上傳到git

專案上傳到git之前,我們需要配置下.gitignore,在專案的根目錄下新增.npmignore檔案

# .gitignore
node_modules
dist
複製程式碼

這樣我們上傳時,不會上傳node_modules和dist的目錄

git add .
git commit -m 'react-loading元件'
git push
複製程式碼

後語

當我們不停的陷於業務程式碼的開發中,何不嘗抽出一點時間來做點自己喜歡做的事呢,比如將自己的業務元件抽出來做成一個npm,開源元件庫不僅可以提高自己還能接觸到原來接觸不到東西。這只是一個簡單的教程,希望能對你有所啟發。

感謝你的閱讀!

相關文章