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 相关文章推荐
点击文章内容处弹出页面代码
Oct 01 Javascript
JS Range HTML文档/文字内容选中、库及应用介绍
May 12 Javascript
DIV+CSS+JS不间断横向滚动实现代码
Mar 19 Javascript
Javascript和HTML5利用canvas构建Web五子棋游戏实现算法
Jul 17 Javascript
PHP结合jQuery实现的评论顶、踩功能
Jul 22 Javascript
实例解析jQuery中proxy()函数的用法
May 24 Javascript
jQuery EasyUI Tab 选项卡问题小结
Aug 16 Javascript
JS中setTimeout和setInterval的最大延时值详解
Feb 13 Javascript
用js屏蔽被http劫持的浮动广告实现方法
Aug 10 Javascript
初探Vue3.0 中的一大亮点Proxy的使用
Dec 06 Javascript
vue eslint简要配置教程详解
Jul 26 Javascript
Vue中通过Vue.extend动态创建实例的方法
Aug 13 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
怎样在UNIX系统下安装MySQL
2006/10/09 PHP
PHP中::、-&amp;gt;、self、$this几种操作符的区别介绍
2013/04/24 PHP
php过滤html标记属性类用法实例
2014/09/23 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
2016/03/25 PHP
PHP实现生成数据字典功能示例
2018/05/24 PHP
Laravel5.7 Eloquent ORM快速入门详解
2019/04/12 PHP
用JavaScript对JSON进行模式匹配(Part 1-设计)
2010/07/17 Javascript
js中widow.open()方法使用详解
2013/07/30 Javascript
js计算两个时间之间天数差的实例代码
2013/11/19 Javascript
javascript 表格内容排序 简单操作示例代码
2014/01/03 Javascript
JavaScript基础教程之alert弹出提示框实例
2014/10/16 Javascript
jquery调取json数据实现省市级联的方法
2015/01/29 Javascript
jquery+php随机生成红包金额数量代码分享
2015/08/27 Javascript
更靠谱的H5横竖屏检测方法(js代码)
2016/09/13 Javascript
详解在vue-cli项目中安装node-sass
2017/06/21 Javascript
详解AngularJS1.x学习directive 中‘&amp; ’‘=’ ‘@’符号的区别使用
2017/08/23 Javascript
微信小程序-getUserInfo回调的实例详解
2017/10/27 Javascript
js 公式编辑器 - 自定义匹配规则 - 带提示下拉框 - 动态获取光标像素坐标
2018/01/04 Javascript
node.js中fs文件系统目录操作与文件信息操作
2018/02/24 Javascript
解决Vue.js 2.0 有时双向绑定img src属性失败的问题
2018/03/14 Javascript
JS中的两种数据类型及实现引用类型的深拷贝的方法
2018/08/12 Javascript
layer父页获取弹出层输入框里面的值方法
2019/09/02 Javascript
vue中keep-alive、activated的探讨和使用详解
2020/07/26 Javascript
Python函数式编程指南(一):函数式编程概述
2015/06/24 Python
python实现unicode转中文及转换默认编码的方法
2017/04/29 Python
浅谈tensorflow中几个随机函数的用法
2018/07/27 Python
python读取txt文件中特定位置字符的方法
2018/12/24 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
python 等差数列末项计算方式
2020/05/03 Python
Python和Bash结合在一起的方法
2020/11/13 Python
CSS3实现闪烁动画效果的方法
2015/02/09 HTML / CSS
杭州龙健科技笔试题.net部分笔试题
2016/01/24 面试题
岗位竞聘书范文
2014/03/31 职场文书
学习方法演讲稿
2014/05/10 职场文书
大学生国家助学金感谢信
2015/01/23 职场文书
转正申请报告格式
2015/05/15 职场文书