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

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

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

自己书写一个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



相关推荐

python入门到脱坑函数—定义函数_如何定义函数python

Python函数定义:从入门到精通一、函数的基本概念函数是组织好的、可重复使用的代码块,用于执行特定任务。在Python中,函数可以提高代码的模块性和重复利用率。二、定义函数的基本语法def函数名(...

javascript函数的call、apply和bind的原理及作用详解

javascript函数的call、apply和bind本质是用来实现继承的,专业点说法就是改变函数体内部this的指向,当一个对象没有某个功能时,就可以用这3个来从有相关功能的对象里借用过来...

JS中 call()、apply()、bind() 的用法

其实是一个很简单的东西,认真看十分钟就从一脸懵B到完全理解!先看明白下面:例1obj.objAge;//17obj.myFun()//小张年龄undefined例2shows(...

Pandas每日函数学习之apply函数_apply函数python

apply函数是Pandas中的一个非常强大的工具,它允许你对DataFrame或Series中的数据应用一个函数,可以是自定义的函数,也可以是内置的函数。apply可以作用于DataF...

Win10搜索不习惯 换个设定就好了_window10搜索用不了怎么办

Windows10的搜索功能是真的方便,这点用惯了Windows10的小伙伴应该都知道,不过它有个小问题,就是Windows10虽然会自动联网搜索,但默认使用微软自家的Bing搜索引擎和Edge...

面试秘籍:call、bind、apply的区别,面试官为什么总爱问这三位?

引言你有没有发现,每次JavaScript面试,面试官总爱问你call、bind和apply的区别?好像这三个方法成了通关密码,掌握了它们,就能顺利过关。其实不难理解,面试官问这些问题,不...

记住这8招,帮你掌握“追拍“摄影技法—摄影早自习第422日

杨海英同学提问:请问叶梓老师,我练习追拍时,总也不能把运动的人物拍清晰,速度一般掌握在1/40-1/60,请问您如何把追拍拍的清晰?这跟不同的运动形式有关系吗?请您给讲讲要点,谢谢您!摄影:Damia...

[Sony] 有点残酷的测试A7RII PK FS7

都是好机!手中利器!主要是最近天天研究fs5,想知道fs5与a7rii后期匹配问题,苦等朋友的fs5月底到货,于是先拿手里现有的fs7小测一下,十九八九也能看到fs5的影子,另外也了解一下fs5k标配...

AndroidStudio_Android使用OkHttp发起Http请求

这个okHttp的使用,其实网络上有很多的案例的,但是,如果以前没用过,copy别人的直接用的话,可以发现要么导包导不进来,要么,人家给的代码也不完整,这里自己整理一下.1.引入OkHttp的jar...

ESL-通过事件控制FreeSWITCH_es事务控制

通过事件提供的最底层控制机制,允许我们有效地利用工具箱,适时选择使用其中的单个工具。FreeSWITCH是一个核心交换与混合矩阵,它周围有几十个模块提供各种功能特性。我们完全控制了所有的即时信息,这些...

【调试】perf和火焰图_perf生成火焰图

简介perf是linux上的性能分析工具,perf可以对event进行统计得到event的发生次数,或者对event进行采样,得到每次event发生时的相关数据(cpu、进程id、运行栈等),利用这些...

文本检索控件也玩安卓?dtSearch Engine发布Android测试版

dtSearchEngineforLinux(原生64-bit/32-bitC++和JavaAPIs)和dtSearchEngineforWin&.NET(原生64-bi...

网站后台莫名增加N个管理员,记一次SQL注入攻击

网站没流量,但却经常被SQL注入光顾。最近,网站真的很奇怪,网站后台不光莫名多了很多“管理员”,所有的Wordpres插件还会被自动暂停,导致一些插件支持的页面,如WooCommerce无法正常访问、...

多元回归树分析Multivariate Regression Trees,MRT

多元回归树(MultivariateRegressionTrees,MRT)是单元回归树的拓展,是一种对一系列连续型变量递归划分成多个类群的聚类方法,是在决策树(decision-trees)基础...

JMETER性能测试_JMETER性能测试指标

jmeter为性能测试提供了一下特色:jmeter可以对测试静态资源(例如js、html等)以及动态资源(例如php、jsp、ajax等等)进行性能测试jmeter可以挖掘出系统最大能处...