前置知识
快速原型开发
- VueCli 中提供了一个插件可以进行原型快速开发(能单独运行某个组件)
- 需要先额外安装一个全局的扩展:
npm install -g @vue/cli-service-global - 使用
vue serve快速查看组件的运行效果
vue serve如果不指定参数默认会在当前目录下找以下入口文件:main.js、 index.js、 App.vue、 app.vue
- 可以指定要加载的组件
vue serve ./src/login.vue
Multirepo(Multiple Repository)
每一个包对应一个项目
Monorepo策略
Monorepo 是一种将多个项目代码存储在一个仓库里的软件开发策略。(一个项目仓库中管理多个模块/包)
由于介绍两种策略的文章很多,这里只简单介绍一下优势,劣势就不过多介绍了
优势:
-
灵活:每个repo可以灵活选择开发工具和环境配置等
-
安全:自然的权限控制,发布上线对其他项目无影响
storybook
- 可视化的组件展示平台
- 在隔离的开发环境中,以交互式的方式展示组件
- 独立开发组件
- 支持的框架:⬇️
React、React Native、Vue、Angular、Ember、HTML、Svelte、Mithril、Riot
storybook 安装
npx -p @storybook/cli sb init --type vue
npm i vue
npm i vue-loader vue-template-compiler --dev
storybook 配置
在
.sotrybook文件中的main.js中配置匹配路径
module.exports = {
"stories": [
"../stories/**/*.stories.mdx",
"../stories/**/*.stories.@(js|jsx|ts|tsx)",
+ "../packages/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials"
],
"framework": "@storybook/vue"
}
使用storybook搭建组件库文档
yarn工作区的使用
在项目根目录的
package.json文件中设置如下代码来开启工作区。
"private": true,
"workspaces": [
"./packages/*"
]
其次给工作区根目录安装开发依赖
yarn add lodash@4 -D -W
给指定工作区安装依赖
yarn workspace j-button add lodash@3
给所有工作区安装依赖
yarn install
Lerna
Lerna是一种工具,针对 使用 git 和 npm 管理多软件包代码仓库的工作流程进行优化。官网传
送门。用于管理具有多个包的 JavaScript 项目,它可以一键把代码提交到git和npm仓库。
项目初始化
首先使用 npm 将 Lerna 安装到全局环境中:
推荐使用 Lerna 2.x 版本。
npm install --global lerna
接下来,我们将创建一个新的 git 代码仓库:
git init lerna-repo && cd lerna-repo
现在,我们将上述仓库转变为一个 Lerna 仓库:
lerna init && npm i
你的代码仓库目前应该是如下结构:
lerna-repo/
packages/
package.json
lerna.json
还有加入 Babel 插件(给代码降级,提高兼容性)
npm i babel-core@bridge -D
常用指令
-
lerna init => 初始化
-
lerna bootstrap => 在当前 Lerna 仓库中执行引导流程(bootstrap)。安装所有 依赖项并链接任何交叉依赖。
-
lerna import => 将本地路径 中的软件包导入(import) packages/ 中并提交 commit。
-
lerna publish => 将本地路径 中的软件包导入(import) packages/ 中并提交 commit。
-
lerna changed => 检查自上次发布以来哪些软件包被修改过。
-
lerna diff => 列出所有或某个软件包自上次发布以来的修改情况。
-
lerna run [script] => 在每一个包含 [script] 脚本的软件包中运行此 npm 脚本。
-
lerna ls => 列出当前 Lerna 仓库中的所有公共软件包(public packages)。
-
lerna add => 安装依赖:
lerna add 依赖文件 安装地址 -
lerna link => 链接互相引用的库
关于打包
相比webpack来说,打包组件库或者框架Rollup更方便一些。因为webpack需要自己配置Tree-shaking,即使配置了Tree-shaking,打包出来的结果也要比Rollup更加臃肿,而Rollup默认就支持Tree-shaking。
安装依赖:
yarn add rollup rollup-plugin-terser rollup-plugin-vue@5.1.9 vue-template-compiler -D -W
配置文件rollup.config.js:
import { terser } from 'rollup-plugin-terser'
import vue from 'rollup-plugin-vue'
module.exports = [
{
input: 'index.js',
output: [
{
file: 'dist/index.js',
format: 'es'
}
],
plugins: [
vue({
// Dynamically inject css as a <style> tag
css: true,
// Explicitly convert template to render function
compileTemplate: true
}),
terser()
]
}
]
之后在package.json中添加scripts
注意: 此时的package.json并不是根目录下的,而是每个组件自己的package.json
"build": "rollup -c"
运行yarn workspace j-button run build就会在j-button下生成打包之后的文件。这个命令的意思是使用yarn运行名为j-button的工作区下的build命令,即刚在j-button文件夹下的package.json中添加的build命令。
但是这一单独的打包一个组件也太繁琐了些,使用yarn的一些插件可以实现将所有的组件一起打包。
yarn add @rollup/plugin-json rollup-plugin-postcss @rollup/plugin-node-resolve -D -W
其中@rollup/plugin-json可以让rollup将json文件作为模块加载,@rollup/plugin-node-resolve可以将依赖的第三方包打包进来。
之后在项目根目录下创建rollup的配置文件rollup.config.js文件
import fs from 'fs'
import path from 'path'
import json from '@rollup/plugin-json'
import vue from 'rollup-plugin-vue'
import postcss from 'rollup-plugin-postcss'
import { terser } from 'rollup-plugin-terser'
import { nodeResolve } from '@rollup/plugin-node-resolve'
const isDev = process.env.NODE_ENV !== 'production'
// 公共插件配置
const plugins = [
vue({
// Dynamically inject css as a <style> tag
css: true,
// Explicitly convert template to render function
compileTemplate: true
}),
json(),
nodeResolve(),
postcss({
// 把 css 插入到 style 中
// inject: true,
// 把 css 放到和js同一目录
extract: true
})
]
// 如果不是开发环境,开启压缩
isDev || plugins.push(terser())
// packages 文件夹路径
const root = path.resolve(__dirname, 'packages')
module.exports = fs.readdirSync(root)
// 过滤,只保留文件夹
.filter(item => fs.statSync(path.resolve(root, item)).isDirectory())
// 为每一个文件夹创建对应的配置
.map(item => {
const pkg = require(path.resolve(root, item, 'package.json'))
return {
input: path.resolve(root, item, 'index.js'),
output: [
{
exports: 'auto',
file: path.resolve(root, item, pkg.main),
format: 'cjs'
},
{
exports: 'auto',
file: path.join(root, item, pkg.module),
format: 'es'
},
],
plugins: plugins
}
})
然后在根目录的package.json文件中配置脚本
"build": "rollup -c"
之后在每个组件对应的package.json中配置:
"main": "dist/cjs/index.js",
"module": "dist/es/index.js",
main是组件打包的出口,也是使用时的入口,而module则是存放依赖的第三方包的位置。
配置完成之后在根目录下运行yarn build命令,就会自动打包所有packages下的组件。
关于清理
对node_modules的删除可以使用lerna原本的命令lerna clean,而清理dist文件夹则需要使用第三方库来实现,此处使用rimraf:
yarn add rimraf -D -W
之后给每个组件的package.json配置一个命令:
"del": "rimraf dist"
之后运行yarn workspaces run del即可运行所有包下的del命令,把dist目录删除掉,然而每次新建一个组件都要创建相同的文件是不可取的。
Lerna发布
组件库开发完毕,要将其提交到github或者npm上,这个时候可以使用Lerna,可以方便将所有包统一发布。
Lerna是一个优化使用git和npm管理夺宝仓库的工作流工具,用于管理具有多个包的JavaScript项目,它可以一键把代码提交到git和npm仓库。
全局安装Lerna之后,使用lerna init来进行初始化lerna的配置。如果当前项目没有使用git进行管理的话,则会自动创建.git文件夹,当然,如果项目根目录下没有packages文件夹的话,也会自动创建出来。
关于发布,使用yarn lerna命令会自动把packages文件夹下的所有组件都发布到npm上。此时要注意可能组件名字会与当前已有的包重复,此时会提示相应信息,只需要改组件名字就好。还要注意此时的yarn和npm的源都要设置成初始的源,不要是淘宝的源,否则会报错。