首页 > 其他分享 >NPM 包开发与优化全面指南

NPM 包开发与优化全面指南

时间:2024-10-28 10:44:13浏览次数:4  
标签:NPM 指南 dist index js version npm 版本 优化

前言

  • Hey, 我是 Immerse
  • 系列文章首发于【Immerse】,更多内容请关注该网站
  • 转载说明:转载请注明原文出处及版权声明!

1. 理解 NPM 包的结构

1.1 package.json 文件:包的核心

package.json文件是 NPM 包的中央配置,定义了包的各个方面,从基本元数据到复杂的发布配置。

{
    "name": "my-awesome-package",
    "version": "1.0.0",
    "description": "一个令人惊叹的包",
    "main": "./dist/index.js",
    "module": "./dist/index.mjs",
    "types": "./dist/index.d.ts",
    "files": ["dist"],
    "scripts": {
        "build": "tsup src/index.ts --format cjs,esm --dts",
        "test": "jest"
    },
    "keywords": ["awesome", "package"],
    "author": "Your Name <[email protected]>",
    "license": "MIT",
    "dependencies": {
        "lodash": "^4.17.21"
    },
    "devDependencies": {
        "typescript": "^4.5.5",
        "tsup": "^5.11.13",
        "jest": "^27.4.7"
    }
}

让我们详细解析一些关键字段:

  • nameversion:这两个字段组成了包在 NPM 注册表中的唯一标识符。
  • mainmoduletypes:这些指定了不同模块系统和 TypeScript 支持的入口点。
  • files:这个数组指定了发布包时应该包含哪些文件和目录。
  • scripts:这些是常见任务(如构建和测试)的命令快捷方式。

1.2 理解包的入口点

现代 JavaScript 生态系统支持多种模块格式。您的包应该通过提供多个入口点来适应不同的环境。

  1. main:主要入口点,通常用于 CommonJS (CJS)模块。
  2. module:用于 ECMAScript (ESM)模块的入口点。
  3. browser:用于浏览器环境的入口点。
  4. types:TypeScript 类型声明的入口点。

以下是一个包结构的示例:

my-awesome-package/
├── src/
│   ├── index.ts
│   └── utils.ts
├── dist/
│   ├── index.js        (CJS构建)
│   ├── index.mjs       (ESM构建)
│   ├── index.d.ts      (TypeScript声明)
│   └── browser.js      (浏览器特定构建)
├── package.json
└── tsconfig.json

对应的package.json配置:

{
    "name": "my-awesome-package",
    "version": "1.0.0",
    "main": "./dist/index.js",
    "module": "./dist/index.mjs",
    "browser": "./dist/browser.js",
    "types": "./dist/index.d.ts",
    "exports": {
        ".": {
            "require": "./dist/index.js",
            "import": "./dist/index.mjs",
            "types": "./dist/index.d.ts"
        }
    }
}

2. 深入理解模块格式

2.1 CommonJS (CJS)

CommonJS 是 Node.js 的传统模块格式。它使用require()进行导入,使用module.exports进行导出。

// mathUtils.js
function add(a, b) {
    return a + b;
}

function subtract(a, b) {
    return a - b;
}

module.exports = {
    add,
    subtract,
};

// main.js
const mathUtils = require('./mathUtils');
console.log(mathUtils.add(5, 3)); // 输出: 8

2.2 ECMAScript 模块 (ESM)

ESM 是 JavaScript 模块的现代标准,使用importexport语句。

// mathUtils.mjs
export function add(a, b) {
    return a + b;
}

export function subtract(a, b) {
    return a - b;
}

// main.mjs
import { add, subtract } from './mathUtils.mjs';
console.log(add(5, 3)); // 输出: 8

2.3 通用模块定义 (UMD)

UMD 是一种允许模块在多种环境(CommonJS、AMD、全局变量)中工作的模式。

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['exports'], factory);
    } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
        // CommonJS
        factory(exports);
    } else {
        // 浏览器全局变量
        factory((root.mathUtils = {}));
    }
})(typeof self !== 'undefined' ? self : this, function (exports) {
    exports.add = function (a, b) {
        return a + b;
    };
    exports.subtract = function (a, b) {
        return a - b;
    };
});

3. 高级包优化技术

3.1 Tree Shaking 和副作用

Tree shaking 是现代打包工具用来消除死代码的技术。要使您的包可以进行 tree shaking:

  1. 使用 ES 模块
  2. 避免副作用
  3. package.json中使用"sideEffects"字段
{
    "name": "my-utils",
    "version": "1.0.0",
    "sideEffects": false
}

如果某些文件确实有副作用:

{
    "name": "my-utils",
    "version": "1.0.0",
    "sideEffects": ["./src/polyfills.js", "*.css"]
}

3.2 代码分割和动态导入

对于大型包,考虑使用代码分割,允许用户只导入他们需要的部分:

// heavyFunction.js
export function heavyFunction() {
    // ... 一些计算密集型操作
}

// main.js
async function doHeavyWork() {
    const { heavyFunction } = await import('./heavyFunction.js');
    heavyFunction();
}

3.3 条件导出

使用条件导出为不同的环境或导入条件提供不同的入口点:

{
    "name": "my-package",
    "exports": {
        ".": {
            "import": "./dist/index.mjs",
            "require": "./dist/index.cjs",
            "browser": "./dist/browser.js"
        },
        "./utils": {
            "import": "./dist/utils.mjs",
            "require": "./dist/utils.cjs"
        }
    }
}

4. 版本管理和发布

4.1 语义化版本控制 (SemVer)

语义化版本使用三部分版本号:主版本号.次版本号.修订号

  • 主版本号:进行不兼容的 API 更改时
  • 次版本号:以向后兼容的方式添加功能时
  • 修订号:进行向后兼容的 bug 修复时
npm version patch -m "版本更新到 %s - 修复文档中的拼写错误"
npm version minor -m "版本更新到 %s - 添加新的实用函数"
npm version major -m "版本更新到 %s - 更改API结构"

4.2 预发布版本

对于预发布版本,使用带连字符的标签:

  • latest: 最新线上版本
  • alpha: 内部测试版本
  • beta: 公开测试版本
  • rc: 发行候选版本
    • Tips: 可以将这些标识符添加到版本号中,同时也可以添加额外版本:如:1.0.0-alpha.01.0.0-beta.11.0.0-rc.1
npm version prerelease --preid=alpha
# 1.0.0 -> 1.0.1-alpha.0

npm version prerelease --preid=beta
# 1.0.1-alpha.0 -> 1.0.1-beta.0

npm version prerelease --preid=rc
# 1.0.1-beta.0 -> 1.0.1-rc.0

4.3 使用标签发布

使用标签发布不同版本或预发布版本:

npm publish --tag next
npm publish --tag beta

用户可以安装特定版本:

npm install my-package@next
npm install my-package@beta

5. 持续集成和部署 (CI/CD)

5.1 使用 GitHub Actions 进行自动发布

创建一个.github/workflows/publish.yml文件:

name: 发布包

on:
    release:
        types: [created]

jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v2
            - uses: actions/setup-node@v2
              with:
                  node-version: '14'
                  registry-url: 'https://registry.npmjs.org'
            - run: npm ci
            - run: npm test
            - run: npm run build
            - run: npm publish
              env:
                  NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

    publish-gpr:
        needs: build
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v2
            - uses: actions/setup-node@v2
              with:
                  node-version: '14'
                  registry-url: 'https://npm.pkg.github.com'
            - run: npm ci
            - run: npm publish
              env:
                  NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}

这个工作流程将在您创建新版本时自动将您的包发布到 NPM 和 GitHub Packages。

5.2 自动化版本更新

您可以在 CI/CD 管道中自动化版本更新。以下是使用 GitHub Action 的示例:

name: 更新版本

on:
    push:
        branches:
            - main

jobs:
    bump-version:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v2
              with:
                  fetch-depth: 0
            - uses: actions/setup-node@v2
              with:
                  node-version: '14'
            - name: 更新版本
              run: |
                  git config --local user.email "[email protected]"
                  git config --local user.name "GitHub Action"
                  npm version patch -m "更新版本到 %s [skip ci]"
            - name: 推送更改
              uses: ad-m/github-push-action@master
              with:
                  github_token: ${{ secrets.GITHUB_TOKEN }}
                  branch: ${{ github.ref }}

这个动作将在每次向主分支推送更改时自动更新包的修订版本号。

6. 包开发最佳实践

6.1 文档

良好的文档对于包的采用至关重要。考虑使用像 JSDoc 这样的工具进行内联文档:

/**
 * 将两个数字相加。
 * @param {number} a - 第一个数字。
 * @param {number} b - 第二个数字。
 * @returns {number} a和b的和。
 */
function add(a, b) {
    return a + b;
}

6.2 测试

使用像 Jest 这样的框架实现全面的测试:

// math.js
export function add(a, b) {
    return a + b;
}

// math.test.js
import { add } from './math';

test('1 + 2 应该等于 3', () => {
    expect(add(1, 2)).toBe(3);
});

6.3 代码检查和格式化

使用 ESLint 进行代码检查,使用 Prettier 进行代码格式化。以下是一个示例.eslintrc.js

module.exports = {
    env: {
        browser: true,
        es2021: true,
        node: true,
    },
    extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
    parser: '@typescript-eslint/parser',
    parserOptions: {
        ecmaVersion: 12,
        sourceType: 'module',
    },
    plugins: ['@typescript-eslint'],
    rules: {
        // 在这里添加自定义规则
    },
};

以及一个.prettierrc文件:

{
    "singleQuote": true,
    "trailingComma": "es5",
    "tabWidth": 2,
    "semi": true,
    "printWidth": 100
}

info.jpg

标签:NPM,指南,dist,index,js,version,npm,版本,优化
From: https://www.cnblogs.com/leadingcode/p/18509898

相关文章

  • 改进的鲸鱼算法(IWOA)优化BP神经网络原理及Matlab代码复现
    目录0引言1数学模型2模型性能提升3Maltab代码3.1伪代码3.3IWOA-BP0引言为了缓解WOAQ易陷入局部最优和收敛精度低的问题,武泽权等人提出一种改进的鲸鱼优化算法(IWOA)。该算法通过准反向学习方法来初始化种群,提高种群的多样性;然后将线性收敛因子修改为非线性收......
  • 改进的鲸鱼算法(IWOA)优化支持向量机原理及Matlab代码复现
    目录0引言1数学模型2模型性能提升3Maltab代码3.1伪代码3.3IWOA-SVM/SVR0引言为了缓解WOAQ易陷入局部最优和收敛精度低的问题,武泽权等人提出一种改进的鲸鱼优化算法(IWOA)。该算法通过准反向学习方法来初始化种群,提高种群的多样性;然后将线性收敛因子修改为非......
  • 【办公类-53-14】2024年9月周计划系列优化(5天、6天、7天模版)
    11月为了迎接普及普惠督导抽查,所有班级资料都要做到第11周。我拿出去年的周计划代码,重新批量一下。这学期做代码有一个难点——并非全部5天,“国庆节”的4-5周是7天教案放在一个WORD模版上5天模版(一横三竖=4页)节日写法7天模版(一横四竖=5页)而原版的周计划里面也有6天7......
  • 一次mysql表空间优化记录
    场景:有个订单表,因为是按订单商品拆的数据,所以一个订单号会出现多行的情况。我们为了更新不漏数据(比如某订单删除了商品,但是根据订单号更新时会漏删除这些数据),我们就采用了先通过订单号删除数据,然后再将订单数据导入,插入的数据会有大量和删除的数据重复的数据。采用的是innodb索引......
  • 大数据新视界 -- 大数据大厂之大数据在能源行业的智能优化变革与展望
           ......
  • 《 C++ 修炼全景指南:十七 》彻底攻克图论!轻松解锁最短路径、生成树与高效图算法
    摘要1、引言1.1、什么是图?图(Graph)是计算机科学和离散数学中一种重要的数据结构,用来表示一组对象之间的关系。一个图由顶点(也称为节点,Vertex)和边(Edge)组成。顶点表示实体,而边则表示实体之间的关联或连接关系。根据边的性质,图可以分为无向图和有向图。在无向图中,边没有方向......
  • 南京做网站追踪流量与优化策略
    南京做网站追踪流量与优化策略在数字化时代,网站流量的追踪与优化成为企业成功的关键。尤其对于南京这样一个经济不断发展的城市,拥有良好的网络策略尤为重要。首要步骤是使用网站分析工具,如GoogleAnalytics或百度统计。这些工具能够精准地监测网站的访客来源、访问时长、热......
  • 使用LM Studio在ZBlog基于大模型原创文章上稿进行SEO优化
    在当今内容创作需求日益增长的背景下,如何高效地进行文章生成与发布,成为众多开发者关注的焦点。通过结合Python脚本与ZBlog平台,能够实现从分类与标签的自动化管理,到文章生成与发布的一整套流程。本文详细讲解了如何进行自动化文章生成与发布的基础配置、项目搭建与实际应用,......
  • 【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-2
    文件下载与邀请翻译者学习英特尔开发手册,最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。讲解下载英特尔开发手册的文章翻译英特尔开发手册,会是一件耗时费力的工作。如果有愿意和我一起来做这件事的,那么,欢迎你的加入。另外,我不仅仅是打算翻译这一种手册,......
  • 【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-3
    文件下载与邀请翻译者学习英特尔开发手册,最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。讲解下载英特尔开发手册的文章翻译英特尔开发手册,会是一件耗时费力的工作。如果有愿意和我一起来做这件事的,那么,欢迎你的加入。另外,我不仅仅是打算翻译这一种手册,......