环境初始化
mkdir npm-log
cd npm-log
npm init -y
入口文件
自定义依赖模块和命令行的入口文件不同:
模块是在
package.json
里通过main
字段定义这个包对外裸露的入口;- 模块起源于
node
,语法默认反对commonjs
标准 - 模块若应用
ES Module
语法书写,通过module
字段定义入口
- 模块起源于
- 如果是提供命令行工具,则须要通过
bin
字段来定义裸露的命令名称与理论执行的文件
模块
创立
lib/index.js
const Noop = () => {}class Logmi { errorHandler = Noop successHandler = Noop static create (options) { return new Logmi(options) } constructor (options = {}) { console.log('---------create------', options) } log (msg, level) { console.log('log: start', msg, level) }}module.exports = Logmi
更新
package.json
"main": "lib/index.js"
命令行
- 最次要的是在
package.json
里通过main
字段定义这个包对外裸露的入口; - 如果是提供命令行工具,则须要通过
bin
字段来定义裸露的命令名称与理论执行的文件
开发环境
- [ ] 主动日志
- [ ] 版本更新
husky
npm install husky --save-dev npx husky install
配置
run-script
:装置依赖后主动启动Git hooks
"prepare": "husky install"
追加测试钩子
# Unix零碎可用 npx husky add .husky/pre-commit "npm run test" # Windows通过以下命令创立文件(引号在windows下不是正确的语法) npx husky add .husky/pre-commit # Windows去新建的文件中指定命令 #!/bin/sh . "$(dirname "$0")/_/husky.sh" npm run test
commitlint
commitlint
提交信息校验工具- 须要和校验标准配合应用,官网默认标准
@commitlint/config-conventional
—— 可自定义。 commitlint
绑定@commitlint/config-conventional
# Unixecho "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js# Windowsecho module.exports = {extends: ['@commitlint/config-conventional']} > commitlint.config.js
配置
Git hook
:在提交commit msg
进行参数校验 —— 写在run-script
中有效# Unix零碎可用npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"# Windows通过以下命令创立文件(引号在windows下不是正确的语法)npx husky add .husky/commit-msg# Windows去新建的文件中指定命令#!/bin/sh. "$(dirname "$0")/_/husky.sh"npx --no-install commitlint --edit $1
standard-version
npm i --save-dev standard-version
配置
run-script
:公布前主动降级版本号 + 生成日志"publish": "standard-version"
调试
进入本地
NPM
包npm link
创立软链接到全局node
环境中
进入依赖包的我的项目A中
npm link <packageName>
建设软链接依赖
在我的项目A须要调用的文件中
# 调用import Logmi from "log";const LogmiInstance = Logmi.create({ url: 'http://localhost:3000'})LogmiInstance.log(`paste: ${JSON.stringify(paste)}`, 1)
- 启动我的项目A,即可调试
开发
NPM
包是commonJS
语法,应用require()
,而非import...from...
引入依赖。
实例化参数
- 工厂函数
参数默认值
const Noop = () => {}
:空语句
传参校验
- 参数数据实体类型
校验正告
- 参数合并
DTO
- 校验DTO组成构造参数
ParamChecker
- 对立构造
ContentWrapper
- 校验DTO组成构造参数
配置信息对立分类解决
module.exports = {EXCEED_TRY_TIMES: 'Exceed try times',}
打包公布
打包须要引入webpack
,这里的package.json
批改入口文件:
"main": "dist/logmi.js","module": "lib/index.js",
其中,main
是裸露打包后的入口文件;module
是webpack
环境下裸露的入口文件;
package.json
{ "name": "log", "version": "1.0.0", "description": "", "main": "dist/logmi.js", "module": "lib/index.js", "scripts": { "prepare": "husky install", "build": "cross-env NODE_ENV=production webpack --config webpack.config.js --mode=production", "test": "echo \"npm run test\" && exit 1" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.14.3", "@babel/preset-env": "^7.14.4", "@commitlint/cli": "^12.1.4", "@commitlint/config-conventional": "^12.1.4", "babel-loader": "^8.2.2", "cross-env": "^7.0.3", "husky": "^6.0.0", "standard-version": "^9.3.0", "terser-webpack-plugin": "^5.1.3", "webpack": "^5.38.1", "webpack-cli": "^4.7.0" }, "dependencies": { "@babel/polyfill": "^7.12.1", "idb-managed": "^1.0.9" }, "bundledDependencies": [ "idb-managed" ]}
pkg#main
作为第三方依赖包时,包的入口执行文件。
如果没有指定,默认为root
目录下的index.js
。
pkg#bin
作为命令行工具时,包的入口执行文件
装置该包时,node
会主动创立硬链接该包到全局执行环境。
String
:单执行文件Map
:多执行文件
pkg#module
非官方配置,rollup
、webpack
等打包工具提供的配置项。
指向的应该是一个基于ES6
模块标准书写的模块。
pkg#private
设置"private": true
,npm
回绝公布该包。
pkg#workspaces
联合monorepo
的概念,创立工作区。
pkg#files
装置该包时,目录中蕴含在pkg.files
中指定的文件构造。
默认蕴含:
package.jsonREADMECHANGES / CHANGELOG / HISTORYLICENSE / LICENCENOTICEThe file in the "main" field
pkg#bundledDependencies
通过fpt
、scp
等工具传输该包时,须要将该包的依赖打包在一起。
在
bundledDependencies
中指定依赖包的列表- 只须要指定包名,版本会在
dependencies
查找
- 只须要指定包名,版本会在
- 通过
npm pack
打包 - 通过传输工具传输打好的
*.tgz
包 - 通过
npm i *.tgz
装置该包及其依赖
pkg#peerDependencies
表明该包对主包/主工具库的兼容性,而不是依赖性,这种关系称之为插件。
- 主包个别会对插件暴漏的接口指定规范
在peerDependencies
指定的包@版本号
表明,咱们的包须要在指定包的环境下执行,须要一起装置。
打包
装置插件
npm i -D webpack-cli webpack cross-env terser-webpack-plugin
npm install --save-dev @babel/core babel-loader @babel/preset-envnpm install --save @babel/polyfill
配置babel.config.json
{ "presets": [ [ "@babel/env", { "targets": { "edge": "17", "firefox": "60", "chrome": "67", "safari": "11.1" }, "useBuiltIns": "usage", "corejs": "3.6.5" } ] ]}
配置run-script
... "build": "cross-env NODE_ENV=production webpack --config webpack.config.js --mode=production",...
webpack.config.js
const path = require('path')const webpack = require('webpack')const TerserPlugin = require("terser-webpack-plugin")const resolve = dir => path.join(__dirname, '.', dir)const isProd = process.env.NODE_ENV === 'production'module.exports = { entry: { logmi: './lib/index.js' }, output: { path: resolve('dist'), // 输入目录 filename: '[name].js', // 输入文件 libraryTarget: 'umd', // 采纳通用模块定义 library: 'logmi', // 库名称 libraryExport: 'default', // 兼容 ES6(ES2015) 的模块零碎、CommonJS 和 AMD 模块标准 globalObject: 'this' // 兼容node和浏览器运行,防止window is not undefined状况 }, devtool: 'source-map', module: { rules: [ { test: /\.js$/, exclude: /(node_modules)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] }, optimization: { minimize: true, minimizer: [new TerserPlugin()], }}
配置可见目录构造
... "files": [ "dist/" ]...
补充常识
[ ]
Peer Dependencies
The peerDependencies configuration was originally designed to address the problem of NPM packages that were ‘plugins’ for other frameworks.
删除CHangeLog
- https://github.com/convention...
- https://lukasznojek.com/blog/...