上一节我们书写了 button
和 icon
组件,单元测试和文档也都完成了,接下来我们把写好的库打包发布到 npm
上。之后我们建个小 vue3
的项目,安装我们自己的包。
config 文件配置
- 获取
packages
下的index.js
文件作为入口文件,每个组件单独的入口
function resolve(dir) {
return path.resolve(__dirname, dir)
}
function getEntries(path) {
// 整理需要按需加载的文件,dir为各组件所在的共同目录
let files = fs.readdirSync(resolve(path))
const entries = files.reduce((ret, item) => {
if (item == 'utils') return ret
const itemPath = join(path, item)
const isDir = fs.statSync(itemPath).isDirectory()
if (isDir) {
// 路径拼接,得到组件所在地址
ret[item] = resolve(join(itemPath, 'index.js'))
} else {
const [name] = item.split('.')
ret[name] = resolve(`${itemPath}`)
}
return ret
}, {})
return entries
}
- 配置打包项
const buildConfig = {
// 输出的目录名
outputDir: 'lib',
// 关闭 sourcemap
productionSourceMap: false,
configureWebpack: {
entry: {
// 多入口文件, packages 目录下
...getEntries('packages')
},
output: {
// 输出文件以 d- 开头
filename: 'd-[name]/index.js',
libraryTarget: 'commonjs2'
},
resolve: {
alias: {
packages: resolve('packages')
}
}
},
css: {
sourceMap: true,
extract: {
// 打包输出的样式文件
filename: 'style/d-[name].css' //在lib文件夹中建立style文件夹中,生成对应的css文件。
}
},
// webpack 解析
chainWebpack: config => {
config.module
.rule('js')
.include.add('/packages')
.end()
.use('babel')
.loader('babel-loader')
.tap(options => {
return options
})
// 删除不必要的配置
config.optimization.delete('splitChunks')
config.plugins.delete('copy')
config.plugins.delete('html')
config.plugins.delete('preload')
config.plugins.delete('prefetch')
config.plugins.delete('hmr')
config.entryPoints.delete('app')
// 字体文件配置
config.module
.rule('fonts')
.use('url-loader')
.tap(option => {
option.fallback.options.name = 'static/fonts/[name].[ext]'
return option
})
}
}
打包命令
我们可以直接执行 npm run build
,这样会把我们每个组件打包出来,但我们还要一个总包,包括所有组件和样式的文件,我们我们添加新的命令,打包成库的配置
"scripts": {
...
"lib": "vue-cli-service build --target lib packages/index.js && vue-cli-service build --no-clean"
}
--no-clean 表示打包时不删除现有的 lib 文件,为了后面的按需打包
执行 npm run lib
,我们可以看到执行完全库打包后继续执行组件的单独打包
配置 package.json
{
"name": "day-ui", // 包名
"version": "0.0.1", // 包的版本,每次发布需要修改
"description": "A Personal Learning UI library For Vue",// 描述
"main": "lib/day-ui.umd.min.js",// 包的入口文件
"author": { // 作者信息
"name": "",
"email": ""
},
// 上传的文件
"files": [
"lib",
"packages",
"package.json",
"typings",
"README.md"
],
// ts 项目类型文件
"typings": "typings/index.d.ts",
"style": "lib/day-ui.css",
"repository": {
"url": ""// 仓库地址
},
"keywords": [
"UI",
"Vue",
"UI-Library"
]
}
如果有需要不上传的文件,也可以创建 .npmignore
文件,忽略不发布的文件
发布
- 上传到
npm
,我们首先需要注册个账号,直接到官网即可。 - 第一次的话有些配置
npm login
,按提示输入信息 npm publish
发布即可
大家注册完之后一定要用官网邮箱验证,否则发布的时候会报异常
使用
yarn add day-ui -S
,我们在 main.ts
中引入
全部引入
在页面中使用:
<DButton icon="search">button</DButton>
按需引入
安装插件 npm i babel-plugin-import -D
,
配置 babel.config.js
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'],
plugins: [
[
"import",
{
libraryName: 'day-ui',
// 默认 DButton -> d-button
customStyleName: (name) => {
return `day-ui/lib/style/${name}.css`;
},
},
],
]
}
我们在页面中引入 import {DButton, DIcon} from "day-ui"
,插件会帮我们默认引入组件和样式
可能在项目中使用是会遇到如下的问题,这是由于有两个 Vue
实例导致的,我们的组件库中把 Vue
安装在开发依赖中,同时 packages.json
中配置 peerDependencies
, vue.config.js
中配置 externals
....
"peerDependencies": {
"vue": "^3.0.7"
},
...
externals: [
{
vue: {
root: 'Vue',
commonjs: 'vue',
commonjs2: 'vue'
}
}
]
组件库搭建的整体流程到这里就结束了,后面还会写每个组件分享,学习 element-plus
内部实现,更深入学习了解 vue3
的使用。
如果文章对您有帮助的话欢迎 github
支持:
如果文章对你有帮助欢迎转发,有什么意见欢迎留言。