百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

教你写第一个NPM包惊艳其他人

liuian 2025-02-07 18:21 13 浏览

自己书写一个npm包并发布到npm上面

说到npm包都会给人一种特别高大上的感觉,并且自己写了一个包之后如果有人用那么就会产生莫大的成就感,程序员的快乐就是这么简单。

想必有产生写npm包想法的人都对模块化比较熟悉,并且对于react、vue两者之一都比较熟练了。

下面呢我们就是使用react来写一个自己的npm包,我们呢会使用自己封装的webpack脚手架来写,如果有兴趣同学可以来看一下我的自我沉淀webpack5+react+eslint+tslint[1]文章。接下来的内容呢也是基于此来说明的。

这里也有现成的脚手架[2]

一、不同点

npm包的目录结构和普通的脚手架结构有所不同

  1. 启动目录不同:以往我们习惯将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?=?()?=>?;
?render(,?document.getElementById('root'));
?
????复制代码
index.html
?
?
???
?????
?????
?????
?????Document
???
???
?????
??? ? ????复制代码
然后在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



相关推荐

【常识】如何优化Windows 7

优化Windows7可以让这个经典系统运行更流畅,特别是在老旧硬件上。以下是经过整理的实用优化方案,分为基础优化和进阶优化两部分:一、基础优化(适合所有用户)1.关闭不必要的视觉效果右键计算机...

系统优化!Windows 11/10 必做的十个优化配置

以下是为Windows10/11用户整理的10个必做优化配置,涵盖性能提升、隐私保护和系统精简等方面,操作安全且无需第三方工具:1.禁用不必要的开机启动项操作路径:`Ctrl+S...

最好用音频剪辑的软件,使用方法?

QVE音频剪辑是一款简单实用的软件,功能丰富,可编辑全格式音频。支持音频转换、合并、淡入淡出、变速、音量调节等,无时长限制,用户可自由剪辑。剪辑后文件音质无损,支持多格式转换,便于存储与跨设备播放,满...

Vue2 开发总踩坑?这 8 个实战技巧让代码秒变丝滑

前端开发的小伙伴们,在和Vue2打交道的日子里,是不是总被各种奇奇怪怪的问题搞得头大?数据不响应、组件传值混乱、页面加载慢……别慌!今天带来8个超实用的Vue2实战技巧,每一个都能直击痛...

Motion for Vue:为Vue量身定制的强大动画库

在前端开发中,动画效果是提升用户体验的重要手段。Vue生态系统中虽然有许多动画库,但真正能做到高性能、易用且功能丰富的并不多。今天,我们要介绍的是MotionforVue(motion-v),...

CSS view():JavaScript 滚动动画的终结

前言CSSview()方法可能会标志着JavaScript在制作滚动动画方面的衰落。如何用5行CSS代码取代50多行繁琐的JavaScript,彻底改变网页动画每次和UI/U...

「大数据」 hive入门

前言最近会介入数据中台项目,所以会推出一系列的跟大数据相关的组件博客与文档。Hive这个大数据组件自从Hadoop诞生之日起,便作为Hadoop生态体系(HDFS、MR/YARN、HIVE、HBASE...

青铜时代的终结:对奖牌架构的反思

作者|AdamBellemare译者|王强策划|Tina要点运维和分析用例无法可靠地访问相关、完整和可信赖的数据。需要一种新的数据处理方法。虽然多跳架构已经存在了几十年,并且可以对...

解析IBM SQL-on-Hadoop的优化思路

对于BigSQL的优化,您需要注意以下六个方面:1.平衡的物理设计在进行集群的物理设计需要考虑数据节点的配置要一致,避免某个数据节点性能短板而影响整体性能。而对于管理节点,它虽然不保存业务数据,但作...

交易型数据湖 - Apache Iceberg、Apache Hudi和Delta Lake的比较

图片由作者提供简介构建数据湖最重要的决定之一是选择数据的存储格式,因为它可以大大影响系统的性能、可用性和兼容性。通过仔细考虑数据存储的格式,我们可以增强数据湖的功能和性能。有几种不同的选择,每一种都有...

深入解析全新 AWS S3 Tables:重塑数据湖仓架构

在AWSre:Invent2024大会中,AWS发布了AmazonS3Tables:一项专为可扩展存储和管理结构化数据而设计的解决方案,基于ApacheIceberg开放表格...

Apache DataFusion查询引擎简介

简介DataFusion是一个查询引擎,其本身不具备存储数据的能力。正因为不依赖底层存储的格式,使其成为了一个灵活可扩展的查询引擎。它原生支持了查询CSV,Parquet,Avro,Json等存储格式...

大数据Hadoop之——Flink Table API 和 SQL(单机Kafka)

一、TableAPI和FlinkSQL是什么TableAPI和SQL集成在同一套API中。这套API的核心概念是Table,用作查询的输入和输出,这套API都是批处理和...

比较前 3 名Schema管理工具

关注留言点赞,带你了解最流行的软件开发知识与最新科技行业趋势。在本文中,读者将了解三种顶级schema管理工具,如AWSGlue、ConfluentSchemaRegistry和Memph...

大数据技术之Flume

第1章概述1.1Flume定义Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统。Flume基于流式架构,灵活简单。1.2Flume的优点1.可以和...