如何搭建npm包

栏目: JavaScript · 发布时间: 5年前

内容简介:本文将从以下几个方面分享如何搭建一个npm包,在搭建过程中需要注意的事项在项目根目录下执行:

本文将从以下几个方面分享如何搭建一个npm包,在搭建过程中需要注意的事项

  • 初始化
  • 入口
  • 依赖
  • 文件
  • 版本号管理
  • 自动化发布

初始化

在项目根目录下执行: npm init 创建 package.json 文件,这也是npm包的核心配置文件

入口

package.json 中可以通过下面两个字段来指定入口文件:

  • main 指向 commonjs 模块的入口,使用 require 语法引入
  • module 指向 ES2015 模块的入口,使用 import 语法引入,支持webpack等构建 工具 的 tree shaking 优化

这里,可以展开介绍一下 umd、commonjs、es module 模块类型的区别

  • umd 是兼容 commonjs、amd 的通用模块规范,支持全变量规范,可以直接通过 <script> 标签引入,写法如下:
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
	typeof define === 'function' && define.amd ? define(factory) :
	(global['xxx'] = factory());
}(this, (function () { 'use strict';
    ...
})));
复制代码
  • commonjs 使用 module.exports 定义模块对外输出的接口,使用 require 加载模块
  • es module 是ES6模块,使用 exportimport 语法

而一般npm包都需要支持以上三种模块规范,以下列出通用的rollup配置:

import path from 'path';
import babel from 'rollup-plugin-babel';
import cleanup from 'rollup-plugin-cleanup';
import replace from 'rollup-plugin-replace';
import { uglify } from 'rollup-plugin-uglify';
import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import pkg from './package.json';

const { version, name, author } = pkg;

const banner = `/*!
* ${name} v${version}
* (c) ${new Date().getFullYear()} ${author}
*/`;

const resolve = p => {
    return path.resolve(__dirname, p);
}

const pluginsCommon = [
    commonjs({
        // polyfill async/await
        'node_modules/@babel/runtime/helpers/asyncToGenerator.js': ['default']
    }),
    nodeResolve({
        module: false,
    }),
    babel({
        runtimeHelpers: true,
    }),
]

export default [
    {
        input: resolve('src/index.js'),
        plugins: pluginsCommon.concat([
            cleanup(),
        ]),
        output: {
            file: resolve(`dist/npmpackage-name-${version}.js`),
            format: 'umd',
            name: 'npmpackage-name',
            banner,
        }
    },
    {
        input: resolve('src/index.js'),
        plugins: pluginsCommon.concat([
            uglify(),
        ]),
        output: {
            file: resolve(`dist/npmpackage-name-${version}.min.js`),
            format: 'umd',
            name: 'npmpackage-name',
            banner,
        }
    },
    {
        input: resolve('src/index.js'),
        plugins: pluginsCommon.concat([
            cleanup(),
        ]),
        output: [
            {
                file: resolve(`dist/npmpackage-name.es.js`),
                format: 'es',
                banner,
            },
            {
                file: resolve(`dist/npmpackage-name.js`),
                format: 'cjs',
                banner,
            }
        ]
    },
];
复制代码

再附上对应的babel配置:

{
    "presets": [
        ["@babel/preset-env", {
            "targets": {
                "browsers": ["Android >= 4", "iOS >= 8"]
            },
            "modules": false,
            "loose": true
        }]
    ],
    "plugins": [
        "@babel/plugin-external-helpers",
        [
            "@babel/plugin-transform-runtime",
            {
                "regenerator": true
            }
        ]
    ]
}
复制代码

以上,配置则能构建出满足以上三种模块规范的文件

相应的 package.json 文件中,也需要通过不同的字段,来指定对应模块规范的入口文件,如下:

{
    ...
    "main": "dist/npmpackage-name.js",
    "module": "dist/npmpackage-name.es.js",
    ...
}
复制代码

dist/npmpackage-name-${version}.js 的文件,则可以直接通过 <script> 标签引入

注意:不要将入口文件指定为未过babel的文件,这往往会导致使用了此包的项目出现兼容问题

依赖

package.json 中跟npm包依赖相关的字段主要有:

  • dependencies:项目运行时所依赖的模块
  • devDependencies:项目开发时所依赖的模块
  • peerDependencies:这是“同伴依赖”,一种特殊的依赖,在发布包的时候需要。有这种依赖意味着安装包的用户也需要和包同样的依赖。(在安装包时会提示)

我们在开发npm包过程中,需要注意安装依赖的类型。

对于那些对版本有强要求的依赖,为了避免因依赖版本不一致导致问题,需要将此类依赖安装在 peerDependencies 中

文件

一个npm包一般包括源文件、构建产出的文件、demo文件、测试文件等文件,而为了减小npm包大小,加快下载速度,发布时应该将无用的文件剔除掉,有两种方式:

  • 使用 package.json 中的 files 指定需要发布的文件
  • .npmignore 文件中指定需要提出的文件

版本号管理

每发布一个版本,版本号需要相应的升级(不要手动在package.json中维护)

应该通过 npm version 来对版本号进行管理,版本号有以下几种类型:

  • major: 主版本号
  • minor: 次版本号
  • patch: 补丁号
  • premajor: 预备主版本
  • preminor: 预备次版本
  • prepatch: 预备补丁号
  • prerelease: 预发布版本

版本号管理策略如下:

  • 版本号格式:主版本号.次版本号.修订号
  • 主版本号:有不兼容的 API 修改
  • 次版本号:有向后兼容的功能性新增
  • 修订号:有向后兼容的问题修正

而升级对应的版本号的命令则如下:

npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]
复制代码

发布自动化

package.json 配置如下:

{
    "scripts": {
        "build": "rm -rf dist && rollup --config",
        "release_major": "npm version major",
        "release_minor": "npm version minor",
        "release_patch": "npm version patch",
        "postversion": "npm publish",
        "prepublishOnly": "npm run build"
    },
}
复制代码

直接通过执行对应的 release_ 命令来进行发布即可

以上就是一个npm包通常会用到基本事项,后续会不断更新一些进阶的用法~


以上所述就是小编给大家介绍的《如何搭建npm包》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入浅出强化学习:原理入门

深入浅出强化学习:原理入门

郭宪、方勇纯 / 电子工业出版社 / 2018-1 / 79

《深入浅出强化学习:原理入门》用通俗易懂的语言深入浅出地介绍了强化学习的基本原理,覆盖了传统的强化学习基本方法和当前炙手可热的深度强化学习方法。开篇从最基本的马尔科夫决策过程入手,将强化学习问题纳入到严谨的数学框架中,接着阐述了解决此类问题最基本的方法——动态规划方法,并从中总结出解决强化学习问题的基本思路:交互迭代策略评估和策略改善。基于这个思路,分别介绍了基于值函数的强化学习方法和基于直接策略......一起来看看 《深入浅出强化学习:原理入门》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具