热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

封装一个react组件发布到npm

为什么要将封装的组件发布到npm上?在日常开发中,我们会基于项目对一些通用的组件进行封装,并在项目中进行调用。当一个组件被多个项目调用,需要升级

为什么要将封装的组件发布到npm上?

  1. 在日常开发中,我们会基于项目对一些通用的组件进行封装,并在项目中进行调用。当一个组件被多个项目调用,需要升级维护时,就会出多次修改的情况,这种维护成本无疑是比较高的。所以,我们此时需要将组件发布到npm上,进行统一版本管理。项目中直接从npm上加载最新的包就可以了。
  2. 搭建一个自己或企业的私人组件仓库。

第一部分:封装一个react组件
1. 初始化一个package.json

yarn init -y

2. 安装相关插件包

package.json

"devDependencies": {"@babel/core": "^7.10.4","@hot-loader/react-dom": "^16.13.0","@babel/preset-env": "^7.10.4","@babel/preset-react": "^7.10.4","autoprefixer": "^9.8.4","babel-loader": "^8.1.0","clean-webpack-plugin": "^3.0.0","css-loader": "^3.6.0","html-webpack-plugin": "^4.3.0","optimize-css-assets-webpack-plugin": "^5.0.3","postcss-loader": "^3.0.0","style-loader": "^1.2.1","terser-webpack-plugin": "^3.0.6","webpack": "^4.43.0","webpack-cli": "^3.3.12","webpack-dev-server": "^3.11.0","webpack-merge": "^5.0.9","webpack-node-externals": "^2.5.0"},"dependencies": {"react": "^16.13.1","react-dom": "^16.13.1"}

3. 准备文件夹目录

在这里插入图片描述

4. 编写组件内容

4.1 src/components/change_button.js

import React, { useState, Component } from 'react';
import &#39;./change_button.css&#39;;class ChangeButton extends Component{constructor(props){super(props);this.state&#61;{btnTxt:&#39;Login&#39;}}render(){const {btnTxt}&#61;this.state;return(<div className&#61;&#39;button-container&#39; onClick&#61;{()&#61;>{ this.setState({btnTxt:btnTxt&#61;&#61;&#61;&#39;Login&#39;?&#39;Logout&#39;:&#39;Login&#39;})}}><span>{btnTxt}</span></div>)}
}export default ChangeButton;

注意&#xff1a;此处的组件内容不可以用hooks的形式去写&#xff0c;否则会编译报错&#xff0c;因为hooks只能在依赖于body&#xff0c;不能在独立的组件中使用。

4.2 src/components/change_button.css

.button-container{width: 100px;height: 40px;display: flex;align-items: center;justify-content: center;background-color: aquamarine;border-radius: 5px;
}.button-container:hover{cursor:pointer;
}

4.3 src/components/index.js

import ChangeButton from &#39;./change_button&#39;;export default ChangeButton;

4.4 src/index.js

import React from &#39;react&#39;;
import ReactDOM from &#39;react-dom&#39;;
import ChangeButton from &#39;./components/change_button&#39;;const App &#61; () &#61;> {return (<div><ChangeButton /></div>)
}//要实现局部热更新&#xff0c;必须要添加此句
if (module.hot) {module.hot.accept()}ReactDOM.render(<App />, document.getElementById(&#39;root&#39;));

4.5 public/index.html

<!DOCTYPE html>
<html><head><meta charset&#61;"utf-8" /><title>React</title></head><body><div id&#61;"root" class&#61;"root"></div></body>
</html>

5. 编写webpack内容

5.1 webpack.base.config.js

const webpackConfigBase &#61; {//module此处为loader区域&#xff0c;一般文件内容解析&#xff0c;处理放在此处&#xff0c;如babel&#xff0c;less,postcss转换等module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: &#39;babel-loader&#39;,options: {presets: [&#39;&#64;babel/preset-react&#39;],}}},{test: /\.css$/,use: [&#39;style-loader&#39;,&#39;css-loader&#39;,{loader: &#39;postcss-loader&#39;,options: {ident: &#39;postcss&#39;,plugins: (loader) &#61;> [require(&#39;autoprefixer&#39;)()],}}]}]}
}
module.exports &#61; webpackConfigBase

5.2 webpack.dev.config.js

const path &#61; require(&#39;path&#39;);
const webpack &#61; require(&#39;webpack&#39;);
const webpackConfigBase &#61; require(&#39;./webpack.base.config&#39;);
const HtmlWebpackPlugin &#61; require(&#39;html-webpack-plugin&#39;);
const { merge } &#61; require(&#39;webpack-merge&#39;);function resolve(relatedPath) {return path.join(__dirname, relatedPath)
}const webpackConfigDev &#61; {mode: &#39;development&#39;,entry: {app: [resolve(&#39;../src/index.js&#39;)],},output: {path: resolve(&#39;../lib&#39;), filename: &#39;change-button.js&#39;,},devtool: &#39;cheap-module-eval-source-map&#39;, devServer: {contentBase: resolve(&#39;../lib&#39;), hot: true,open: true, host: &#39;localhost&#39;,port: 8080,},plugins: [new HtmlWebpackPlugin({template: &#39;./public/index.html&#39;, }),new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin()]
}module.exports &#61; merge(webpackConfigBase, webpackConfigDev)

5.3 webpack.prod.config.js

const path &#61; require(&#39;path&#39;);
const webpack &#61; require(&#39;webpack&#39;);
const nodeExternals &#61; require(&#39;webpack-node-externals&#39;);
const webpackConfigBase &#61; require(&#39;./webpack.base.config&#39;);
const TerserJSPlugin &#61; require(&#39;terser-webpack-plugin&#39;);
const OptimizeCSSAssetsPlugin &#61; require(&#39;optimize-css-assets-webpack-plugin&#39;);
const { CleanWebpackPlugin } &#61; require(&#39;clean-webpack-plugin&#39;);
const { merge } &#61; require(&#39;webpack-merge&#39;);function resolve(relatedPath) {return path.join(__dirname, relatedPath)
}const webpackConfigProd &#61; {mode: &#39;production&#39;,entry: {app: [resolve(&#39;../src/components/index.js&#39;)], },output: {filename: &#39;change-button.js&#39;,path: resolve(&#39;../lib&#39;), libraryTarget:&#39;commonjs2&#39;},devtool: &#39;source-map&#39;, //或使用&#39;cheap-module-source-map&#39;、&#39;none&#39;optimization: {minimizer: [// 压缩js代码new TerserJSPlugin({// 多进程压缩parallel: 4,// 开启多进程压缩terserOptions: {compress: {drop_console: true, // 删除所有的 &#96;console&#96; 语句},},}),//压缩css代码new OptimizeCSSAssetsPlugin()],},externals: [nodeExternals()],plugins:[new CleanWebpackPlugin() //每次执行都将清空一下./dist目录]
}
module.exports &#61; merge(webpackConfigBase, webpackConfigProd)

注意&#xff1a;
1.entry的入口文件位置&#xff0c;由开发环境的src/index.js改成了组件的出口src/components/index.js&#xff0c;表示此处只负责输出组件。
2.output的libraryTarget需要为commonjs2。
3.通过nodeExternals()将打包组件内的react等依赖给去除了&#xff0c;减小了包的体积&#xff0c;在引用该包时&#xff0c;只要其环境下有相关包&#xff0c;就可以正常使用。

5.4 在package.json中添加如下scripts&#xff0c;用来启动webpack

"scripts": {"build": "webpack --config ./scripts/webpack.prod.config.js","dev": "webpack-dev-server --config ./scripts/webpack.dev.config.js"},

6. 配置组件发布的相关信息

package.json

"name": "&#64;yangin/change-button","version": "1.0.0","main": "lib/change-button.js","author":"yangin","license": "MIT",

属性说明
name: 包名&#xff0c;当建自己的私有仓库时&#xff0c;建议在包名前加一个scoped&#xff0c;如&#64;yangin/change-button&#xff0c;而不是change-button&#xff0c;因为 npm 包特别的多&#xff0c;很容易重复。这样这个包就会是私有的&#xff0c;可以通过 npm publish --access&#61;public 将这个包变为共有的包。
version: 包的版本&#xff0c;每次发布包的版本不能和上次一样。详细规范可见这里
description&#xff1a;包的简介。
repository&#xff1a;适合写 Github 地址&#xff0c;建议写成&#xff1a;:username/:repository。
license&#xff1a;认证。不知道该用什么的&#xff0c;就写MIT 吧。
main&#xff1a;包的入口文件。就是引入这个包的时候去加载的入口文件。
keywords&#xff1a;添加一些关键词更容易使你的包被搜索到。

更详细的package.json配置可见官网。

至此&#xff0c;完成了组件的相关配置

7. 调试并生成组件包文件

7.1 通过在根目录下运行

yarn dev

来启动项目&#xff0c;并对组件内的代码进行调试修改&#xff08;因为已配置了热更新&#xff0c;所以可以实时看到修改效果&#xff09;。

7.2 打包组件

yarn build

根据webpack的配置&#xff0c;在lib目录下会生成一个change-button.js文件&#xff0c;而此文件&#xff0c;正是我们的插件文件。
也是我们将要发布的文件。
在这里插入图片描述
至此&#xff0c;我们完成了组件的开发与打包环节。

第二部分&#xff1a;调试验证
第1步&#xff1a;将组件映射到本地库

在组件项目的根目录下运行

yarn link

在这里插入图片描述
运行后&#xff0c;在yarn的link文件夹下会有一个文件的快捷键映射
在这里插入图片描述
如图&#xff0c;则表示映射成功。

第2步&#xff1a;新建一个项目pblog

create-react-app pblog

第3步&#xff1a;在pblog项目中引入&#64;yangin/change-button组件&#xff0c;并调用

yarn link &#64;yangin/change-button

则在pblog的node_modules文件夹下新增一个&#64;yangin/change-button文件夹
调用在这里插入图片描述

第4步&#xff1a;在app.js中调用&#xff0c;最终运行结果如下

在这里插入图片描述
至此&#xff0c;则表示组件调试成功。

第三部分&#xff1a;将组件发布到npm
1.将源码发布到github上

1.1 在自己的github上新建一个respository&#xff0c;名称为change-button&#xff0c;并生成README.md

1.2 克隆仓库到本地&#xff0c;并将前面编写的项目文件内容拉到目录下。

git clone [仓库地址]

1.3 添加.gitignore文件
.gitignore

/node_modules
/yarn-err.log

1.4 提交项目至github。
在这里插入图片描述
至此&#xff0c;完成将项目源码发布至github上。

2.将组件包发布到npm上

2.1 准备npm账号,npm官网地址&#xff1a;https://www.npmjs.com/

2.2 在组件的项目根目录下登录npm

npm login

按照提示输入username、password、email
登录后&#xff0c;可以通过npm whoami来查看登录用户信息

npm whoami

2.3 发布组件到npm上

npm publish --access&#61;public

因为我们在给组件命名时&#xff0c;用的是&#64;yangin/change-button&#xff0c;此种为私有库命名方式&#xff0c;但此处需要将组将公开给大家共用&#xff0c;所以需要添加–access&#61;public。
在这里插入图片描述
至此&#xff0c;完成了将组件发布至npm上。

2.4 验证
在新项目中通过引入&#64;yangin/change-button组件&#xff0c;并调用来进行验证。

yarn add &#64;yangin/change-button

编写README&#xff0c;可参考资料&#xff1a;https://blog.csdn.net/weixin_33721344/article/details/88679068


推荐阅读
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文介绍了JavaScript进化到TypeScript的历史和背景,解释了TypeScript相对于JavaScript的优势和特点。作者分享了自己对TypeScript的观察和认识,并提到了在项目开发中使用TypeScript的好处。最后,作者表示对TypeScript进行尝试和探索的态度。 ... [详细]
  • loader资源模块加载器webpack资源模块加载webpack内部(内部loader)默认只会处理javascript文件,也就是说它会把打包过程中所有遇到的 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • python限制递归次数(python最大公约数递归)
    本文目录一览:1、python为什么要进行递归限制 ... [详细]
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
  • Node.js学习笔记(一)package.json及cnpm
    本文介绍了Node.js中包的概念,以及如何使用包来统一管理具有相互依赖关系的模块。同时还介绍了NPM(Node Package Manager)的基本介绍和使用方法,以及如何通过NPM下载第三方模块。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • express工程中的json调用方法
    本文介绍了在express工程中如何调用json数据,包括建立app.js文件、创建数据接口以及获取全部数据和typeid为1的数据的方法。 ... [详细]
author-avatar
ddcall
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有