开发一个组件库,最后一步是将组件库发布到 npm
上。这样,全世界的开发者就可以直接安装使用。如何让其他开发者在使用我们的组件库时能够安装更快、体验更好呢?这里,除了优化组件库本身的代码外,还可以通过优化组件库的 package.json
来实现。
开发环境
-
create-react-app -
react 16.8.0+ -
typescript 4.5.5 -
jest -
testing-library -
scss -
storybook -
eslint -
husky -
……
优化前的 package.json
内容有点长,和我们平时使用的基本一致,可以简单看一下就行。主要用于前后对比。
{
"name": "vikingship",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "react-scripts start",
"build": "npm run build-ts && npm run build-css",
"test": "react-scripts test",
"eject": "react-scripts eject",
"build-ts": "tsc -p tsconfig.build.json",
"build-css": "node-sass ./src/styles/index.scss ./dist/index.css",
"lint": "eslint -c .eslintrc.js --ext .js,.jsx,.ts,.tsx",
"lint:fix": "npm run lint -- --fix",
"storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook -s public"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.3.0",
"@fortawesome/free-solid-svg-icons": "^6.0.0",
"@fortawesome/react-fontawesome": "^0.1.17",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"@types/classnames": "^2.3.1",
"@types/jest": "^27.4.0",
"@types/node": "^16.11.22",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.11",
"@types/react-transition-group": "^4.4.4",
"@types/storybook__addon-info": "^5.2.4",
"axios": "^0.26.0",
"classnames": "^2.3.1",
"node-sass": "^7.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"react-transition-group": "^4.4.2",
"typescript": "^4.5.5",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@storybook/addon-actions": "^6.4.19",
"@storybook/addon-docs": "^6.4.19",
"@storybook/addon-essentials": "^6.4.19",
"@storybook/addon-info": "^5.3.21",
"@storybook/addon-interactions": "^6.4.19",
"@storybook/addon-links": "^6.4.19",
"@storybook/builder-webpack5": "^6.4.19",
"@storybook/manager-webpack5": "^6.4.19",
"@storybook/node-logger": "^6.4.19",
"@storybook/preset-create-react-app": "^4.0.1",
"@storybook/preset-scss": "^1.0.3",
"@storybook/react": "^6.4.19",
"@storybook/testing-library": "^0.0.9",
"css-loader": "^6.6.0",
"react-docgen": "^5.4.0",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"style-loader": "^3.3.1",
"webpack": "^5.69.1"
},
"eslintConfig": {
"overrides": [
{
"files": [
"**/*.stories.*"
],
"rules": {
"import/no-anonymous-default-export": "off"
}
}
]
}
}
优化步骤
移除之前 build 生成的文件夹
初始化 package.json
中的 build
,每个在执行 npm run build
时,都会在 dist
文件夹下重新生成构建好的文件内容。但这有一个问题,如果我组件库中的一个组件已经删除了,但是之前构建在 dist
目录下的对应的组件文件依然存在。所以,我们需要在 build
之前,删除掉之前的 dist
文件夹。
由于不同的系统,删除文件夹的命令不一致,所以这里借助一个叫 rimraf
的工具来进行。
执行命名
npm install rimraf --save-dev
安装好 rimraf
后,修改 build
命令如下所示:
"script": {
...
- "build": "npm run build-ts && npm run build-css",
+ "clean": "rimraf ./dist",
+ "build": "npm run clean && npm run build-ts && npm run build-css",
...
},
"devDependencies": {
...
+ "rimraf": "^3.0.2",
...
}
添加基本信息
因为组件库需要提供给其他开发者使用,所以需要设置项目的 private: false
,指定组件库不是私有的,是公开的。需要的其它信息还包括:
-
description
组件的描述 -
author
作者 -
main
入口文件 -
module
导出的模块文件 -
types
对应的ts
定义文件 -
license
遵循的开源协议 -
keywords
关键字,方便其他人搜索使用 -
homepage
/repository
项目对应的git
仓库地址 -
files
指定哪些文件 / 文件夹需要上传到npm
上
{
...
- "private": true,
+ "private": false,
+ "description": "这里是包的描述内容",
+ "author": "作者名字",
+ "main": "dist/index.js",
+ "module": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "license": "MIT",
+ "keywords": [
+ "component",
+ "UI",
+ "React"
+ ],
+ "homepage": "https://github.com/xiangming25/vikingship.git",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/xiangming25/vikingship.git"
+ },
+ "files": [
+ "dist"
+ ],
...
}
发布之前执行构建命令
"script": {
...
+ "prepublish": "npm run build"
...
}
精简 package.json 依赖
初始化项目时,有许多的包都是放在 dependencies
下面的,这样在 npm install
时,都会进行下载安装。但像 @types/*
下面的定义文件、将 scss
处理为 css
的 node-sass
、开发时需要启动服务的 react-scripts
、以及帮助我们提高代码质量和效率的 typescript
等。这些都只是我们在开发过程中需要用到,在发布后的组件库中完全不需要用到它们,所以这里对依赖项的位置进行调整,将只在开发环境中用到的组件放在 devDependencies
中。
{
...
"dependencies": {
...
- "@types/classnames": "^2.3.1",
- "@types/jest": "^27.4.0",
- "@types/node": "^16.11.22",
- "@types/react": "^17.0.39",
- "@types/react-dom": "^17.0.11",
- "@types/react-transition-group": "^4.4.4",
- "@types/storybook__addon-info": "^5.2.4",
- "node-sass": "^7.0.1",
- "react-scripts": "5.0.0",
- "typescript": "^4.5.5",
...
},
"devDependencies": {
...
+ "@types/classnames": "^2.3.1",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^16.11.22",
+ "@types/react": "^17.0.39",
+ "@types/react-dom": "^17.0.11",
+ "@types/react-transition-group": "^4.4.4",
+ "@types/storybook__addon-info": "^5.2.4",
+ "node-sass": "^7.0.1",
+ "react-scripts": "5.0.0",
+ "typescript": "^4.5.5",
...
},
...
}
优化 react & react-dom
组件库的 react
版本可能不能与其他开发者使用的 react
版本完全一致,如果不一致,就又会下载安装一次,并且还会出现一些奇怪的问题。所以我们可以将 react
以及 react-dom
放在 peerDependencies
中。这样就可以告诉用户,我们需要的最低版本是多少,只要开发者的实际项目满足最低版本要求就行。
{
...
"dependencies": {
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
}
...
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0",
+ }
...
"devDependencies": {
...
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
...
}
},
}
注意为什么又将 react
以及 react-dom
放在了 devDependencies
下面。这是因为放在 peerDependencies
下面可以满足使用组件的人能够正常运行,但是我们在开发调试时,就不能正常运行了。所以需要将 react
和 react-dom
添加在 devDependencies
下面。
添加组件测试&风格检测
默认使用 react-scripts test
对代码进行测试,会在控制台中一直处于 watch
状态,控制台一直会卡在那里,不会有任何的返回值。查阅文档如果先设置环境变量为 CI=true
,就不会一直处于 watch
状态,直接就会有测试结果的返回值。
问题又来了。在不同的系统设置环境变量的方式又是不一样,所以我们又需要借助 cross-env
工具来实现。
安装 cross-env
npm install cross-env -D
添加 test
命令
{
...
+ "test:nowatch": "cross-env CI=true react-scripts test",
- "prepublish": "npm run build",
+ "prepublishOnly": "npm run test:nowatch && npm run lint && npm run build"
...
"devDependencies": {
...
+ "cross-env": "^7.0.3",
...
}
}
注意这里为什么将 prepublish
修改为 prepublishOnly
。原因是因为 prepublish
在 npm install
时也会执行,这不是我们预期的效果。所以使得 prepublishOnly
来进行实现。
添加 husky
为了保证在开发过程中就对代码质量有所保证。我们在 git
提交时,就对组件进行测试以及对代码风格进行检查。这里我们使用到一个新的工具 husky
。
执行命令安装 husky
npm install husky -D
在项目中使用 husky
npm set-script prepare "husky install"
npm run prepare
添加钩子方法
npx husky add .husky/pre-commit "npm run test:nowatch && npm run lint"
git add .husky/pre-commit
husky
不同版本的设置方法可能不同,大家可以根据自己实际使用的版本进行配置。
{
...
+ "husky": {
+ "hooks": {
+ "pre-commit": "npm run test:nowatch && npm run lint"
+ }
+ },
"devDependencies": {
...
+ "husky": "^7.0.4",
...
}
...
}
husky
仓库的地址为:https://github.com/typicode/husky
最终的 package.json
{
"name": "vikingship",
"version": "0.1.0",
"private": false,
"description": "这里是包的描述内容",
"author": "xiangming",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
"keywords": [
"component",
"UI",
"React"
],
"homepage": "https://github.com/xiangming25/vikingship.git",
"repository": {
"type": "git",
"url": "https://github.com/xiangming25/vikingship.git"
},
"files": [
"dist"
],
"scripts": {
"start": "react-scripts start",
"clean": "rimraf ./dist",
"build": "npm run build-ts && npm run build-css",
"test": "react-scripts test",
"test:nowatch": "cross-env CI=true react-scripts test",
"eject": "react-scripts eject",
"build-ts": "tsc -p tsconfig.build.json",
"build-css": "node-sass ./src/styles/index.scss ./dist/index.css",
"lint": "eslint -c .eslintrc.js --ext .js,.jsx,.ts,.tsx src --max-warnings 5",
"lint:fix": "npm run lint -- --fix",
"storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook -s public",
"prepublishOnly": "npm run test:nowatch && npm run lint && npm run build",
"prepare": "husky install"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.3.0",
"@fortawesome/free-solid-svg-icons": "^6.0.0",
"@fortawesome/react-fontawesome": "^0.1.17",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.26.0",
"classnames": "^2.3.1",
"react-transition-group": "^4.4.2",
"web-vitals": "^2.1.4"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
},
"devDependencies": {
"@storybook/addon-actions": "^6.4.19",
"@storybook/addon-docs": "^6.4.19",
"@storybook/addon-essentials": "^6.4.19",
"@storybook/addon-info": "^5.3.21",
"@storybook/addon-interactions": "^6.4.19",
"@storybook/addon-links": "^6.4.19",
"@storybook/builder-webpack5": "^6.4.19",
"@storybook/manager-webpack5": "^6.4.19",
"@storybook/node-logger": "^6.4.19",
"@storybook/preset-create-react-app": "^4.0.1",
"@storybook/preset-scss": "^1.0.3",
"@storybook/react": "^6.4.19",
"@storybook/testing-library": "^0.0.9",
"@types/classnames": "^2.3.1",
"@types/jest": "^27.4.0",
"@types/node": "^16.11.22",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.11",
"@types/react-transition-group": "^4.4.4",
"@types/storybook__addon-info": "^5.2.4",
"babel-eslint": "^10.1.0",
"cross-env": "^7.0.3",
"css-loader": "^6.6.0",
"husky": "^7.0.4",
"node-sass": "^7.0.1",
"react": "^17.0.2",
"react-docgen": "^5.4.0",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"rimraf": "^3.0.2",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"style-loader": "^3.3.1",
"typescript": "^4.5.5",
"webpack": "^5.69.1"
},
"eslintConfig": {
"overrides": [
{
"files": [
"**/*.stories.*"
],
"rules": {
"import/no-anonymous-default-export": "off"
}
}
]
}
}
总结
最近重新学习了一遍组件库的开发,对组件的开发又有了许多新的认识。很多需求都可以渐进式开发,并不是一来就能想得非常的全面,很多时候都是在做的过程中不断升级优化,然后越来越好。
原文始发于微信公众号(前端学习总结):如何优化组件库的package.json
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/83090.html