如何在在NPM发布一个React组件

发布于:2025-07-30 ⋅ 阅读:(31) ⋅ 点赞:(0)

第一步:注册npm账号

官网地址:https://www.npmjs.com/
点击 sign up 按钮
输入用户名、邮箱和密码
其中密码最少10位,数字大小写字母和特殊字符构成

第二步:新建一个react项目

npm install -g create-react-app
create-react-app checkboxlist

进入项目
cd checkboxlist
运行 
npm install
我这里用了antd顺便也install一下antd@4.x.x
(后面组件中也加了import 'antd/dist/antd.css';你要是没用就不用加)


src下的文件保留 App.js App.css index.js 文件
其他没用的可以全部删除,涉及删除文件可能存在一些图片和方法的调用,也一并删除。
不然由于他们互相之间的引入会报错。


在src下新建一个lib文件夹,里面存放index.jsx文件和一个叫做CheckboxList文件夹。
其中:lib下的index.jsx文件是将来用来导出CheckboxList组件用的。
index.jsx具体代码为:
import CheckboxList from "./CheckboxList";
export {CheckboxList};

其中:lib下的CheckboxList文件夹用来放置我CheckboxList的组件用的,
在CheckboxList文件夹里面存放我组件的index.jsx和index.css文件。
index.jsx具体代码就是我这个组件的代码。
index.css具体代码就是我这个组件的样式。



我的CheckboxList文件夹下的index.jsx组件代码(你可以不用管,换成你自己的组件)
import { useState ,useEffect} from 'react';
import {Button,Checkbox, Divider} from 'antd';
import './index.css';
import 'antd/dist/antd.css';

function CheckboxList(props)  {
  const [isCheckAll, setisCheckAll] = useState(false)
  const [addmanList,setaddmanList]=useState([]);
  const [xingmingList,setxingmingList]=useState([...props.dataSource]);

  useEffect(()=>{
    // 这里判断翻页新传递的数据和选中的数据是否存在...
    console.log('addmanList',addmanList);
    setisCheckAll(false);
    let data=[...props.dataSource];
    let num=0;
    let addmanlist=addmanList;
    data.forEach(item => {
      let matched = addmanlist.find(obj => obj.id === item.id);
      if (matched){
        item.checked=true;
        num+=1;
      }        
    });
    if(num==data.length){
      setisCheckAll(true);
    }
    setxingmingList([...data]);
  },[props.dataSource])

  function onCheckChange(e,item){
    let ischecked=e.target.checked;
    let selectId=item.id;
    let num=0;
    let xingminglist=xingmingList;
    xingminglist.map((item,index)=>{
      if(item.id==selectId){
        item.checked=ischecked;
        if(item.checked==true){
          setaddmanList(prev=>[...prev,item]);
          props.check([...addmanList,item]);
        }else{
          let array=addmanList.filter(i=>i.id!==selectId);
          setaddmanList([...array]);
          props.check([...array]);
        }
      }
    })
    setxingmingList([...xingminglist]);
    xingminglist.map((item,index)=>{
      if(item.checked==true){
        num+=1;
      }
    })
    if(num==xingminglist.length){
      setisCheckAll(true);
    }else{
      setisCheckAll(false);
    }    
  };

  function onCheckAllChange(e){
    let ischecked=e.target.checked;
    setisCheckAll(ischecked);
    let addmanlist=addmanList;
    let xingminglist=xingmingList;
    xingminglist.map((item,index)=>{
      item.checked=ischecked;
    })
    if(ischecked==true){
      let array = [...new Set([...xingminglist,...addmanlist].map(item => JSON.stringify(item)))].map(item => JSON.parse(item));
      setaddmanList(array);
      props.allcheck(array);
    }else{
      let array = addmanlist.filter(itemA => !xingminglist.some(itemB => itemA.id === itemB.id));
      setaddmanList(array);
      props.allcheck(array);
    }

  };

  return (
    <>
      <div className="alarmNotice2_draw_top_body">
        <div className="alarmNotice2_draw_top_body_header">
          <div className="alarmNotice2_draw_top_body_header_left"><Checkbox onChange={onCheckAllChange} checked={isCheckAll}></Checkbox><div className="alarmNotice2_draw_top_body_header_left_name">人员姓名</div></div>
          <div className="alarmNotice2_draw_top_body_header_right">部门</div>
        </div>
        <div  className="alarmNotice2_draw_top_body_list">
          { 
              xingmingList.map((item,index)=>{
                return (
                  <div className="alarmNotice2_draw_top_body_list_item" key={item.id}>
                    <div className="alarmNotice2_draw_top_body_list_item_left">
                      <Checkbox  onChange={(e)=>onCheckChange(e,item)} checked={item.checked}></Checkbox>
                      <div className="alarmNotice2_draw_top_body_list_item_left_name">{item.name}</div>
                    </div>
                    <div className="alarmNotice2_draw_top_body_list_item_right">{item.department}</div>
                  </div>
                )
              })
          }
        </div>
      </div>
    </>
  )
}

export default CheckboxList;



我的CheckboxList文件夹下的index.css组件样式代码(你可以不用管,换成你自己的组件样式)
#root {
  padding: 0px;
  margin:0px;
}
body {
  padding: 0px;
  margin:0px;
}
*{
  padding: 0px;
  margin:0px;
}
.alarmNotice2_draw_top_body{
  width: 100%;
  height: calc(100% - 100px);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  overflow: auto;
}
.alarmNotice2_draw_top_body_header{
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  height: 50px;
  border-bottom: 1px solid #eee;
}
.alarmNotice2_draw_top_body_header_left{
  width: 49%;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}
.alarmNotice2_draw_top_body_header_left_name{
  margin-left: 10px;
  font-weight: 500;
  font-size: 14px;
  color: rgba(0, 0, 0, .85);
}
.alarmNotice2_draw_top_body_header_right{
  width: 49%;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  font-size: 14px;
  font-weight: 500;
  color: rgba(0, 0, 0, .85);
}
.alarmNotice2_draw_top_body_list{
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items:center;
}
.alarmNotice2_draw_top_body_list_item{
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  height: 50px;
  border-bottom: 1px solid #efefef;
}
.alarmNotice2_draw_top_body_list_item_left{
  width: 49%;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}
.alarmNotice2_draw_top_body_list_item_left_name{
  margin-left: 10px;
  font-size: 14px;
  color: rgba(0, 0, 0, .85);
}
.alarmNotice2_draw_top_body_list_item_right{
  width: 49%;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  font-size: 14px;
  color: rgba(0, 0, 0, .85);
}
.alarmNotice2_draw_bottom{
  width: 100%;
  height: 50px;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items:center;
}
.alarmNotice_draw_bottom_btn{
  margin-right: 10px;
  border-radius: 5px;
}

 按照上面操作,最后你的src中结构如图 

第三步:在app中引入./lib下的CheckboxList组件

import { useState ,useEffect} from 'react';
import {CheckboxList} from './lib';
import './App.css';

function App() {
  const [dataSource,setdataSource]=useState([]);
  useEffect(()=>{
      let data=[
        {id:'pichangshan1',name:'皮常山1',department:'实施部',tel:'13112345678',checked:false},
        {id:'xieguangkun1',name:'谢广坤1',department:'智慧燃气部',tel:'15112345678',checked:false},
        {id:'wanglaoqi1',name:'王老七1',department:'综合管理部',tel:'18112345678',checked:false},
        {id:'liuneng1',name:'刘能1',department:'财务管理部',tel:'13612345678',checked:false},
        {id:'zhaosi1',name:'赵四1',department:'生产中心,科技中心',tel:'13812345678',checked:false}
      ]
      setdataSource(data);
  },[])
  function getCheck(checkarray){
    console.log('checkarray',checkarray);
  }
  function getAllCheck(allcheckarray){
    console.log('allcheckarray',allcheckarray);
  }
  return (
      <CheckboxList dataSource={dataSource}  check={getCheck} allcheck={getAllCheck}/>
  );
}

export default App;

第四步:运行看效果

npm run start

 

 

 

第五步:安装相关依赖

npm install -save @babel/polyfill
npm install --save-dev @babel/preset-react
npm install --save-dev @babel/core @babel/cli @babel/preset-env 

第六步:修改package.json文件

  "scripts": {
    "start": "react-scripts start",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "build": "babel src/lib --out-dir dist --copy-files"
  },

第七步:打包

npm run build

build成功会生成dist文件夹,就是打包好的文件。
cd dist文件夹中,执行npm init初始化
可以在dist文件夹中加一个README.md,这样可以用来描述组件的功能和用法。

第八步:npm login

npm login
这里要注意的是,你的npm镜像是不是官方镜像,
使用:npm get registry 指令查看是不是官方镜像
如果不是的话,记得切换镜像
使用:npm config set registry https://registry.npmjs.org/

然后执行:npm login 
可能会让你输入账号密码
也可能告诉你点击回车自动打开浏览器然后要你输入验证码
这个验证码在login时候会自动发送到你邮箱中

然后在执行:npm publish
这时候可能会报错,因为package.json中"private": true,
需要将这个true,改成false

然后执行:npm publish --access=public

我的package.json文件

{
  "name": "checkboxcontactlist",
  "version": "0.1.0",
  "private": false,
  "dependencies": {
    "@babel/polyfill": "^7.12.1",
    "@testing-library/dom": "^10.4.1",
    "@testing-library/jest-dom": "^6.6.4",
    "@testing-library/react": "^16.3.0",
    "@testing-library/user-event": "^13.5.0",
    "antd": "^4.24.16",
    "react": "^19.1.1",
    "react-dom": "^19.1.1",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "babel src/lib --out-dir dist --copy-files",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@babel/cli": "^7.28.0",
    "@babel/core": "^7.28.0",
    "@babel/preset-env": "^7.28.0",
    "@babel/preset-react": "^7.27.1"
  }
}

我的项目目录文件


网站公告

今日签到

点亮在社区的每一天
去签到