@surveyking/my-component v1.0.2
如何发布 npm 包
Webpack 的配置文件主要做了如下事情:
- 使用 example/src/index.js作为项目入口,处理资源文件的依赖关系
- 通过 babel-loader来编译处理 js和jsx文件
- 通过style-loader 和 css-loader来处理 css 依赖和注入内联样式
- 通过html-webpack-plugin自动注入编译打包好的脚本文件
- 为 demo 启动端口为 3001 的服务
后需要指定 Babel 需要对哪些文件进行编译,毫无疑问 React 中使用的 JSX 文件需要被编译,让它转换成被主流浏览器都支持的 ES5 ,通用的配置也很简单,只需要添加一对 presets,在项目根目录下添加文件.babelrc
{
"presets": ["env", "react"]
}
发布到 npm 是一个很简单自动化的工作,只是在发布前需要做如下工作
我们要发布被 babel 编译且被压缩后的版本,要让没有使用 babel 的项目也能够正常的使用,比如不能出现 JSX 语法
首先需要安装 babel cli
npm i babel-cli -D
现在我们添加 transpile脚本,以便使用 Babel 编译我们的源代码,同时拷贝一些静态文件(如:css 文件)到目标打包目录dist下
同时指定被编译后的版本为组件的主入口,更改后的 package.json
npm run transpile
现在在我们项目根目录下面会有一个 dist 目录,包含了 index.js 的编译版本,和拷贝的样式文件styles.css,这些文件是用户可以直接 可以import到他们项目的文件,接下来我们再在我们的工作流中添加一个脚本prepublishOnly ,这个脚本会在每次我们需要发布我们的组件到 npm上去的时候会自动执行,他能确保我们每次发布上去的代码都是最新代码编译的
另外我们需要告诉用户在用户我们的组件的时候对于 React 版本的要求,peerDependency 能够很好的表达这个信息,同时在我们的发布的组件包中不会包含 react , 这样也减小了包的大小,更加重要是可以避免在用户的项目中存在多个 react 版本,更改后的 package.json如下
最后让我们在项目的根目录下添加.npmignore文件,告诉 npm,我们项目中哪些文件和文件夹是在发布的包中被忽略掉的
# .npmignore
src
examples
.babelrc
.gitignore
webpack.config.js
dependencies 区别
- devDependecies 蛀牙放置本地开发过程需要使用到的编译、打包、测试、格式化模块,安装依赖的时候,不会安装依赖的 devDependencies 运行时用不到的依赖,放在 devDependencies 中
- dependencies 项目中实际运行需要用到的代码,没有的话会出错,安装依赖的时候会
- peerDependencies 同级依赖,用在发布的代码库当中,表示需要宿主环境提供该配置下的模块依赖,与宿主环境息息相关。npm(3.x 版本之后,7.x 之前)、yarn 不会自动安装该配置下的依赖模块,会告警提示。要求运行时时单例的依赖(vue、react 等同时只能存在一个实例)使用 peerDependencies
// faker-project
{
"name": "faker-project",
"dependencies": {
"sdk-a": "1.0.0"
}
}
// sdk-a
{
"name": "sdk-a",
"version":"1.0.0",
"dependencies": {
"sdk-core": "0.0.1"
}
}
faker project 执行
|
├── node_modules
| ├── sdk-a
| └── sdk-core
|
└── package.json
假设现在有一个 helloWorld 工程,已经在其 package.json 的 dependencies
中声明了 packageA,有两个插件 plugin1 和 plugin2 他们也依赖 packageA,如果在插件中使用 dependencies
而不是 peerDependencies
来声明 packageA,那么 $ npm install
安装完 plugin1 和 plugin2 之后的依赖图是这样的:
.
├── helloWorld
│ └── node_modules
│ ├── packageA
│ ├── plugin1
│ │ └── nodule_modules
│ │ └── packageA
│ └── plugin2
│ │ └── nodule_modules
│ │ └── packageA
而 peerDependency
就可以避免类似的核心依赖库被重复下载的问题。
- 如果用户显式依赖了核心库,则可以忽略各插件的
peerDependency
声明; - 如果用户没有显式依赖核心库,则按照插件
peerDependencies
中声明的版本将库安装到项目根目录中;
npm的扁平化安装
你想要在使用你的插件的时候自动安装的,就用dependencies,一般都是构建后会用到的包,peerDependencies是没有显式依赖的,不会影响你的插件构建,你希望用户项目内有,但是不会自动下载的 如果你使用peerDependencies,但是构建会报错,说明你的项目用到了那个包,并且构建时依赖了,一般插件都不会把npm的依赖打包进去,因为如果你直接打包进去了,那么会导致例如vue和corejs代码在项目内存在多个 一般看你的插件打包配置是否正确,就看比如vue和corejs等npm包代码在dist代码里是require或import的,还是直接把代码打包进去了,应该都是require和import的才对