如何搭建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包》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Node.js硬实战:115个核心技巧

Node.js硬实战:115个核心技巧

【美】Alex R. Young、【美】Marc Harter / 承竹、慕陶、邱娟、达峰 / 电子工业出版社 / 2017-1 / 109.9

《Node.js 硬实战:115 个核心技巧》是一本面向实战的Node.js 开发进阶指南。作为资深专家,《Node.js 硬实战:115 个核心技巧》作者独辟蹊径,将着眼点放在Node.js 的核心模块和网络应用,通过精心组织的丰富实例,向读者充分展示了Node.js 强大的并发处理能力,读者从中可真正掌握Node 的核心基础与高级技巧。《Node.js 硬实战:115 个核心技巧》总共有三部分......一起来看看 《Node.js硬实战:115个核心技巧》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换