Vue多组件仓库开发与发布详解


Posted in Javascript onFebruary 28, 2019

在开发组件时,我们可能会期望一类组件放在同一个代码仓库下,就像element那样,我们可以使用element提供的脚手架,也可以使用vue cli 3创建一个更‘新'的项目。

项目创建

通过vue cli 3创建项目,创建文件夹packages用于存放组件。

单个组件目录

在packages下就是每一个组件,每个组件和单独项目一样,会有package.json、README.md、src、dist等文件及目录。

如何演示/调试组件

在组件开发过称中,我们需要对组件进行展示,所以创建了examples文件夹,用于存放每个组件示例。

通过一个列表展示出所有的组件,点击选择当前开发的组件,进入对应的example。

路由的根就是一个导航列表,然后每个组件对应一个路由,通过一个配置文件的components.js来生成这个路由。

// 路由
import Navigation from "./Navigation";
import components from "./components";

let routes = components.map(component => ({
 path: `/${component.name}`,
 component: () => import(`../examples/${component.name}`)
}));

routes.unshift({
 path: "",
 component: Navigation
});

export default routes;

自动化脚本

创建/编译/发布

创建新的组件,需要修改components.js配置文件,在examples和packages下创建对应目录。

编译/发布组件,因为仓库下会有多个组件,如果一次发布多个,就需要进入每个文件夹下执行命令。

上面过程实现自动化,有很多种方式,比如可以通过npm run <script>,可以直接通过node命令等。这里我参考element,采用了Makefile。

创建script文件夹,其中包括创建脚本new.js和构建脚本build.js。

创建脚本

创建脚本主要就是目录的创建与文件的写入,其中可能需要注意的可能就是格式问题。

一种方式是在``之间,按照规范格式去完成写入内容,这样做比较麻烦,而且可能面临格式化要求修改问题。

另一种方式是在脚本中引入eslint,脚本中的eslint.CLIEngine可以根据配置文件(比如.eslintrc.js)格式化文件。需要注意的是需要比命令行中配置需要多添加fix: true配置, 如下

const CLIEngine = eslint.CLIEngine;
const cli = new CLIEngine({ ...require("../.eslintrc.js"), fix: true });

eslint在脚本中的使用方法,更具体的可以参考eslint文档中Node.js API部分。

// scripts/new.js部分
...

components.push({
 label: newName,
 name: newName
})

const updateConfig = function(path, components) {
 writeFile(path, `module.exports = ${JSON.stringify(components)}`).then(() => {
  console.log("完成components.js")
  // 格式化
  CLIEngine.outputFixes(cli.executeOnFiles([configPath]))
 })
}

const createPackages = function(componentName) {
 try {
  const dir = path.resolve(__dirname, `../packages/${componentName}/`)
  // 创建文件夹
  if (!fs.existsSync(dir)) {
   fs.mkdirSync(dir)
   console.log(`完成创建packages/${componentName}文件夹`)
  }
  // 写入README
  if (!fs.existsSync(`${dir}/README.md`)) {
   writeFile(
    `${dir}/README.md`,
    `## ${componentName}
 
 ### 使用说明
      `
   ).then(() => {
    console.log("完成创建README")
   })
  }
  // 写入package.json
  if (!fs.existsSync(`${dir}/package.json`)) {
   writeFile(
    `${dir}/package.json`,
    `{
 "name": "@hy/${componentName}",
 "version": "1.0.0",
 "description": "${componentName}",
 "main": "./dist/hy-${componentName}.umd.min.js",
 "keywords": [
  "${componentName}",
  "vue"
 ],
 "author": "",
 "license": "ISC"
}
    `
   ).then(() => {
    console.log("完成创建package.json")
   })
  }
  // 创建index.js
  if (!fs.existsSync(`${dir}/index.js`)) {
   writeFile(`${dir}/index.js`, `export {}`).then(() => {
    console.log("完成创建index.js")
    CLIEngine.outputFixes(cli.executeOnFiles([`${dir}/index.js`]))
   })
  }
 } catch (err) {
  console.error(err)
 }
}

const createExample = function(componentName) {
 try {
  const dir = path.resolve(__dirname, `../examples/${componentName}/`)
  // 创建文件夹
  if (!fs.existsSync(dir)) {
   fs.mkdirSync(dir)
   console.log(`完成创建examples/${componentName}文件夹`)
  }
  // 写入index.vue
  if (!fs.existsSync(`${dir}/index.vue`)) {
   writeFile(
    `${dir}/index.vue`,
    `<template>

</template>

<script>
import { } from '../../packages/${componentName}/index'

export default {
 components: {}
}

</script>
   `
   ).then(() => {
    console.log(`完成创建examples/${componentName}/index.vue文件`)
    // 格式化index.vue
    CLIEngine.outputFixes(cli.executeOnFiles([`${dir}/index.vue`]))
   })
  }
 } catch (err) {
  console.error(err)
 }
}

...

构建脚本

// build.js
...

async function build() {
 for (let i = 0, len = components.length; i < len; i++) {
  const name = components[i].name
  await buildService.run(
   "build",
   {
    _: ["build", `${root}/packages/${name}/src/index.js`],
    target: "lib",
    name: `hy-${name}`,
    dest: `${root}/packages/${name}/dist`,
    // 生成格式: umd格式会同时成功demo.html commonjs,umd,umd-min
    formats: "commonjs,umd-min"
    // clean: false
   },
   ["--target=all", `./packages/${name}/src/index.js`]
  )
 }
}

...

Lerna

lerna是一个多包仓库管理的工具,可以帮助创建、管理、发布多包仓库中的包。

关于lerna我也没有太深入得使用,只是用到了发布。首先在项目下执行init初始化了项目,在每次commit之后,可以执行publish。lerna会对应代码库打tag,并发布到npm仓库。

项目版本问题

0.0.1为不规范版本号,最小应该从1.0.0开始。npm publish无法发布,但是lerna publish可以发布。

导致结果安装为固定版本号,而不是以^开头的版本号范围。outdate可以检测到有更新,无法通过update升级。

组件开发

组件开发主要是在packages/<component name>/src目录下进行,在example/<component name>/目录下可以引入该组件src下的源文件,用一些数据来进行开发测试。组件开发和项目中的组件开发基本相同。

作为组件库中的组件,需要更多的考虑其通用性和易用性。不能为了通用而加入很多的属性,而使其失去易用性;同样也不能为了易用,而使其过于简单,使用范围过于局限。

对于每一个属性、每个抛出去的方法,都需要认真考虑其必要性。

唯一不同的地方可能需要注意的是导出的方式。

一种是直接导出组件,这种形式在使用时需要引入,并且在components中声明,也就是局部注册。

另一种是添加install方法后导出。这种形式需要调用vue.use方法,相当于全局注册。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
在IE下获取object(ActiveX)的Param的代码
Sep 15 Javascript
Cookie 小记
Apr 01 Javascript
JS扩展方法实例分析
Apr 15 Javascript
Jquery 全选反选实例代码
Nov 19 Javascript
Jquery Ajax Error 调试错误的技巧
Nov 20 Javascript
js实现C#的StringBuilder效果完整实例
Dec 22 Javascript
javascript瀑布流式图片懒加载实例解析与优化
Feb 23 Javascript
javascript字符串对象常用api函数小结(连接,替换,分割,转换等)
Sep 20 Javascript
微信小程序 实现拖拽事件监听实例详解
Nov 16 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
Mar 15 Javascript
jQuery基于cookie实现换肤功能实例
Oct 14 jQuery
详解vue-cli 3.0 build包太大导致首屏过长的解决方案
Nov 10 Javascript
JavaScript数组去重的方法总结【12种方法,号称史上最全】
Feb 28 #Javascript
vue-cli3+typescript初体验小结
Feb 28 #Javascript
详解超简单的react服务器渲染(ssr)入坑指南
Feb 28 #Javascript
JS浅拷贝和深拷贝原理与实现方法分析
Feb 28 #Javascript
微信小程序搜索功能(附:小程序前端+PHP后端)
Feb 28 #Javascript
详解写好JS条件语句的5条守则
Feb 28 #Javascript
JS判断两个数组或对象是否相同的方法示例
Feb 28 #Javascript
You might like
PHP乱码问题,UTF-8乱码常见问题小结
2012/04/09 PHP
php设计模式之简单工厂模式详解
2014/09/04 PHP
php多线程实现方法及用法实例详解
2015/10/26 PHP
php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法
2016/07/12 PHP
Laravel中unique和exists验证规则的优化详解
2018/01/28 PHP
tp5(thinkPHP5)框架连接数据库的方法示例
2018/12/24 PHP
HTML IMG标签 onload 内存溢出导致浏览器CPU占用过高
2021/03/09 Javascript
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
2007/05/08 Javascript
每天一篇javascript学习小结(基础知识)
2015/11/10 Javascript
AngularJS入门教程之服务(Service)
2016/07/27 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
2016/08/02 Javascript
JS 在数组指定位置插入/删除数据的方法
2017/01/12 Javascript
Vue全家桶实践项目总结(推荐)
2017/11/04 Javascript
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
2018/05/07 Javascript
Vue.js 实现微信公众号菜单编辑器功能(二)
2018/05/08 Javascript
JavaScript数组去重的几种方法
2019/04/07 Javascript
vue调用本地摄像头实现拍照功能
2020/08/14 Javascript
[04:22]DOTA2上海特级锦标赛主赛事第四日TOP10
2016/03/06 DOTA
Python实现两个list对应元素相减操作示例
2017/06/09 Python
详解Python requests 超时和重试的方法
2018/12/18 Python
python实现屏保程序(适用于背单词)
2019/07/30 Python
Python通过TensorFLow进行线性模型训练原理与实现方法详解
2020/01/15 Python
VSCode配合pipenv搞定虚拟环境的实现方法
2020/05/17 Python
Python实现播放和录制声音的功能
2020/08/12 Python
css3中transition属性详解
2014/09/02 HTML / CSS
Parts Express:音频、视频和扬声器的第一来源
2017/04/25 全球购物
英国领先的葡萄酒专家:Majestic Wine
2017/05/30 全球购物
会计电算化专业毕业生求职信范文
2013/12/10 职场文书
客户服务经理岗位职责
2014/01/29 职场文书
会计学自我鉴定
2014/02/06 职场文书
单位租房协议范本
2014/12/03 职场文书
2015年法务工作总结范文
2015/05/23 职场文书
怎样写家长意见
2015/06/04 职场文书
2016年员工政治思想表现评语
2015/12/02 职场文书
将图片保存到mysql数据库并展示在前端页面的实现代码
2021/05/02 MySQL
pandas中关于apply+lambda的应用
2022/02/28 Python