react发布一个组件库 系列篇(二)
前言
在上篇说到,不是特殊情况,我们尽量还是把源码打包编译成es5之后再发布到npm,这样用户使用的时候就很方便。
接下来我们就还拿上章的代码,使用rollup+babel编译、打包后再发版,来举个例子吧~
安装编译和打包工具
进入到组件库hello-cmp的根目录,安装打包工具rollup和编译工具babel、babel for react的预设
yarn add --dev rollup
yarn add --dev @babel/core @rollup/plugin-babel
yarn add --dev @babel/preset-react
新增编译和打包配置文件rollup.config.js
// rollup.config.js
import path from 'path'
import babel from '@rollup/plugin-babel';
const resolveFile = source => path.resolve(__dirname, source)
export default {
input: "index.jsx",
output: [
{
file: resolveFile('index.js'),
format: 'es'
},
],
plugins: [babel({
"presets": ["@babel/preset-react"]
})]
};
这里要注意下,在被处理的源码处要导入React,编译需要,即index.jsx改为如下
// index.jsx
import React from 'react'; // 即添加这行
export default (props)=>{
return <div>你好啊,{props.msg}</div>
}
编译和打包
准备完以上工作后,我们来打包,执行打包命令
npx rollup --c rollup.config.js
命令完成之后,就可以看到在目录下生成了打包后的文件 index.js
// index.js
import React from 'react';
var index = (props => {
return /*#__PURE__*/React.createElement("div", null, "你好啊", props.msg);
});
export { index as default };
通过观察编译打包后的输出文件内容,我们也能看到rollup打包esm的时候,对于import的是node_modules中内容的时候,基本直接输出模块化语法 并不会像webpack一样自己实现一遍模块处理(大量处理函数包裹包裹代码)
rollup这种做法非常的棒,因为库最终还是给项目用,项目本身的代码和用到的库本身都会再经历过webpack处理一遍。
所以大家经常说 webpack和rollup两者定位不通,rollup适合库打包,而webpack适合最终项目部署打包
发版
修改入口文件,即将packge.json的main改为index.js,最后一键发版npm publish
// packge.json
{
"name": "hello-cmp",
"version": "0.0.1-beta.6",
"description": "",
"main": "index.js",
"files": [
"index.js",
"package.json"
],
"keywords": [],
"author": "",
"license": "ISC"
}
使用
接下来我们在react项目中安装并使用下这个包。
不需要做任何配置(比如上一章节还需要额外配置include)
// src/app.js
import HelloCmp from 'hello-cmp'
function App() {
return (
<div className="App">
<HelloCmp msg="张三"/>
</div>
);
}
export default App;
效果如下
你好啊,张三
其它
有注意到我及使用rollup打包,但是我的插件项目依赖里依然没有这些。
这个其实有没有都可以。
1、运行时的依赖:在确定主项目 即 myApp项目有这些运行时和组件库有哪些共同依赖的情况下,插件本身是可以公用的 反正都在npm里(会自动向上找包)。
2、编译时的依赖: 都已经编译完成了提供给主项目了 主项目本身也不会用到。
3、放不放都没事:放上去也没事,无脑放上去,一个是不用npm和github的packge.json要维护两份。另一个是万一主项目没有,你的组件包用到了找不到 就不会报错。缺点就是在旧版npm情况下,放上依赖只会增加主项目的体积(这在新版npm或yarn上有所改善)
为什么要选择rollup打包呢?
因为一般开发插件或者组件库都不会使用webpack,比如我组件里因为了三方库。
webpack在打包我组件库的时候就会将其打进去,这不是必要的,因为使用者默认都会(是一般使用webpack)处理的导入三方包的语句。我在这里提前处理意义不大,而且还徒增我自己插件或者组件库的体积。还让代码变得巨大不利于阅读。
那为什么不用esbuild或者其他打包工具呢?因为插件较少。
那万一使用者的项目不是webpack,而是直接将包通过标签引入页面 用于浏览器怎么办?
这个时候我们就可以使用webpack给组件打包了,它会将三方包打进去了。
当然也可以继续用rollup打包成iife即可,配置external+output.globals标记外部库,通过cdn引入即可