教你写第一个NPM包惊艳其他人
ztj100 2024-11-17 18:14 59 浏览 0 评论
自己书写一个npm包并发布到npm上面
说到npm包都会给人一种特别高大上的感觉,并且自己写了一个包之后如果有人用那么就会产生莫大的成就感,程序员的快乐就是这么简单。
想必有产生写npm包想法的人都对模块化比较熟悉,并且对于react、vue两者之一都比较熟练了。
下面呢我们就是使用react来写一个自己的npm包,我们呢会使用自己封装的webpack脚手架来写,如果有兴趣同学可以来看一下我的自我沉淀webpack5+react+eslint+tslint[1]文章。接下来的内容呢也是基于此来说明的。
这里也有现成的脚手架[2]
一、不同点
npm包的目录结构和普通的脚手架结构有所不同
- 启动目录不同:以往我们习惯将entry文件写在src中,但是npm包的入口文件不能写在src中,因为npm是将我们的源代码打包,不可以包括html。所以将index.jsx和index.html文件提取到example文件中。【注意】example文件要和src同级。结构和内容如下index.jsx
import React from 'react';
import { render } from 'react-dom';
import ReactDemo from '../src';
const App = () => <ReactDemo />;
render(<App />, document.getElementById('root'));
复制代码
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
复制代码
然后在src/index.jsx文件中 导出
import App1 from './App';
export default App1;
复制代码
## 二 配置npm包的打包运行文件
在 config文件夹中新建webpack.npm.js文件
配置文件内容差不多。如下:详细配置请移步 [自我沉淀webpack5+react+eslint+tslint](https://juejin.cn/post/7002157698108096543 "https://juejin.cn/post/7002157698108096543")
externals划重点:这个可以告诉npm打包的时候不许将下面几种东西打包进去哦。
const { resolve } = require('path');
const cssLoaders = [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: {
auto: (resourcePath) => resourcePath.endsWith('.less'),
localIdentName: '[local]_[hash:base64:10]',
},
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [['autoprefixer'], require('postcss-preset-env')()],
},
},
},
];
module.exports = {
entry: './src/index.tsx',
mode: process.env.NODE_ENV,
externals: {
antd: 'antd',
react: 'React',
},
output: {
libraryTarget: 'umd',
filename: 'index.js',
path: resolve(resolve(__dirname, '..'), 'dist'),
clean: true,
},
resolve: {
alias: {
'@': resolve(resolve(__dirname, '..'), 'src/'),
},
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
mainFiles: ['index'],
},
devServer: {
hot: true,
port: 3002,
host: '127.0.0.1',
compress: true,
open: true,
proxy: {
'/api': {
target: 'http://127.0.0.1:3002',
pathRewrite: { '^/api': '' },
secure: false,
},
},
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: resolve(resolve(__dirname, '..'), ''),
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
// 缓存:第二次构建时,会读取之前的缓存
cacheDirectory: true,
},
},
],
},
{
test: /\.tsx$/,
loader: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: [...cssLoaders],
},
{
test: /\.less$/,
use: [...cssLoaders, 'less-loader'],
},
{
test: /\.s[ac]ss$/,
use: [...cssLoaders, 'sass-loader'],
},
{
exclude: /.(html|less|css|sass|js|jsx|ts|tsx)$/,
test: /\.(jpg|jpe|png|gif)$/,
loader: 'file-loader',
options: {
name: 'imgs/[name].[ext]',
outputPath: 'other',
},
},
{
test: /\.(ect|ttf|svg|woff)$/,
use: {
loader: 'file-loader',
options: {
name: 'icon/[name].[ext]',
},
},
},
],
},
};
复制代码
下面着重说一下package.json中的内容
- name: 包名,后续在npm中搜索全靠它
- version:版本号,每发布一次npm包就要增加一个版本,每个版本不能重复。
- description:描述
- main: 本包向外暴露的文件,很重要,一定要和你打包出来的文件名一模一样,我的叫做"dist/index.js"
- private: true/false 是否为私有。一般为false否则只有自己能使用
- flies: 暴露的文件夹, 有哪些文件夹提交到npm上面 格式为[ "dist" ]
- keywords: npm检索的关键字
- author: 作者
- license: ISC
- peerDependencies: 代表着当前npm包依赖下面这几种环境。
- 完整配置
{
"name": "new_webpack_action2",
"version": "1.0.24",
"m": "",
"main": "dist/index.js",
"private": false,
"flies": [
"dist"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "export NODE_ENV=development && npx webpack serve --config config/webpack.dev.js",
"build": "export NODE_ENV=production && npx webpack --config config/webpack.prod.js",
"npm": "export NODE_ENV=production && npx webpack --config config/webpack.npm.js"
},
"keywords": [
"react",
"javascript",
"npm"
],
"author": "919022572@qq.com",
"license": "ISC",
"devDependencies": {
"@ant-design/icons": "4.7.0",
"@babel/core": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.14.5",
"@types/lodash": "^4.14.178",
"@types/react": "^17.0.19",
"@types/react-dom": "^17.0.11",
"@types/react-router-dom": "^5.3.3",
"@typescript-eslint/eslint-plugin": "^5.11.0",
"@typescript-eslint/parser": "^5.11.0",
"autoprefixer": "^10.3.2",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
"css-loader": "^6.2.0",
"css-minimizer-webpack-plugin": "^3.0.2",
"eslint": "^8.8.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-webpack-plugin": "^3.1.1",
"file-loader": "^6.2.0",
"html-webpack-externals-plugin": "^3.8.0",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.1",
"less-loader": "^10.0.1",
"lodash": "^4.17.21",
"mini-css-extract-plugin": "^2.2.0",
"postcss-loader": "^6.1.1",
"postcss-preset-env": "^7.4.2",
"sass": "^1.38.0",
"sass-loader": "^12.1.0",
"speed-measure-webpack-plugin": "^1.5.0",
"style-loader": "^3.2.1",
"stylelint": "^13.13.1",
"stylelint-config-standard": "^22.0.0",
"terser-webpack-plugin": "^5.1.4",
"thread-loader": "^3.0.4",
"ts-loader": "^9.2.5",
"tslint": "^6.1.3",
"typescript": "^4.5.5",
"webpack": "^5.68.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.0.0",
"webpack-merge": "^5.8.0",
"workbox-webpack-plugin": "^6.4.2"
},
"dependencies": {
"antd": "4.18.8",
"axios": "^0.26.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-router-dom": "5.2.0"
},
"peerDependencies": {
"@ant-design/icons": "4.7.0",
"antd": "4.18.8",
"bizcharts": "4.1.15",
"rc-footer": "0.6.6",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-router-dom": "5.2.0"
},
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
}
复制代码
三、发布
如果是第一次发布包,执行以下命令,然后输入前面注册好的NPM账号,密码和邮箱,将提示创建成功
npm adduser
复制代码
如果不是第一次发布包,执行以下命令进行登录,同样输入NPM账号,密码和邮箱
npm login
复制代码
注意:npm adduser成功的时候默认你已经登陆了,所以不需要再进行npm login了
接着先进入项目文件夹下,然后输入以下命令进行发布
npm publish
复制代码
当终端显示如下面的信息时,就代表版本号为1.0.0(你的package.json中的版本号)的包发布成功啦!前往NPM官网就可以查到你的包
+ 你的文件名@0.1.0
复制代码
四、报错
1、如果出现
npm ERR! code E403
npm ERR! 403 403 Forbidden - PUT https://registry.npmjs.org/ghost-watermarkdemo - Forbidden
npm ERR! 403 In most cases, you or one of your dependencies are requesting
npm ERR! 403 a package version that is forbidden by your security policy, or
npm ERR! 403 on a server you do not have access to.
复制代码
以下几种原因会导致
账号密码错误 (请检查npm官网的账号密码)
包重名 (请检查npm官网上是否有同名项目,名字取决于 package.js 的项目名字段)
网络原因
镜像源问题
新注册的用户邮箱未激活。 登陆你的邮箱去激活(如下)
复制代码
image.png
2、 如果出现
image.png
需要在你的package.json中 private改为false或者删除
更新已经发布的包
更新包的操作和发布包的操作是一样的
npm publish
复制代码
但是每次更新时,必须修改版本号后才能更新,比如将1.0.0修改为1.0.1后才能更新发布。
这里的包版本管理规则都是一样的,采用的是semver(语义化版本),意思就是版本号:大改.中改.小改
五、## 从npm上面卸载自己发布的包
进入自己项目的目录执行。npm unpublish --force 出现:
npm WARN using --force Recommended protections disabled.
-包名@0.1.0
复制代码
则卸载成功,这时在npm上面就搜索不到了
关于本文
来自:夏末海棠
https://juejin.cn/post/7072652104837365774
相关推荐
- sharding-jdbc实现`分库分表`与`读写分离`
-
一、前言本文将基于以下环境整合...
- 三分钟了解mysql中主键、外键、非空、唯一、默认约束是什么
-
在数据库中,数据表是数据库中最重要、最基本的操作对象,是数据存储的基本单位。数据表被定义为列的集合,数据在表中是按照行和列的格式来存储的。每一行代表一条唯一的记录,每一列代表记录中的一个域。...
- MySQL8行级锁_mysql如何加行级锁
-
MySQL8行级锁版本:8.0.34基本概念...
- mysql使用小技巧_mysql使用入门
-
1、MySQL中有许多很实用的函数,好好利用它们可以省去很多时间:group_concat()将取到的值用逗号连接,可以这么用:selectgroup_concat(distinctid)fr...
- MySQL/MariaDB中如何支持全部的Unicode?
-
永远不要在MySQL中使用utf8,并且始终使用utf8mb4。utf8mb4介绍MySQL/MariaDB中,utf8字符集并不是对Unicode的真正实现,即不是真正的UTF-8编码,因...
- 聊聊 MySQL Server 可执行注释,你懂了吗?
-
前言MySQLServer当前支持如下3种注释风格:...
- MySQL系列-源码编译安装(v5.7.34)
-
一、系统环境要求...
- MySQL的锁就锁住我啦!与腾讯大佬的技术交谈,是我小看它了
-
对酒当歌,人生几何!朝朝暮暮,唯有己脱。苦苦寻觅找工作之间,殊不知今日之事乃我心之痛,难道是我不配拥有工作嘛。自面试后他所谓的等待都过去一段时日,可惜在下京东上的小金库都要见低啦。每每想到不由心中一...
- MySQL字符问题_mysql中字符串的位置
-
中文写入乱码问题:我输入的中文编码是urf8的,建的库是urf8的,但是插入mysql总是乱码,一堆"???????????????????????"我用的是ibatis,终于找到原因了,我是这么解决...
- 深圳尚学堂:mysql基本sql语句大全(三)
-
数据开发-经典1.按姓氏笔画排序:Select*FromTableNameOrderByCustomerNameCollateChinese_PRC_Stroke_ci_as//从少...
- MySQL进行行级锁的?一会next-key锁,一会间隙锁,一会记录锁?
-
大家好,是不是很多人都对MySQL加行级锁的规则搞的迷迷糊糊,一会是next-key锁,一会是间隙锁,一会又是记录锁。坦白说,确实还挺复杂的,但是好在我找点了点规律,也知道如何如何用命令分析加...
- 一文讲清怎么利用Python Django实现Excel数据表的导入导出功能
-
摘要:Python作为一门简单易学且功能强大的编程语言,广受程序员、数据分析师和AI工程师的青睐。本文系统讲解了如何使用Python的Django框架结合openpyxl库实现Excel...
- 用DataX实现两个MySQL实例间的数据同步
-
DataXDataX使用Java实现。如果可以实现数据库实例之间准实时的...
- MySQL数据库知识_mysql数据库基础知识
-
MySQL是一种关系型数据库管理系统;那废话不多说,直接上自己以前学习整理文档:查看数据库命令:(1).查看存储过程状态:showprocedurestatus;(2).显示系统变量:show...
- 如何为MySQL中的JSON字段设置索引
-
背景MySQL在2015年中发布的5.7.8版本中首次引入了JSON数据类型。自此,它成了一种逃离严格列定义的方式,可以存储各种形状和大小的JSON文档,例如审计日志、配置信息、第三方数据包、用户自定...
你 发表评论:
欢迎- 一周热门
-
-
MySQL中这14个小玩意,让人眼前一亮!
-
旗舰机新标杆 OPPO Find X2系列正式发布 售价5499元起
-
【VueTorrent】一款吊炸天的qBittorrent主题,人人都可用
-
面试官:使用int类型做加减操作,是线程安全吗
-
C++编程知识:ToString()字符串转换你用正确了吗?
-
【Spring Boot】WebSocket 的 6 种集成方式
-
PyTorch 深度学习实战(26):多目标强化学习Multi-Objective RL
-
pytorch中的 scatter_()函数使用和详解
-
与 Java 17 相比,Java 21 究竟有多快?
-
基于TensorRT_LLM的大模型推理加速与OpenAI兼容服务优化
-
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)