如何制作react组件包上传到npm

虽说现在市面上组件库相当多了,但是还有一些组件特定场景市面上没有,公司内部一些不同项目,有类似相同组件可以直接复用,避免重复造轮子,就可以直接制作一个npm包,下次直接使用。

注意:文中的每一步都很重要,都是踩过的坑

一、准备前提

1、注册npm账号
地址:https://www.npmjs.com/signup
注意:注册完后,记得验证你的邮件地址!一定!否则会在提交组件包的时候报403错误,那是因为没有验证你的邮箱。

二、创建空工程

1、创建新的文件夹
2、进入该文件夹,使用cmd命令,npm进入安装项目流程

//安装
npm init

3、对应的字段:

package name:   组件包名称,注意不能和npm上面已经存在的同名
version: (1.0.0)   版本
description:  描述
entry point: (index.js)   入口文件,默认为index
test command:  (可以为空)
git repository:  (可以为空)
keywords:  (可以为空)
author: 作者
license: (ISC)

创建完成后,该目录下会多一个package.json文件,内容如下

上面截图的文件可随意修改,但是发布时候需遵守规则:
1、版本号必须每次都修改
2、名称保持和上一次不变

三、安装工程需要的依赖包

npm install react react-dom -D
npm install @babel/cli @babel/core @babel/plugin-syntax-jsx @babel/plugin-transform-runtime @babel/preset-env @babel/preset-react  -D
npm install style-loader css-loader babel-loader less-loader less -D
npm install html-webpack-plugin webpack webpack-cli webpack-dev-server -D

上面的安装依赖我把它分为4部分好理解:
1、react基础部分,react依靠react、react-dom(vue的话可以自行查看需要啥)
react :react语法
react-dom:react和页面的dom打交道依赖
2、编译必须要的模块
@babel/cli
@babel/core: 把开发的nodejs编译成前端可以运行的js代码
@babel/preset-react: 把react编译成可执行js
@babel/preset-env
@babel/plugin-transform-runtime
@babel/plugin-syntax-jsx
3、项目各种loader依赖
style-loader:处理 dom style 标签里面的css(处理行内样式)
css-loader:处理css样式
less-loader :处理less样式
less:less样式依赖(样式我用less,需要scss的同学自行安装scss)
babel-loader:负责调用上面所有@babel的依赖模块
4、webpack脚手架
webpack:webpack主程序 ,webpack-cli:webpack编译工具脚手架
html-webpack-plugin: 插件,处理html的工具
webpack-dev-server: 编译运行工具,npm run start 实际调用的方法
其中 - D的意思是将依赖安装到devDependencies这里,一般来会默认安装到dependencies字段里,区别是dependencies会在打包时候进dist文件夹

有需要可以自行安装自己要的依赖,上面几个是我写组件必要的几个依赖,因为我没有写对应的依赖版本所以安装时候会以最新版本安装。

四、开始配置工程

1、新建如下目录结构和文件

#目录结构如下
├── package.json     依赖包管理文件
├── .gitignore     上传git时候忽略不传的文件
├── public                  
    ├── index.html    html静态页面
    └── app.js      webpack入口文件
└── src     组件包源码文件夹
    ├── index.jsx
    ├── index.less
├── index.js  暴露你的组件入口文件,即引用组件包时的入口文件,文件名和package.json中main字段同名
├── webpack.config.js      webpack配置文件
├── babel.config.js      @babel的配置文件(webpack4版本的叫做.babelrc )

2、编写webpack.config.js的配置,以下是最基础的配置

const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
/**
 * webpack插件将打包好的文件注入到html模板里
 * @type {HtmlWebpackPlugin}
 */
const htmlWebpackPlugin = new HtmlWebpackPlugin({
    template: path.join(__dirname, "./public/index.html"),
    filename: "./index.html"
});

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, "./public/app.js"),   //入口文件
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js"
    },
    module: {
        rules: [{
            test: /\.js$|.jsx/,   //正则匹配文件名称
            use: "babel-loader",    //会去调用babel.config.js里的所有babel的配置
            exclude: /node_modules/
        },  {
             test: /\.css|l.ess$/,
             use: ["style-loader", "css-loader", "less-loader"]
            }]
    },
    plugins: [htmlWebpackPlugin],   //插件:自动注入编译打包好的文件
    resolve: {
        extensions: [".js", ".jsx"]
    },
    devServer: {
        port: 3001,  //端口号
        open: true, // 自动打开浏览器
        compress: true, // 启动gzip压缩
    }
};

上面的less-loader没有启用lessmodules模块化比较不好,假设现在项目有好几个组件,那么模块化就可以避免我们不同组件的样式污染,如果不开启就不生效,如下例子:

//  index.jsx文件
import './exp1.less'; //普通用法
import styles from './exp2.less'; //less  module写法

如果没有启用模块化这种写法样式将不生效,dom元素上不会有class样式

所以得将webpack.config.js修改如下:

const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
/**
 * webpack插件将打包好的文件注入到html模板里
 * @type {HtmlWebpackPlugin}
 */
const htmlWebpackPlugin = new HtmlWebpackPlugin({
    template: path.join(__dirname, "./public/index.html"),
    filename: "./index.html"
});

module.exports = {
    mode: 'development',   //这个值有3种:production、development、none
    entry: path.join(__dirname, "./public/app.js"),
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js"
    },
    module: {
        rules: [{
            test: /\.js$|.jsx/,
            use: "babel-loader",
            exclude: /node_modules/
        },
            {
                test: /\.css$/,
                use: [
                    {loader: "style-loader"},
                    {loader: "css-loader"}],   //打包处理css样式表的第三方loader
            }, {
                //只为less启用模块化
                test: /\.less$/,
                use: [
                    {loader: "style-loader"},
                    {
                        loader: "css-loader", options: {
                            modules: {localIdentName: "[path][name]-[local]-[hash:5]"}
                        }
                    },
                    {loader: "less-loader"},
                ]
            }]
    },
    plugins: [htmlWebpackPlugin],   //插件:自动注入编译打包好的文件
    resolve: {
        extensions: [".js", ".jsx"]
    },
    devServer: {
        port: 3001,  //端口号
        open: true, // 自动打开浏览器
        compress: true, // 启动gzip压缩
    }
};

接下来往babel.config.js添加编译时候需要的loader配置:

module.exports = {
    "presets": ["@babel/preset-env", "@babel/preset-react"],
    "plugins": ["@babel/plugin-syntax-jsx", "@babel/plugin-transform-runtime"]
}

3、编写组件
这个是核心部分,就是说这里是你的组件
------------- ./src/index.jsx

import React, {Component, useState, memo} from 'react';
import styles from './index.less';
function Index() {
    return 
组件包测试
} export default memo(Index);

------------- ./src/index.less

.color {
  color: red;
}

4、对外暴露组件,编辑根目录下的index.js文件
我这里叫Test,使用组件包引入时候就是Test组件。别人在引用组件包时候会从该文件作为入口(package.json的main字段可以配置),这个文件有两种写法,第一种:

'use strict';
var Test = require('./src/index.jsx');

module.exports = Test;

第二种:

import Test from './src/index.jsx'

export default Test

5、编写webpack读取的入口文件 public/app.js
webpack启动、编译、打包都会从这个文件作为入口(webpack那边配置的)

import React from 'react'
import {render} from 'react-dom'
import ReactDemo from '../src/index.jsx'    //引入组件

const App = () => {
    return 
    // return 
1111111111111
}; render(, document.getElementById('root')); //获取虚拟dom的挂载节点

6、编写html模板,public/index.html文件。
我们知道spa单页面都是依据一个html模板上面引入js创建虚拟dom生成到这个html上面,所以需要有一个挂载的实例模板。




    
    第一个组件包



7、编写.gitignore文件
这个文件可以配置git上传时候忽略哪些文件不想传上去,同时发布组件包的时候它也会按照这个文件来,忽略哪些不上传。

# Created by .ignore support plugin (hsz.mobi)
node_modules/
dist/

8、添加项目启动命令:修改package.json文件
给该文件的scripts里添加两个系统命令,一个是启动命令,一个是打包命令(制作组件包用的比较少)。注意webpack4的版本可能不是 webpack server --mode development,这个需要自己对应版本。

  "scripts": {
    "start": "webpack server --mode development",
    "build": "webpack --mode development"
  },

接下来本地启动试下看下效果,命令:npm run start ,如果启动时候报错:[webpack-cli] ReferenceError: BigInt is not defined

说明是node版本问题,需要安装高点版本的node,可以使用nvm来管理node版本,这里不多说,我切换为node 12.0.0版本就可以。


五、发布

到此为止,我们已经配置好了工程,接下来需要把组件包发布上去
1、发布规则

1、组件包名称不能与npm上已经存在的一致,必须唯一性
2、每次发布必须修改版本号
3、发布的源必须是npm,有的设置了淘宝或者其他源,需要设置回npm源。

例如你是淘宝源你需要:
查看设置过的所有的源:npm config get registry
设置当前源为npm:npm config set registry https://registry.npmjs.org/
发布完成后设置回淘宝源:npm config set registry https://registry.npm.taobao.org

2、发布流程
1、登录注册好的npm账号:npm login
输入对应的账号、密码、邮箱即可


2、发布上去:npm publish
没有报错则表示成功

结尾:以上是基本的组件包发布过程,后面有时间更新正式的组件包上去,例如一些网站已存在的组件样式,优酷、虎牙等这些网站的组件仿制。

你可能感兴趣的:(如何制作react组件包上传到npm)