前言

经常使用别人写好的组件库,然后安装引入使用即可。比如:

npm install beautiful-table
import BeautifulTable from 'beautiful-table'

function App() {
return (
<div className="App">
<BeautifulTable/>
</div>
);
} export default App;

这对于我们开发这来说,非常的舒服对吧!

那么你有考虑这些组件是如何编写的吗?

接下来,我将从头到尾的,写一个demo组件库,并且发版到npm平台上!

这个组件我们起名字 哈喽组件, 即 hello-componet简写下 hello-cmp。

然后我们再新建一个react简单项目 起名为myApp,在这个项目使用组件库hello-cmp。

思考:可否将源代码直接发包

有了这个想法很好,这就是编写组件库的第一步!

这是最简单的方式,不用任何编译工具进行转换,直接将源码发布到npm上。

├── index.jsx                 组件核心
├── package.json
// index.jsx
export default (props)=>{
return <div>你好啊,{props.msg}</div>
}
// package.json
{
"name": "hello-cmp",
"version": "0.0.1-beta.2",
"description": "",
"main": "index.jsx",
"keywords": [],
"author": "",
"license": "ISC"
}

接下来我们尝试在一个现有的react项目中安装并使用下这个包

// src/app.js
import HelloCmp from 'hello-cmp' function App() {
return (
<div className="App">
<HelloCmp msg="张三"/>
</div>
);
} export default App;

xx,尴尬的事情发生了,页面以及启动控制台底部都输出了相同的错误

Compiled with problems:X

ERROR in ./node_modules/hello-cmp/index.jsx 2:11

Module parse failed: Unexpected token (2:11)
File was processed with these loaders:
* ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| export default (props)=>{
> return <div>你好啊,{props.msg}</div>
| }

这是因为默认情况下,项目(里的编译工具如babel、esbuild等)均忽略node_modules里的代码处理

而react脚手架创建的项目中 将jsx等文件的解析器用的就是是babel,所以在babel-loader没有处理jsx转换为js的情况下,交给下一个loader即source-map-loader处理。

可loader链里的source-map-loader只能处理js文件,遇到了没有经过babel-loader处理的hello-cmp组件库里的jsx元素交给它处理的时候 自然就崩溃了。

知道原因,自然就好处理了,我们修改当前react项目myApp的webpack配置里的babel-loader,将其不要忽略包hello-cmp的编译即可。

npm run eject之后,修改webpack配置文件如下:修改rules字段,让只编译src扩充到也编译你的包,即可。

eject后查看webpack.config.js 也可以发现react脚手架创建的项目中 将jsx等文件的解析器用的loader是babel-loader,而babel-loader默认即忽略node_modules

// webpack.config.js
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
// 原来这有这个 include: paths.appSrc,
// 其中paths.YourCmp即在path中定义的你组件包的路径 resolveApp('node_modules/YourCmp')
include: [paths.appSrc,paths.YourCmp],
...
}

再次启动,自动打开浏览器,访问页面,开心的一幕出现了

你好啊,张三

结论

1、虽然 npm 中的 package 没有明确规范需要编译成 es5/es3的语法,但是目前事实就是绝大部分公开的 package 都是编译到这个规范的,所以已经是一个事实标准了,如果你的包代码是低版本的js 你当然可以直接发版源码。

2、但是如果是你用到了jsx、ts、vue或用到了esnext最新版本等(非js语言的),别人下载引入你的包 自然也无法开箱即用了。

a、使用者下载安装你的包后,仍然还需要去安装对用的编译器去编译你的代码之后才可以使用。

b、而且很多编译工具默认都会忽略node_modules下的代码,也意味着你还要去设置它(某编译器的)include。

与其麻烦每个使用者一顿猛如虎的操作,还不如库作者直接处理好供我们使用。

3、我司内部的 package 为了方便调试和学习,都是直接暴露源码的,那就需要手动修改编译工具配置 include 相应的包了,大家也可能会遇到这种情况,那发布源码也是请情有可原

其它

如果你的代码里如果只有js+esm,直接发包就可以了,这个不用编译再发包也是可以的。

因为你开发的插件或组件库, 最终还要引入到一个项目中的。

这个项目多半是脚手架创建的 或者至少支持webpack的。

而你组件库或插件里的 esm最终会被当前项目的webpack处理(webpack就是干这个的),webpack并不会忽略node_modules。

比如:以下代码可以直接发包源码,在项目使用就行(放在2020年之前不行,仍然需要通过babel打包,那个时候esm上不被认可,大家还是通过babel将其转换成cjs)

├── index.js
├── calculator.js
├── package.json
// index.js
import {add} from './calculator'
export default add(1,2)
// calculator.js
export function add(x,y){
return x+y;
}

react发布一个组件库 系列篇(一)的更多相关文章

  1. 教你一步步发布一个开源库到 JCenter

    今天想来分享下,如何一步步自己发布一个开源库到 JCenter 这方面的博客网上已经特别多了,所以本篇并不打算仅仅只是记录流程步骤而已,而是尽可能讲清楚,为什么需要有这个步骤,让大伙知其然的同时还知其 ...

  2. 如何基于 React 封装一个组件

    如何基于 React 封装一个组件 前言 很多小伙伴在第一次尝试封装组件时会和我一样碰到许多问题,比如人家的组件会有 color 属性,我们在使用组件时传入组件文档中说明的属性值如 primary , ...

  3. Vue3 企业级优雅实战 - 组件库框架 - 12 发布开源组件库

    前面使用了 11 篇文章分享基于 vue3 .Monorepo 的组件库工程完整四件套(组件库.文档.example.cli)的开发.构建及组件库的发布.本文属于这 11 篇文章的扩展 -- 如何发布 ...

  4. 基于react hooks,zarm组件库配置开发h5表单页面

    最近使用React Hooks结合zarm组件库,基于js对象配置方式开发了大量的h5表单页面.大家都知道h5表单功能无非就是表单数据的收集,验证,提交,回显编辑,通常排列方式也是自上向下一行一列的方 ...

  5. 微信小程序 MinUI 组件库系列之 price 价格组件

    MinUI 是基于微信小程序自定义组件特性开发而成的一套简洁.易用.高效的组件库,适用场景广,覆盖小程序原生框架.小程序组件化框架等,并且提供了高效的命令行工具.MinUI 组件库包含了很多基础的组件 ...

  6. React Native 一个组件styles BUG

    'use strict'; var React = require('react-native'); var { StyleSheet, PanResponder, View, Text } = Re ...

  7. react使用ant-design组件库

    新建项目并引入组件 1,全局安装脚手架 npm install -g create-react-app 2,新建项目 create-react-app reactantd 3,安装组件 npm ins ...

  8. 模仿慕课网一步步发布一个开源库到 JCenter

    H:\common\-common-25.2.2\upload.gradle // Bintray /* Properties properties = new Properties() proper ...

  9. 从0搭建Vue3组件库(七):使用 glup 打包组件库并实现按需加载

    使用 glup 打包组件库并实现按需加载 当我们使用 Vite 库模式打包的时候,vite 会将样式文件全部打包到同一个文件中,这样的话我们每次都要全量引入所有样式文件做不到按需引入的效果.所以打包的 ...

  10. [翻译]怎么写一个React组件库(二)

    本文同步发布于知乎专栏 https://zhuanlan.zhihu.com/p/27434018,喜欢本文的就去知乎点个赞支持下吧- 引言 该系列文章将通过创建一个组件库来引导你学习如何构建自己的组 ...

随机推荐

  1. SpringBoot 部署:外置依赖包

    目录: 1.前言 2.瘦身前的Jar包 3.解决方案 一.前言 SpringBoot部署起来虽然简单,如果服务器部署在公司内网,速度还行,但是如果部署在公网(阿里云等云服务器上),部署起来实在头疼:编 ...

  2. 深度学习实战:从零构建图像分类API(Flask/FastAPI版)

    引言:AI时代的图像分类需求 在智能时代,图像分类技术已渗透到医疗影像分析.自动驾驶.工业质检等各个领域.作为开发者,掌握如何将深度学习模型封装为API服务,是实现技术落地的关键一步.本文将手把手教你 ...

  3. Python科学计算系列5—导数

    1.一元函数的导数 例1:求下列函数的导数 例2:求下列函数的50阶导数 代码如下: from sympy import * x = symbols('x') f1 = diff(tan(x)) f2 ...

  4. Condition类的signal()方法底层原理

    一.Condition类的signal()方法底层原理 Condition 接口的 signal 方法是用于唤醒一个在 Condition 上等待的线程.与 Object 的 notify 方法类似, ...

  5. 『Plotly实战指南』--雷达图绘制与应用

    在数据分析和可视化领域,雷达图是一种适用于多维数据的可视化.综合评估和决策支持的工具. 雷达图通过将数据点沿多个轴分布,并通过多边形面积或线条连接来展示数据的多维度特征,能够直观地呈现数据在各个维度上 ...

  6. python发送QQ邮件,自定义邮件内容

    怎么发QQ邮件,网上的例子很多,就不介绍了,具体可参考:https://www.jianshu.com/p/0f8c5e4e7054 这里主要把自定义邮件内容写一下 # -*- coding: utf ...

  7. Apache Flink(CVE-2020-17519)路径遍历漏洞复现_附POC和批量检测脚本

    声明 本文仅用于技术交流,请勿用于非法用途 由于传播.利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任. 文章作者拥有对此文章的修改和解释权.如 ...

  8. python-docx设置标题颜色

    from docx import Document from docx.enum.text import WD_PARAGRAPH_ALIGNMENT from docx.shared import ...

  9. 17.1K star!两小时就能训练出专属于自己的个性化小模型,这个开源项目让AI触手可及!

    「只需一张消费级显卡,2小时完成26M参数GPT训练!」「从零构建中文大模型的最佳实践指南」「兼容OpenAI API,轻松接入各类AI应用平台」 项目介绍 MiniMind是由开发者Jingyao ...

  10. 鸿蒙NEXT开发教程:浅谈@ComponentV2装饰器

    听说今天的广州车展上有一部分人已经看到华为汽车的最后一"界",尊界超豪华大轿车,应该很快就要正式亮相,可以期待一波. 在api12之后,鸿蒙系统推出一个V2版本的状态管理装饰器,不 ...