还不会发包?30S教会你
前言
学会发包可以避免我们在项目开发中重复造轮子的现象;当我们开发了通用的组件或者工具库后可以将其发布到
npm
上,这样在我们后续有同样需求的时候就可以直接下载下来用了,是不是灰常的的灵性。不知道怎么发包的小伙伴可以跟着我从0到1的发布一个包(发包流程跟技术框架和打包工具没有必然的联系,可根据自身情况进行技术选型)
技术栈
- Vite
- React
- TypeScript
- Less
- Npm
操作流程
1. 准备项目工程并编写组件
- 创建一个基础模板(这里我通过
vite
创建一个react
模板,node
版本要求:14.18+,16+ )
npm: npm create vite@latestoryarn: yarn create vite
然后根据命令行提示输入项目名称、选择框架、选择语言
我这边选择的是:React
和TypeScript
- 项目创建后先安装依赖
npm: npm install
npm: npm install less less-loader -Doryarn: yarn
yarn: yarn add less less-loader -D
- 改造模板(可根据个人习惯改造)
- 删除样式文件
App.css
和index.css
- 在
assets
目录创建styles
目录用于存放样式 - 在
/assets/styles
新建index.less
文件,所有样式都统一从这里导出 - 在
src
目录下新建components
目录用于编写组件 - 在
/src/components
目录下新建index.ts
文件,所有组件都统一从这里导出 - 跟目录下新建
index.d.ts
类型文件 - 改造
main.tsx
- 改造
App.tsx
类型文件index.d.ts
import { ReactNode } from "react"export declare type XButtonType = {children: string | ReactNodeprimaryColor?: stringonClick?: () => void
}
main.tsx
改造后
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
// 引入项目所需样式
import './assets/styles/index.less'
// 导出组件
export * from './components/index'const mode = import.meta.env.MODEif (mode !== 'production') {// <App /> 组件里面可以放我们的组件测试代码 所以开发环境这一步是必要的// 但是生产环境渲染节点会显得多余 所以生产环境不需要这一步(主要是react18+ createRoot不能使用多次,否则开发者使用该包时控制台会报警告)ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />)
}
App.tsx
改造后
import { XButton } from "./components"function App() {return (<div className="App"><XButton>测试</XButton></div>)
}export default App
献上我的组件 components/XButton.tsx
import React from "react";
import { XButtonType } from "../..";// 组件很简单 就是一个可以动态改变颜色和内容的按钮
export default function XButton(props: XButtonType) {const { children, primaryColor = "#8f0ce7", onClick } = props;const style: React.CSSProperties = {"--x-primary-color": primaryColor,} as React.CSSProperties;return (<button className="x-button" style={style} onClick={onClick}>{children}</button>);
}
** 注意点:使用index.d.ts
文件需要在tsconfig.json
文件中配置一下
"include": ["src"],
// 配置后
"include": ["src", "index.d.ts"],
2. 配置vite.config.ts
- 下载
path
npm: npm install path -Doryarn: yarn add path -D
- 配置
vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'// https://vitejs.dev/config/
export default defineConfig({plugins: [react()]build: {lib: {// 打包入口entry: resolve('src', 'main.tsx'),name: 'x-button',// 文件名称fileName: 'index',},rollupOptions: {// 确保外部化处理那些你不想打包进库的依赖external: ['react', 'react-dom'],output: {// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量globals: {react: 'React',},},},// 打包输出目录outDir: 'lib/dist', },
})
- 执行打包命令
npm: npm run buildor yarn: yarn build
- 根目录会生成一个
lib
目录,这时打包工作已经完成,不过还有几个坑我们后面来填
3. 配置npm
- 终端执行命令
npm init
- 根据命令行提示输入对应信息
package name
: 包名,发到npm
上的名称version
: 版本号description
:项目描述(选填)entry point
: 入口文件路径(路径就是我们打包后的目录文件./lib/dist/index.js
)git repository
:仓库地址(选填)keywords
: 关键词(选填)author
:作者信息(选填)license
:开源协议(默认ISC
,关于开源协议可以自行了解)
- 修改
package.json
部分配置
{"name": "xz-test-button","private": false, // true改为false"version": "0.0.1","type": "module","scripts": {"dev": "vite","build": "tsc && vite build","preview": "vite preview"},"dependencies": {"react": "^18.2.0","react-dom": "^18.2.0"},"devDependencies": {"@types/react": "^18.0.22","@types/react-dom": "^18.0.7","@vitejs/plugin-react": "^2.2.0","less": "^4.1.3","less-loader": "^11.1.0","path": "^0.12.7","typescript": "^4.6.4","vite": "^3.2.2"},"types": "./index.d.ts","description": "按钮","main": "./lib/dist/index.js",// 新增 ----------->----------->"module": "./lib/dist/index.js","exports": {".": {"import": "./lib/dist/index.js","require": "./lib/dist/index.umd.cjs"}},"files": ["lib","index.d.ts"],// <--------------<------------"author": "","license": "ISC"
}
经过上面操作我们的准备工作已经完成
4. 发布
- 没有
npm
账号的可以先去npm官网注册一个或者通过npm adduser
命令注册 - 完成上面步骤后我们先登录npm账号,执行
npm login
命令进行登录,根据命令行提示输入用户名、密码、邮箱、邮箱验证码 - 登录完成后我们执行
npm publish
命令进行发布- 这里发包可能会出现
404或者403
,这时先确保是否登录成功,然后再确认当前项目名称是否和npm已有的包冲突,更换名字后再进行尝试 - 每次发包需要保证当前版本号在此之前没有被使用(发布)过
- 这里发包可能会出现
- 当终端没有报错且最后一行显示包名和版本号就表示发布成功
- 如
xz-test-button@0.0.1
- 可以去
npm
官网去搜索自己的包名或者在自己的包列表查看
- 如
- 完成以上操作后一个
npm
包就算是发布成功了,但是还没完…
5. 使用
- 在另一个项目中
npm install 包名
或者yarn add 包名
- 使用方式
import { XButton } from "xz-test-button";function App() {return (<div className="App"><XButton>测试</XButton></div>);
}export default App;
- 使用中的问题:
- 样式没加载
- 使用问题:类型问题
6. 填坑
虽然包发布成功了,但是前面说过还有一些坑需要填,这些坑刚刚也看见了,都是在使用的时候出现的
- 样式问题
- 将包下载到另一个项目使用会发现组件结构是存在的就是没有样式,这是因为
vite
打包的时候虽然将样式打包到输出目录了,但是在js
文件中没有引用css
文件; - 解决方案:
- 可以手动将
style.css
引入到index.js
中(每次打包都需要引一次,比较麻烦,不推荐) - 通过
vite-plugin-libcss
插件自动引入(推荐),先下载依赖:
- 可以手动将
npm: npm install vite-plugin-libcss -Dor yarn: yarn add vite-plugin-libcss -D
改造vite.config.ts
文件
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'path'
import libCss from 'vite-plugin-libcss';// https://vitejs.dev/config/
export default defineConfig({plugins: [react(), libCss()],... 不变 ...
})
- 问题:模块““xxx””没有导出的成员“x”或者找不到“xxx”的类型声明文件
- 因为项目是
TypeScript
开发的所以我们需要模块导出,通过改造index.d.ts
文件来解决
import React, { ReactNode } from "react"export declare type XButtonType = {children: string | ReactNodeprimaryColor?: stringonClick?: () => void
}declare module 'xz-test-button' {export function XButton(props: XButtonType): JSX.Element
}
然后重新打包即可
7. 更新包
- 首先更新包版本
npm version patch
(因为我们是修复bug,所以我们只需更新修复版本号) - 再次执行发包命令
npm publish
- 最后在使用这个包的项目中重新下载一次这个包就不会出现类型问题和样式问题了
总结
通过上面一套流程走下来会发现其实发包很简单,也就是执行一些命令,修改一些配置就能完成;可能难点就是针对一些细节问题,比如发包404、403、401、组件样式问题、TS类型问题。能处理好这些细节就基本没什么问题了
还不会发包?30S教会你相关推荐
- 还在手动发包?手把手教你 Jenkins 自动化部署SpringBoot
大家好,我是一航! 程序员每天的工作,几乎都是围绕着开发.打包.发布.测试这些点循环往复,但这些过程中,有很大一部分重复性的苦力活,不仅消耗了我们大量的时间,但有不得不做:纯手工去集成.部署,既苦力, ...
- 30s教会你在Android模拟器上安装搜狗输入法
我们在使用Android Studio的过程中,肯定会用模拟器运行app,有时候app需要输入中文内容,这时候就需要中文输入法了,但是在API比较低的模拟器中,是没有中文输入法的,需要我们自己安装和配 ...
- 史上最可怜的科学家:出生先天不足,家道中落吃不上饭,追个星丢工作,拜师被冤枉,写书又被烧,最后还被拖工资活活拖死了......
全世界只有3.14 % 的人关注了 爆炸吧知识 今天,小天来向各位模友介绍一个痴迷偶像正面刚的小迷弟吧. 多病的贫家子,鲁莽的小迷弟 1571年,开普勒在德国维尔镇呱呱落地了. 作为一个善解人意的宝宝 ...
- 还在找游戏本推荐排行榜?这款游戏本才是你的菜!
相信不少消费者在选购游戏本前,都会寻找游戏本推荐排行榜进行一个参考与选择,而今天为大家带来的荣耀猎人游戏本V700,同样也是此榜单中的一员,当你了解了这款游戏本后,你将不再需要寻找榜单,因为它绝对是你 ...
- 简易 Python 脚本查询嵊泗船票
夏天来了,这颗躁动的心啊,想去嵊泗玩几天~ 现在上海去嵊泗要上微信公众号或者官网买票,工作日还好,但是周末了不太容易抢到票了,又不能没事就刷手机(这太没有程序员范儿了). 所以,看看能不能用 Pyth ...
- 关于2020考研信息收集
在职研究生学费 同等学力申硕 基本都在1.2-8万元之间, 专业硕士 参加课程学习需要缴纳的学费都在1.8-39万元之间 高级研修 一般都在0.58-30万元之间, 中外合办 需要缴纳的学费都在2.5 ...
- Android Studio模拟器如何设置中文输入法
很多Android项目的运行都需要用到中文输入法,在一年前的Android Studio需要导入输入法apk安装,现在新版的Android Studio免去了这个麻烦,下面就教大家如何设置谷歌拼音输入 ...
- 信科c语言实验程序修改题_豆瓣评分 9.3,史上最好的 C 语言著作,竟然翻车了.........
上周,在小编的各种努力下(省略一万字),Kindle 官方终于答应给我一个广告位了.虽然只是开机屏,但我还是笑出了猪叫,毕竟上一次有这待遇还是 2018 年时的<算法图解>.所以错过了上次 ...
- 豆瓣评分 9.3,史上最好的 C 语言著作,竟然翻车了......
上周,在小编的各种努力下(省略一万字),Kindle 官方终于答应给我一个广告位了.虽然只是开机屏,但我还是笑出了猪叫,毕竟上一次有这待遇还是 2018 年时的<算法图解>.所以错过了上次 ...
最新文章
- Git 创建两个“本地分支”协同工作
- <X86汇编语言:实模式到保护模式>四十四 协同式任务切换
- 51Nod 1007 正整数分组(01背包)
- apache 目录访问加密 简单
- HashMap的hash冲突解决方案
- Spring学习(一)初识Spring
- How does model reference pass from app view to master view
- 【线段树】蝴蝶与花(P6859)
- 转:C++中const、volatile、mutable的用法
- 【EasyNetQ】- 发送接收
- React Native组件(四)TextInput组件解析
- python处理出租车轨迹数据_1-出租车数据的基础处理,由gps生成OD(pandas).ipynb...
- C罗111球成国家队历史射手王,破纪录的动力来自签约曼联
- rtmp协议java实现_RTMP 协议的一个 Java 实现:Flazr
- Modbus从站读写数据
- WIFI驱动开发——WIFI支持WPA3连接
- c#通用后台管理系统
- 2022年Oracle学习计划
- java作业题exercise1
- EngineerCMS开发ONLYOFFICE文档协作的权限管理
热门文章
- bShare分享-分享到微信、微博、QQ
- 接口500什么原因_性价比最高的电脑音箱有哪些?20款50-500元电脑音箱推荐
- mysql建立班级表_MySql 复习及学生表,课程表,班级表的创建
- jQuery开发技术笔记
- 筑牢安全生产防线,工厂人员定位报警系统护航企业发展
- vs中遇见> 0x7BA4EF8C (ucrtbased.dll)处(位于 Project1.exe 中)引发的异常: 0xC0000005: 写入位置 0x00540000 时发生访问冲突。
- panda读取excel文件内容时出错,提示excel表格不能被指定
- Python 动物 , 人,狗,猫 面向对象关系 代码
- RIP v2 汇总
- java毕业设计师生教学评价系统源码+lw文档+mybatis+系统+mysql数据库+调试