教你写第一个NPM包惊艳其他人
ztj100 2024-11-17 18:14 45 浏览 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
相关推荐
- Jquery 详细用法
-
1、jQuery介绍(1)jQuery是什么?是一个js框架,其主要思想是利用jQuery提供的选择器查找要操作的节点,然后将找到的节点封装成一个jQuery对象。封装成jQuery对象的目的有...
- 前端开发79条知识点汇总
-
1.css禁用鼠标事件2.get/post的理解和他们之间的区别http超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信。HTTP的工作方式是客户机与服务器之间的请求-应答协议。...
- js基础面试题92-130道题目
-
92.说说你对作用域链的理解参考答案:作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。...
- Web前端必备基础知识点,百万网友:牛逼
-
1、Web中的常见攻击方式1.SQL注入------常见的安全性问题。解决方案:前端页面需要校验用户的输入数据(限制用户输入的类型、范围、格式、长度),不能只靠后端去校验用户数据。一来可以提高后端处理...
- 事件——《JS高级程序设计》
-
一、事件流1.事件流描述的是从页面中接收事件的顺序2.事件冒泡(eventbubble):事件从开始时由最具体的元素(就是嵌套最深的那个节点)开始,逐级向上传播到较为不具体的节点(就是Docu...
- 前端开发中79条不可忽视的知识点汇总
-
过往一些不足的地方,通过博客,好好总结一下。1.css禁用鼠标事件...
- Chrome 开发工具之Network
-
经常会听到比如"为什么我的js代码没执行啊?","我明明发送了请求,为什么反应?","我这个网站怎么加载的这么慢?"这类的问题,那么问题既然存在,就需要去解决它,需要解决它,首先我们得找对导致问题的原...
- 轻量级 React.js 虚拟美化滚动条组件RScroll
-
前几天有给大家分享一个Vue自定义滚动条组件VScroll。今天再分享一个最新开发的ReactPC端模拟滚动条组件RScroll。...
- 一文解读JavaScript事件对象和表单对象
-
前言相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要会JavaScrip...
- Python函数参数黑科技:*args与**kwargs深度解析
-
90%的Python程序员不知道,可变参数设计竟能决定函数的灵活性和扩展性!掌握这些技巧,让你的函数适应任何场景!一、函数参数设计的三大进阶技巧...
- 深入理解Python3密码学:详解PyCrypto库加密、解密与数字签名
-
在现代计算领域,信息安全逐渐成为焦点话题。密码学,作为信息保护的关键技术之一,允许我们加密(保密)和解密(解密)数据。...
- 阿里Nacos惊爆安全漏洞,火速升级!(附修复建议)
-
前言好,我是threedr3am,我发现nacos最新版本1.4.1对于User-Agent绕过安全漏洞的serverIdentitykey-value修复机制,依然存在绕过问题,在nacos开启了...
- Python模块:zoneinfo时区支持详解
-
一、知识导图二、知识讲解(一)zoneinfo模块概述...
- Golang开发的一些注意事项(一)
-
1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...
- Python鼠标与键盘自动化指南:从入门到进阶——键盘篇
-
`pynput`是一个用于控制和监控鼠标和键盘的Python库...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 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)