使用webpack构建属于你自己的npm包

导语:最近做了几个项目,想对其中公共的部分进行提取,单独设置成npm包,以便别的项目可以使用,省去重复写的烦恼,在网上找了好久,终于寻得一个方法,可以打包自己的包到npm,并且同时支持游览器和node环境使用,非常方便,现在就做一个开发总结。

# 目录

  • 准备工作
  • 编写一个方法
  • 打包
  • 测试
  • 发布

# 准备工作

  • 查询npm包名称是否存在

由于是发布公开包,所以包名称必须是唯一的,不能重复。如果你不确定你的包名称是否已经有人使用,可以打开命令行窗口查询一下。如果没有查到就可以继续,否则更换一个包名称。

npm search fegq-test
1

如果出现一下结果就说明包名称没有被使用,可以放心发布你的包了。

No matches found for "fegq-test"
1

比如我之前发布过一个测试包fsdgq-test,搜索就会出来结果,这时就要更改包名,避免出错。

# 查询包名
npm search fsdgq-test

# 查询结果
NAME                      | DESCRIPTION          | AUTHOR          | DATE       | VERSION  | KEYWORDS
fsdgq-test                |                      | =ioguanqi       | 2021-12-02 | 1.0.1    |
1
2
3
4
5
6
  • 新建一个文件夹,初始化一个包。

这个文件夹的名称,会默认为包名,当然后面也可以在package.json配置文件中修改。

mkdir fegq-test
cd fegq-test
npm init
1
2
3

初始化过程如下:

his utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (fegq-test) # 输入包名称,我这里是默认本文件夹为包名称,就省略了
version: (1.0.0) 0.0.1 # 版本号,我这里写0.0.1因为是刚发布第一版
description: this is a test package. # 对包的描述,我这里简单写一下
entry point: (index.js) ./dist/mytest.js # 入口文件,就是当别人下载你的包以后,导入的地方,这里我就写打包后的文件地址
test command: jest # 测试命令,包写好后,可以选择一个测试语言来测试一下,这里我就用jest来测试
git repository: https://github.com/gitguanqi/fegq-test.git # 仓库地址,可以写github,gitee等仓库地址,这里我就新建一个github测试仓库
keywords: fegq-test,test # 关键词,设置多个逗号隔开,填写属于这个包相关的
author: gitguanqi # 包作者,写你自己就可以
license: (ISC) MIT # 包遵守的软件开发协议,常用的有MIT,GPL3等
About to write to F:\web\front\test\template\npmlx\fegq-test\package.json:

{
  "name": "fegq-test",
  "version": "0.0.1",
  "description": "this is a test package.",
  "main": "./dist/mytest.js",
  "scripts": {
    "test": "jest"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/gitguanqi/fegq-test.git"
  },
  "keywords": [
    "fegq-test",
    "test"
  ],
  "author": "gitguanqi",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/gitguanqi/fegq-test/issues"
  },
  "homepage": "https://github.com/gitguanqi/fegq-test#readme"
}


Is this OK? (yes) # 直接回车解决
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

查看一下配置信息package.json

{
  "name": "fegq-test",
  "version": "0.0.1",
  "description": "this is a test package.",
  "main": "./dist/mytest.js",
  "scripts": {
    "test": "jest"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/gitguanqi/fegq-test.git"
  },
  "keywords": [
    "fegq-test",
    "test"
  ],
  "author": "gitguanqi",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/gitguanqi/fegq-test/issues"
  },
  "homepage": "https://github.com/gitguanqi/fegq-test#readme"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • 安装所需的依赖包

接着安装Babel,以及webpack以及jest系列依赖包

npm i babel-core babel-loader babel-plugin-add-module-exports babel-preset-env eslint webpack webpack-cli clean-webpack-plugin babel-jest jest jquery
1
  • 新建一个webpack.config.js配置文件,写入一下内容。
// webpack.config.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    mode: 'production', // 环境
    entry: './index.js', // 入口文件
    output: {
        path: path.resolve(__dirname, './dist'), // 输出文件夹
        filename: 'mytest.js', // 文件名称
        libraryTarget: 'umd', // 打包方式
        globalObject: 'this', // 全局对象
        library: 'mytest', // 类库名称
    },
    plugins: [
        new CleanWebpackPlugin(), // 清除上一次打包内容
    ],
    externals: {
        jquery: "jQuery", // 不参与打包编译
    },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

output.libraryTarget 一共支持的值:

  • var - 默认值
  • assign
  • this
  • window
  • global
  • commonjs
  • commonjs2
  • amd
  • umd
  • jsonp

如果你使用了诸如jquery,vue之类的包,不想打包到你自己的包里面,可以使用externals

例如:

externals: {
    jquery: "jQuery" 
},
1
2
3

# 编写一个方法

准备工作已经完成,现在进入正题,比如写一个加法的和dom操作的两个方法的包。

  • 新建一个lib文件夹,在面里面放置主要的方法。
mkdir lib
1
  • 编写方法
// ./lib/index.js
const $ = require('jquery');

function addCon () {  
    $('#content').html('<h1>hello</h1>');
}

function add (a,b) {  
    return a+b;
}

const test = {
    addCon,
    add,
}

module.exports = test;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • 引入lib内容

在包根目录下新建一个index.js做webpack入口文件,导入刚刚写好的方法。

// ./index.js
const mytest = require('./lib/index');
module.exports = mytest;
1
2
3

这样一个自己的包就写好了,接下来进行打包操作。

# 打包

  • 新增打包命令。

package.jsonscripts里面新增一条脚本命令webpack

如下:

{
  // ...
  "scripts": {
    "build": "webpack"
  },
  // ...
}
1
2
3
4
5
6
7
  • 开始打包

运行npm run build即可开始打包。

# 启动打包命令
npm run build

# 打包结果
> fegq-test@0.0.1 build
> webpack

asset mytest.js 617 bytes [emitted] [minimized] (name: main)
./index.js 64 bytes [built] [code generated]
./lib/index.js 218 bytes [built] [code generated]
external "jQuery" 42 bytes [built] [code generated]
webpack 5.64.4 compiled successfully in 425 ms
1
2
3
4
5
6
7
8
9
10
11
12

打包成功,现在可以进行简单的测试。

# 测试

这里使用jest来进行测试。

文件命名规则:<测试名称>.test.js

  • 新建一个测试文件add.test.js

写入以下内容,这里对add方法进行测试。

// ./my.test.js
const add = require('./dist/mytest').add;

test('adds 1 + 2 to equal 3', () => {
    expect(add(1,2)).toBe(3);
})
1
2
3
4
5
6
  • 开始测试
# 启动测试命令
npm run test

# 测试结果
> fegq-test@0.0.1 test
> jest

 PASS  ./add.test.js
  √ adds 1 + 2 to equal 3 (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.851 s, estimated 1 s
Ran all test suites.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

可以看到已经测试成功了。

  • 验证方法

新建一个example文件夹,写入node.js用于测试node环境,写入browser.html用于测试游览器环境。

mkdir example
1
// ./example/node.js
const fegqTestAdd = require('../dist/mytest').add;
console.log(fegqTestAdd(1,2)); // 3
1
2
3

运行node ./example/node.js查看一下,如果输出3说明测试成功。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>browser测试</title>
</head>
<body>
    <h2>fegq-test测试</h2>
    <script src="../dist/mytest.js"></script>
    <script>
        let result = mytest.add(1,2);
        console.log(result); // 3
    </script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

运行live-server --port=4001启动一个http服务,F12打开控制台输出3说明测试成功。

接下来就发布到npm上去吧。

# 发布

包代码写好后,可以先保存到github,然后再发布。

  • 拉去仓库初始化内容

这里采用ssh方式拉去和推送代码内容,省去用户权限验证等环节。

git clone git@github.com:gitguanqi/fegq-test.git
1

编写说明文档,介绍你的包使用方法。

可以先写cdn地址

https://unpkg.com/ (opens new window)

规则如下:

unpkg.com/:package@:version/:file

例如:

https://unpkg.com/jquery@3.6.0/dist/jquery.js


# fegq-test

this is a test package.

## use

+ browser

`<script src="https://unpkg.com/fegq-test@0.0.1/dist/mytest.js"></script>`

+ node

`npm install fegq-test`

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

然后推送到仓库。

git add .
git commit -m "add mytest"
git push origin main
1
2
3

好了,最后一步,发布你的包。

  • 发布到npm

如何发布公开npm包,我之前的这一篇《Node发布命令》已经说过了,这里就不再赘述。

我在这里就直接操作了。

# 启动发布命令
npm publish

# 发布结果
npm notice 
npm notice 📦  fegq-test@0.0.1
npm notice === Tarball Contents ===
npm notice 1.1kB LICENSE
npm notice 178B  README.md
npm notice 117B  add.test.js
npm notice 453B  example/browser.html
npm notice 87B   example/node.js
npm notice 64B   index.js
npm notice 218B  lib/index.js
npm notice 879B  package.json
npm notice 642B  webpack.config.js
npm notice === Tarball Details ===
npm notice name:          fegq-test
npm notice version:       0.0.1
npm notice filename:      fegq-test-0.0.1.tgz
npm notice package size:  2.2 kB
npm notice unpacked size: 3.7 kB
npm notice shasum:        2309f87ecd92c1c05cfe01ca1277208c530e483c
npm notice integrity:     sha512-xzksvqJrB7fgQ[...]Azc7jvZ2UXJnQ==
npm notice total files:   9
npm notice
+ fegq-test@0.0.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

接下来就可以在npm (opens new window)搜索到你的包了。

我的包npm地址是https://www.npmjs.com/package/fegq-test (opens new window)

# 常见问题

  • cdn地址出错

这里我查了一下是因为.gitignore文件禁止dist目录上传,进入文件删除一下即可。

# 最后

以上就是如何发布一款属于自己的包,游览器和node环境都兼容可用的方法。

如果有什么不足之处,可以邮箱联系我。

分享至:

  • qq
  • qq空间
  • 微博
  • 豆瓣
  • 贴吧