开发自己的npm包(一)

    

    平时npm install 命令,安装的npm包从这里 https://registry.npmjs.org/ 下载的,如果想创建并发布自己的 NPM包,并分享有用代码。这里简单演示如何帮助你构建、发布和管理自己的 NPM 包。当然你也通过这样的方式可了解node和npm的运行原理等。同时可以制作成组件库提供给同事使用。更好的方式是搭建公司内部的npm源,上传npm包方便管理与维护。

特别是版本有些项目版本变动会比较频繁,有的时候下载下来在再打包,上传到自己的npm服务器上还有很有必要。常用搭建npm源方案如 Verdaccio 和 Nexus3 
      

前提条件

  • Node.js: 确保Node.js已安装在你的系统中。你可以从nodejs官方下载。
     https://nodejs.org/en/download 
  • 技能水平:  你已经具备了不少node.js使用或前端构建的经验|
  • NPM账号: 如果你还没注册,赶紧注册。
  • 利用 npm search <包名>   搜索一下,看项目名称是否存在.

一、自己发布包

步骤一:初始化新项目

  首先,你需要为你的包创建一个新的目录,并将其初始化为一个NPM项目。

1.创建一个项目目录:

D:\nodevue\mynpm2\>mkdir generator
D:\nodevue\mynpm2>cd generator

 

2. 初始化NPM:
  执行以下命令并回答提示(你也可以npm init -y 直接生成package.json文件)。

D:\nodevue\mynpm2\generator>npm init

 

这会生成一个package.json包含包的元数据的文件,比如包名、version、description和入口点等字段信息。

 我现在利用一个现成的 pakckage.json

{
  "name": "generator",
  "version": "0.1.0",
  "description": "this is my npm",
  "main": "my.js",  #这里就是入口文件,我起名为my.js
  "scripts": {
    "test": "echo \"test is ok\" && exit 1"
  },
  "author": "aozhejin",
  "license": "MIT"
}

 #测试用npm run test 运行下,看package.json是否有语法错误
  可以看下各个字段的意义

字段名称 字段解释 内容样例
name 项目/模块名称,长度必须小于等于214个字符,不能以"."(点)或者"_"(下划线)开头,不能包含大写字母  
version 项目版本例如: 0.1.0  
author 项目开发者,它的值是你在https://npmjs.org网站的有效账户名,遵循“账户名<邮件>”的规则  
description 项目描述,是一个字符串。它可以帮助人们在使用npm search时找到这个包  
keywords 项目关键字,是一个字符串数组。它可以帮助人们在使用npm search时找到这个包

"keywords": [
"node.js",
"javascript",
"npm",
"package",
"example",
"demo",
"hello world"
]

private 是否私有,设置为 true 时,npm 拒绝发布  
license 软件授权条款,让用户知道他们的使用权利和限制 "license": "MIT",
bugs bug 提交地址

"bugs": {
"url": "https://github.com/clarkio/simple-npm-package/issues"
}

contributors 项目贡献者  
repository 项目仓库地址

"repository": {
"type": "git",
"url": "git+https://github.com/clarkio/simple-npm-package.git"
},

homepage 项目包的官网 URL  
dependencies 生产环境下,项目运行所需依赖  
devDependencies 开发环境下,项目所需依赖。

"devDependencies": {
"@babel/core": "^7.27.4",
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
"@babel/preset-env": "^7.27.2",
"@babel/preset-react": "^7.27.1"
}

scripts 执行 npm 脚本命令简写,比如 “start”: “react-scripts start”, 执行 npm start 就是运行 “react-scripts start”。

"scripts": {
"build-clean": "rimraf --glob './packages/*/build' './packages/*/dist' './packages/*/tsconfig.tsbuildinfo' './packages/*/api-extractor.json' './api-extractor.json'",
"build": "yarn build:js && yarn build:ts && yarn bundle:ts",
"build:js": "node ./scripts/build.mjs",
"build:ts": "node ./scripts/buildTs.mjs",
"bundle:ts": "node ./scripts/bundleTs.mjs",
"check-changelog": "node ./scripts/checkChangelog.mjs",
"check-copyright-headers": "node ./scripts/checkCopyrightHeaders.mjs"
}

bin 内部命令对应的可执行文件的路径  
main 项目默认执行文件,比如 require(‘webpack’);就会默认加载 lib 目录下的 webpack.js 文件,如果没有设置,则默认加载项目跟目录下的 index.js 文件  
module 是以 ES Module(也就是 ES6)模块化方式进行加载,因为早期没有 ES6 模块化方案时,都是遵循 CommonJS 规范,而 CommonJS 规范的包是以 main 的方式表示入口文件的,为了区分就新增了 module 方式,但是 ES6 模块化方案效率更高,所以会优先查看是否有 module 字段,没有才使用 main 字段  
eslintConfig EsLint 检查文件配置,自动读取验证  
engines node.js的版本

"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},

browserslist 供浏览器使用的版本列表  
style 供浏览器使用时,样式文件所在的位置;样式文件打包工具parcelify,通过它知道样式文件的打包位置  
files 被项目包含的文件名数组  
workspaces  

"workspaces": [
"packages/*",
"website",
"examples/*"
],

 

步骤二:编写你的包代码

创建你的包的主文件。通常入口点是index.js ,但也可以是你在package.json 的字段中指定的任意文件名,这里我起名为my.js。 

例如,创建一个my.js文件,在 my.js中写入你的包功能。这里有一个简单的例子:

function getRandom(length){
    try {
        let digits = "0123456789";
        let str = "";
        let len = digits.length;
        for (let i = 0; i < length; i++) {
          str += digits[Math.floor(Math.random() * len)];
        }
    
        return str;
      } catch (err) {
        throw err;
      }
}
module.exports = getRandom;

在这种情况下,你创建了一个基础包,导出一个getRandom函数,输入一个数字,例如10,则返回一个10位随机数, 

步骤三:在本地创建您的套件

在发布你的package之前,先在本地测试一下。
首先看下这个命令 npm link 

D:\nodevue\mynpm2\generator>npm link --help
Symlink a package folder

Usage:
npm link [<package-spec>]

Options:
[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle]
[-E|--save-exact] [-g|--global]
[--install-strategy <hoisted|nested|shallow|linked>] [--legacy-bundling]
[--global-style] [--strict-peer-deps] [--no-package-lock]
[--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
[--include <prod|dev|optional|peer> [--include <prod|dev|optional|peer> ...]]
[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[--workspaces] [--include-workspace-root] [--install-links]

alias: ln

Run "npm help link" for more info

1.在项目根目录中执行以下命令,将你的包全局链接:

D:\nodevue\mynpm2>cd generator

D:\nodevue\mynpm2\generator>npm link

#执行完npm link 会生成node_module文件夹,里面有两个文件generator 软连接和.package-lock.json 文件
 .package-lock.json (注意前面会有一个dot(.)字符)

{
  "name": "generator",
  "version": "0.1.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "node_modules/generator": {
      "resolved": "",
      "link": true
    }
  }
}

由于你没有依赖其他包,所以这个文件夹里面会比较简单,如果你依赖其他包,则执行npm link 时会下载相关的依赖到node_module文件夹里面

2.查看npm全局的第三方包安装位置

   D:\nodevue> npm root -g
   C:\Users\king\AppData\Roaming\npm\node_modules 
你会发现他已经在这里了

3.查看全局

D:\nodevue\mynpm2\generator>npm list -g
C:\Users\king\AppData\Roaming\npm
+-- @modelcontextprotocol/server-everything@2025.11.25
+-- @vue/cli@5.0.9
+-- chai@6.2.1
+-- create-react-app@5.1.0
+-- download@8.0.0
+-- generator@0.1.0 -> .\D:\nodevue\mynpm2\generator

 

  如果你想删除全局的链接请使用 npm unlink <package-name>  后面需要加上包名,没有加包名会出错

D:\nodevue\mynpm2\otp-generator\test>npm unlink
npm error Must provide a package name to remove
npm error A complete log of this run can be found in: C:\Users\king\AppData\Local\npm-cache\_logs\2025-12-05T01_49_33_560Z-debug-0.log



4. 现在,创建一个用于测试包的目录:

D:\nodevue\mynpm2\generator>mkdir test

 

5. 创建一个测试文件test.js,写入代码如下:

//这里导出的函数和当前变量名称设置可以不一致
const createnum = require('generator');
console.log(createnum(6));

 

6. 进行测试:

D:\nodevue\mynpm2\generator\test>node test.js
4477948039

#查看test.js

D:\nodevue\mynpm2\generator\test>type test.js

//这里导出的函数和当前变量名称设置可以不一致
const createnum = require('generator');
console.log(createnum(6));

 

如果一切正常,你应该会看到一个随机数字,比如:4477948039

步骤4:准备发布

既然你的软件包本地可用,就该为发布做准备了。

更新 package.json:打开文件,确保所有相关字段都正确填写。 
name:    你的package名称(必须在NPM上唯一)。
version: 遵循语义版本化(例如1.0.0 )。
description:简要说明你的package的功能。
main:   入口文件(默认为index.js,我这里起名为my.js )。

 

2. 添加 readme 文件:编写文件以记录你的软件包。这应包括安装说明、使用示例及其他相关信息。

例:README.md

```javascript
const str = require('generator');
console.log(getRandom(10)); //returns a 10 digit random number
 

步骤5:发布你的package

在发布包之前,你需要通过命令行登录你的NPM账户:

登录NPM:

  D:\nodevue\mynpm2\generator\test>npm login
npm notice Log in on https://registry.npmjs.org/
npm notice SECURITY NOTICE: Classic tokens expire December 9. Granular tokens now limited to 90 days with 2FA enforced by default. Update your CI/CD workflows to avoid disruption. Learn more: https://gh.io/npm-token-changes
Login at:
https://www.npmjs.com/login?next=/login/cli/841b5e13-81fb-4a0f-8cd4-d2833f396070
Press ENTER to open in the browser...
#回车会打开浏览器,注册/登录


系统会提示您输入与NPM账户关联的用户名、密码和邮箱。

2. 发布包:登录后,通过以下方式发布包:

npm publish

如果设置正确,你的package会在NPM注册表上生效。

如果发布成功,别人就可以npm install    generator 下载你的包 
 
二、安装本地npm 开发包
 generator 项目打包,你可以发给别人或在其他项目中安装引入

D:\nodevue\mynpm2\generator>npm pack
npm notice
npm notice package: generator@0.1.0
npm notice Tarball Contents
npm notice 228B 制作过程.txt
npm notice 358B my.js
npm notice 221B package.json
npm notice 106B test/test.js
npm notice Tarball Details
npm notice name: generator
npm notice version: 0.1.0
npm notice filename: generator-0.1.0.tgz
npm notice package size: 818 B
npm notice unpacked size: 913 B
npm notice shasum: a7d492d7adede2425e58c2e21bf61f10e5f6dc36
npm notice integrity: sha512-SxtOt42iyFefM[...]yTsX+UG1wCn6g==
npm notice total files: 4
npm notice
generator-0.1.0.tgz

 

 

建立另一个项目generatorcall

进入 D:\nodevue\mynpm2\generatorcall> 
把 generator-0.1.0.tgz 压缩包复制到这个目录

安装开发的 generator

 

D:\nodevue\mynpm2\generatorcall>npm install ./generator-0.1.0.tgz

added 1 package, and audited 4 packages in 1s

found 0 vulnerabilities

编写package.json

{
  "name": "generatorcall",
  "version": "0.1.0",
  "description": "this is my npm",
  "main": "index.js",
  "scripts": {
    "test": "node index.js"
  },
  "author": "aozhejin",
  "license": "MIT",
  "devDependencies": {
    "@types/node": "^24.10.1"
  },
  "dependencies": {
    "generator": "file:generator-0.1.0.tgz"
  }
}

   编写index.js

import pkg from 'generator';
console.log(pkg(3))

   本地运行

D:\nodevue\mynpm2\generatorcall>npm run test

> generatorcall@0.1.0 test
> node index.js

948
(node:55924) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///D:/nodevue/mynpm2/generatorcall/index.js is not specified and it doesn't parse as CommonJS.
Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
To eliminate this warning, add "type": "module" to D:\nodevue\mynpm2\generatorcall\package.json.
(Use `node --trace-warnings ...` to show where the warning was created)

  修复
   在package.json中增加 "type"="module" ,上面的警告就会解除

   TypeScript:设置 “type”: “module” 以加载 ES 模块

{
  "name": "generatorcall",
  "type": "module",
  "version": "0.1.0",
  "description": "this is my npm",
  "main": "index.js",
  "scripts": {
    "test": "node index.js"
  },
  "author": "aozhejin",
  "license": "MIT",
  "devDependencies": {
    "@types/node": "^24.10.1"
  },
  "dependencies": {
    "generator": "file:generator-0.1.0.tgz"
  }
}

 



posted @ 2025-12-05 08:47  jinzi  阅读(2)  评论(0)    收藏  举报