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

NPM 包开发与优化全面指南

时间:2024-10-30 20:47:42浏览次数:6  
标签:NPM 指南 dist index js version npm 版本 优化

1. 理解 NPM 包的结构
   1.1 package.json 文件:包的核心
   1.2 理解包的入口点

2. 深入理解模块格式
   2.1 CommonJS (CJS)
   2.2 ECMAScript 模块 (ESM)
   2.3 通用模块定义 (UMD)

3. 高级包优化技术
   3.1 Tree Shaking 和副作用
   3.2 代码分割和动态导入
   3.3 条件导出

4. 版本管理和发布
   4.1 语义化版本控制 (SemVer)
   4.2 预发布版本
   4.3 使用标签发布

5. 持续集成和部署 (CI/CD)
   5.1 使用 GitHub Actions 进行自动发布
   5.2 自动化版本更新
   6. 包开发最佳实践
   6.1 文档
   6.2 测试
   6.3 代码检查和格式化

原创 非同质前端札记

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"
    }
}

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

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

1.2 理解包的入口点

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

main:主要入口点,通常用于 CommonJS (CJS)模块。
module:用于 ECMAScript (ESM)模块的入口点。
browser:用于浏览器环境的入口点。
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 模块的现代标准,使用import和export语句。

// 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:

使用 ES 模块
避免副作用
在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.0 和 1.0.0-beta.1 和 1.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
}


标签:NPM,指南,dist,index,js,version,npm,版本,优化
From: https://www.cnblogs.com/o-O-oO/p/18516586

相关文章

  • 海外联盟营销入门:2024最新指南
    在联盟营销(AffiliateMarketing)过程中,人们往往会在项目所需的电商、博客、社媒等平台上推广产品或服务以获得佣金收入,有数据显示联盟营销为数字媒体行业带来了15%的增长收入。然而,在联盟营销带来利润丰厚的同时,他也存在一个难题:有效的多账户管理。如果没有合适的工具,联盟营销很......
  • Unity的SkinnedMeshRenderer性能优化
    Unity支持两种主要的Skinning技术在Unity中,Skinning主要指的是角色的蒙皮过程,这是3D动画中的一个关键步骤,用于将3D模型的网格(皮肤)附着到骨骼上,使得模型可以根据骨骼的动作进行逼真的变形。Unity支持两种主要的Skinning技术:CPUSkinning和GPUSkinning。1.CPUSkinning......
  • Oracle数据库AWR报告中高等待事件优化方法
    一、理解等待事件什么是等待事件在Oracle数据库中,等待事件是指会话在执行SQL语句时,由于某些资源(如磁盘I/O、锁、缓冲区等)暂时不可用而必须等待的情况。AWR报告中的等待事件部分可以帮助我们识别数据库性能瓶颈的关键所在。确定高等待事件类型常见的高等待事件包括:......
  • 【Unity】Addressables下的图集(SpriteAtlas)内存优化
    前言:资源管理系统:AddressablesUI:模拟NGUI图集Sprite,在UGUI下继承Image增加UIImage组件,实现将SpriteAtlas组件拖拽到属性面板上,切换选择里面的小图问题:在检查项目内存占用过高问题时,发现直接拖拽上去的资源不受Addressables系统的自动引用管理,导致部分资源虽然没有引用,但是未被释放......
  • 基于贝叶斯优化CNN-LSTM网络的数据分类识别算法matlab仿真
    1.算法运行效果图预览(完整程序运行后无水印) BO优化前 BO优化过程 BO优化后  2.算法运行软件版本matlab2022a 3.部分核心程序(完整版代码包含详细中文注释和操作步骤视频)MBsize=32;Lr=0.1;%CNNLSTM构建卷积神经网络laye......
  • Jenkins执行Shell脚本超时错误处理指南
    Jenkins执行Shell脚本超时错误处理指南在使用Jenkins进行自动化测试时,经常会遇到需要执行Shell脚本的情况。然而,当Shell脚本执行时间过长,超过了Jenkins配置的超时限制时,就会导致构建任务失败。本文将为你详细介绍如何处理Jenkins执行Shell脚本时的超时错误。问题现象当Jenkins......
  • 前端开发 npm ,pnpm
    npmpnpm通过npm安装pnpm安装npminstall-gpnpm安装指定版本[email protected]或者npminstall-gpnpm@X查看当前pnpm版本pnpm-v或pnpm-version卸载npmrm-gpnpm升级版本pnpmadd-gpnpmtoupdate常用命令对比npm命令pnpm......
  • HarmonyOS:应用性能优化实践
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )➤GitHub地址:https://github.com/strengthen➤原文地址:https://www.cnblogs.com/strengthen/p/18515687➤如果链接不是为敢技术的博客园地址,则可能是......
  • 【EI复现】基于深度强化学习的微能源网能量管理与优化策略研究(Python代码实现)
    ......
  • 【无人机】基于GWO算法、MP-GWO灰狼算法、灰狼-布谷鸟优化算法、CS-GWO多种群灰狼优化
        ......