个人UI组件库如何适配各种模块规范以及支持按需加载组件和发布包到包管理市场公网或者私服-1
从指令上去看具体实现逻辑
-
yarn initLibsJs 用指令把所有组件都让入一个js文件对外暴露,作为umd规范的入口文件
-
yarn build:umdjs 用webpack输出上面文件,作为umd规范的
-
yarn initEsmsJs 用指令把所有组件都让入一个js文件对外暴露,作为esm规范的入口文件
-
yarn build:es 用gulp输出上面文件和单个组件,作为esm规范的
-
yarn commit 提交本地修改的规范指令
-
update:version 发布各种类型版本以及打tag
-
src/example/01.vue是使用自己当前组件库的demo
-
npm publish 发布包到开源远端
一些关于包的知识点
文件目录结构
- 文件夹目录注释(使用mddir插件生成)
|-- .browserslistrc //适配哪些浏览器
|-- .editorconfig //代码风格配置
|-- .eslintrc.js
|-- .gitignore
|-- babel.config.js
|-- CHANGELOG.md
|-- lcc-ui.xmind //一些逻辑梳理
|-- package.json
|-- README.md
|-- yarn-error.log
|-- yarn.lock
|-- 如何开发一个组件.md
|-- build
| |-- gulpfile.js //用gulp生成es规范的组件库输出
| |-- bin
| | |-- es-entry.js
| | |-- libs-entry.js
| | |-- version.js
| |-- cli
| | |-- run.js //各种命令的分配文件
| |-- gulp
| |-- webpack
| |-- webpack.example.js
| |-- webpack.libs.js //webpack打包出umd规范的组件库配置
|-- dist
| |-- favicon.ico
| |-- index.html
| |-- main.js
| |-- main.js.LICENSE.txt
|-- es //es规范输出文件
| |-- index.js
| |-- checkbox
| | |-- index.js
| |-- input
| | |-- index.js
| |-- select
| |-- index.js
|-- lib //umd规范输出文件
| |-- lccx-ui.common.js
|-- packages //组件库都在这个目录里开发
| |-- index.js
| |-- checkbox
| | |-- index.js
| | |-- index.vue
| |-- input
| | |-- index.js
| | |-- index.vue
| |-- select
| |-- index.js
| |-- index.vue
|-- public
| |-- favicon.ico
| |-- index.html
| |-- images
| |-- elmdbh.png
| |-- elmdbh2.png
|-- src
|-- App.vue
|-- index.js //umd规范的组件编译入口
|-- main.js //本地查看的编译入口
|-- assets
| |-- logo.png
|-- components
| |-- HelloWorld.vue
|-- example
|-- 01.vue
开发组件过程
1.基本项目生成
基于vue生成一个基本项目lcc-ui
vue create lcc-ui
项目根目录下新增packages文件夹,作为组件库开发目录
mkdir packages
在packages里新建checkbox组件文件
|-- packages //组件库都在这个目录里开发
| |-- checkbox //组件目录,也是自动指令生成组件名的文件
| | |-- index.js //组件对外暴露文件
| | |-- index.vue //组件内容
在checkbox/index.js文件里处理vue组件的对外暴露和增加install方法使该组件可以在使用vue.use(Checkbox)的时候成为一个全局组件
import index from "./index.vue"
index.install = function(Vue){
Vue.component(index.name,index)
}
export default index;
2.用脚本自动根据组件目录生成一个暴露所有组件的对外文件(umd规范的)
- build/bin/libs-entry.js
/**
* 000.该指令作用:动态读取src/packages下面所有的组件,写入到index.js这个文件作为统一输出所有组件的入口
* 1.用glob读取src/packages下面的文件夹,获取文件夹名就是组件吗,获取文件下面的index.js是每个组件的入口文件
* 2.用json-templater/string来拼接输出所有组件的index.js文件里面的内容
* 3.用fs.writeFileSync来把拼接的内容写入index.js文件里
*/
const path = require("path");//拼接路径
const fs = require("fs");//文件写入,读取
const glob = require("glob");//文件夹读取输出
const uppercamelcase = require("uppercamelcase");//大小写转换
const render = require('json-templater/string');//字符串拼接文件内容可以带参数
var endOfLine = require('os').EOL;//不同该系统换行符
const componentsDir = path.join(__dirname,"../../packages/*/*.js");//需要读取的UI组件库的目录下哪些文件
const allComponentsFiles = glob.sync(componentsDir,"");//读取的UI组件库地址
// 文件里面引入组件的模板
var IMPORT_TEMPLATE = 'import {{name}} from \'../packages/{{package}}/index.js\';';
// index.js文件的输出模板,里面动态引入和导出所有组件
var MAIN_TEMPLATE = `/* Automatically generated by './build/bin/libs-entry.js' */
{{include}}
const components = [
{{install}}
];
const install = function(Vue, opts = {}) {
components.forEach(component => {
Vue.component(component.name, component);
});
};
/* istanbul ignore if */
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
export default {
version: '{{version}}',
install,
{{list}}
};
`;
const includeTemplate = []; //动态引入组件的集合 例如 import a from "a"
const includeComponents = []; //动态引入组件的组件数组集合例如 [a,b]
allComponentsFiles.forEach(c=>{
const package = path.basename(path.dirname(c));
const name = uppercamelcase(package);
includeComponents.push(name);
includeTemplate.push(render(IMPORT_TEMPLATE,{name,package}))
})
// console.log(includeTemplate)
const indexTemplate = render(MAIN_TEMPLATE,{
include:includeTemplate.join(endOfLine),
list:includeComponents.join(","+endOfLine),
version: process.env.VERSION || require('../../package.json').version,
install:includeComponents.join(","+endOfLine)})
// console.log(indexTemplate)
fs.writeFileSync(path.join(__dirname,"../../src/index.js"),indexTemplate);
增加package.json里面脚本
"initLibsJs": "node build/bin/libs-entry.js",
运行 yarn initLibsJs
生成对外暴露组件的入口文件src/index.js,自动生成内容如下
/* Automatically generated by './build/bin/libs-entry.js' */
import Checkbox from '../packages/checkbox/index.js'
import Input from '../packages/input/index.js'
import Select from '../packages/select/index.js'
const components = [
Checkbox,
Input,
Select
]
const install = function (Vue, opts = {}) {
components.forEach(component => {
Vue.component(component.name, component)
})
}
/* istanbul ignore if */
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
version: '0.3.3',
install,
Checkbox,
Input,
Select
}
package.json增加script指令
"build:umdjs": "webpack --config build/webpack/webpack.libs.js",
来打包混淆代码输出umd规范的打包文件 lib/lcc-ui.common.js
//build/webpack/webpack.libs.js
//webpack里面配置的输出文件内容
output: {
path: path.resolve(process.cwd(), './lib'),
publicPath: '/dist/',
filename: 'lccx-ui.common.js',
chunkFilename: '[name].js',
library: {
name: 'LCCXUI',
type: 'umd', // commonjs2/amd/umd
export: 'default' // 指定哪一个导出应该被暴露为一个库
}
},
3.用脚本自动根据组件目录生成一个暴露所有组件的对外文件(es规范的)
步骤和上面基本相同,除了打包方式是用的gulp不是webpack
指令顺序:
yarn initEsmsJs
yarn build:es
4.发布包
npm先登录账号后用npm publish发布