Vue组件发布到npm总结与展望~

这是我参与更文挑战的第3天,活动详情查看:更文挑战

昨天发布了自己第一个认认真真写的 Vue 组件,有兴趣的可以看下:来动手打造一款自己的大图预览组件~,昨天已经把组件的基本功能(包括放大,缩写,旋转,还原)完成了,今天又加上了下载,虽然下载好像没什么用,右键另存为就可以了,但下载写着写着发现还是不少知识点的,比如要对不同的src地址(httpURL,base64,本地地址)来进行下载文件,一会贴上代码,大家可以看一下~ 然后就是对项目进行一点配置,上传到npm,供其他项目或者有需求的朋友使用(不管你们用不用,反正我自己感觉我的组件挺好用,哈哈哈~)。

1. 下载功能实现

// utils/index.js

// blob下载
export async function downFile(url, fileName = "download") {
  try {
    let blob = null;
    // 本地图片 网络图片 base64图片处理
    if (url.startsWith("http")) {
      blob = await getBlob(url);
    } else if (url.startsWith("data:image")) {
      let mime = getBase64Type(url);
      blob = mime ? dataURLtoBlob(url, mime) : dataURLtoBlob(url);
    } else if (url.startsWith("/")) {
      blob = await getBlob(window.origin + url);
    } else {
      return;
    }

    let a = document.createElement("a");
    a.download = fileName;
    a.href = window.URL.createObjectURL(blob);
    a.click();
  } catch (error) {
    console.log(error);
  }
}
// 将base64转为blob
export function dataURLtoBlob(base64, mimeType = "image/png") {
  let bytes = window.atob(base64.split(",")[1]);
  let ab = new ArrayBuffer(bytes.length);
  let ia = new Uint8Array(ab);
  for (let i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i);
  }
  return new Blob([ab], { type: mimeType });
}
// 将网络url转为blob
export function getBlob(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = () => {
      if (xhr.status == 200) {
        resolve(xhr.response);
      } else {
        reject();
      }
    };
    xhr.send();
  });
}
// 获取base64文件类型
export function getBase64Type(base64) {
  let index0 = base64.indexOf(":");
  let index1 = base64.indexOf(";");
  let mime = "";
  if (index0 !== -1 && index1 !== -1) {
    mime = base64.slice(index0 + 1, index1);
  }
  return mime;
}

复制代码

2. 组件发布

组件注册工具函数

// 引入组件
import imgLargeMode from "@/components/img-large-mode";
// install方法,以供Vue.use()注册使用
const install = (Vue, option) => {
  // 创建构造器,生成一个Vue实例
  const componentInstance = Vue.extend(imgLargeMode);
  // 定义实例化对象
  let currentComponent = null;
  // 对象实例化,将组件挂载到body下
  const initInstance = () => {
    currentComponent = new componentInstance();
    let componentEL = currentComponent.$mount().$el;
    document.body.appendChild(componentEL);
  };
  // 定义用户使用的方法,挂在到Vue
  Vue.prototype.$_openLargeMode = {
    show(opt) {
      initInstance();
      return currentComponent.show(opt);
    }
  };
};
if (typeof window !== "undefined" && window.Vue) {
  install(window.Vue);
}
export default {
  install,
  imgLargeMode
};

复制代码

package.json

{
  "name": "img-large-mode",
  "version": "0.1.0",
  "main": "./dist/img-large-mode.umd.min.js",
  "author": "Tmier",
  "description": "基于Vue的大图模式组件",
  "keywords": [
    "img-large-mode",
    "img-large",
    "large-mode"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/itmier/img-large-mode"
  },
  "license": "MIT",
  "files": [
    "dist"
  ],
  "private": false,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "package": "vue-cli-service build --target lib --name img-large-mode --dest dist ./src/components/index.js",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
   ...
  },
  "devDependencies": {
   ...
  }
}

复制代码

组件发布的package.json具体说明:

name: 组件名称,包名,必须有且不能重复

version: 版本号,发布时必填

main: 入口函数,启动项目的文件

如果包由用户安装,则用户执行require('foo-lib')时,这时require将返回main字段所列出的文件的module.exports属性

author: 作者

description: 描述

keywords: 关键词

license: 许可证

repository: 记录代码所在的资源库

private: 默认true,发布包时要设置为false,否则npm会拒绝发布它

files: 是一个文件数组,描述了将软件包作为依赖项安装时要包括的条目。如果在数组里面声明了一个文件夹,那么也会包含文件夹中的文件。某些特殊文件和目录也会被包括或者排除在外,无论它们是否存在于文件数组中。

以下文件无论是否设置,总是包含:
*   `package.json`
*   `README`
*   `CHANGES`/`CHANGELOG`/`HISTORY`
*   `LICENSE`/`LICENCE`
*   `NOTICE`
*   The file in the “main” field

以下文件总是被忽略:
*   `.git`
*   `CVS`
*   `.svn`
*   `.hg`
*   `.lock-wscript`
*   `.wafpickle-N`
*   `.*.swp`
*   `.DS_Store`
*   `._*`
*   `npm-debug.log`
*   `.npmrc`
*   `node_modules`
*   `config.gypi`
*   `*.orig`
*   `package-lock.json`(use shrinkwrap instead)
复制代码

scripts中新添加一条命令,我觉得得记录一下:

"package": "vue-cli-service build --target lib --name img-large-mode --dest dist ./src/components/index.js"
复制代码
用法:vue-cli-service build [options] [entry|pattern]

选项:

  --mode        指定环境模式 (默认值:production)
  --dest        指定输出目录 (默认值:dist)
  --modern      面向现代浏览器带自动回退地构建应用
  --target      app | lib | wc | wc-async (默认值:app)
  --name        库或 Web Components 模式下的名字 (默认值:package.json 中的 "name" 字段或入口文件名)
  --no-clean    在构建项目之前不清除目标目录
  --report      生成 report.html 以帮助分析包内容
  --report-json 生成 report.json 以帮助分析包内容
  --watch       监听文件变化
复制代码

索引上面我加的那条命令可以解释为: 构建命令 构建目标 库 名称 img-large-mode 输出目录 dist 函数入口

PS: 这个入口可以是一个 .js 或一个 .vue 文件。如果没有指定入口,则会使用 src/App.vue

配置完成,接下来就是npm发布~

npm发布包

npm login //输入用户名密码登录npm,没有的话去注册
npm run package(自己定义的scripts打包命令)
npm publish
复制代码

ok,发布成功,大功告成~

还差一点,写文章的时候在家里的电脑上安装了一下自己发布的包,然后发现会带着vue,vuex,vue-router,是不是我有地方没有配置好?我安装了一下element-ui,发现它没有安装vue相关库,有没有大佬指点一下~

3. 展望

完善组件功能,目前能想到的就下面几个,有看到的可以补充一下:

  • 支持数组List,图片可以实现上一张下一张查看
  • ant design 一样的modal 动画效果,为图片遮罩添加动画

参考文章: segmentfault.com/a/119000002…

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享