发布自己的npm超详细步骤

  1. 前沿:
    从去年毕业,vue掌握的还算熟练应用了,做过的vue项目也有十几个了吧,每次做项目的时候,有些组件老是使用,拷贝来拷贝去的使用。我就想把这些组件封装到一起,以后做项目可以直接使用。一开始我不知道封装,在网上找资料学习,大部分的帖子都没有把封装包的方式和发包方式讲的详细,今天我特意自我总结分享发布自己的npm的步骤,让每个人都可以封装自己的包,当然我的方式只是封装包一种方式,至少可以封装正常npm下载使用(大佬有好的方式,勿喷!)
    本人发布的简单包

  2. 创建项目
    主要是基于使用cli3初始化一个项目工程:
    全局安装vue-cli:

    npm install -g @vue/cli

    创建一个vue项目:
    vue create llgtfoo-components-boxs
    注:这部分我就不详细说了,相信大家应该都会

  3. 在项目中添加组件库文件夹:
    在根目录下新建一个plugins文件夹,用来放组件,项目文件结构为:
    (我的是跟src平级 创建plugins组件文件夹)在这里插入图片描述

  4. 添加配置文件
    项目根目录下面添加vue.config.js文件,写入以下内容:
    (主要是配置webpack的打包)

const path = require('path')
module.exports = {
  // 修改 pages 入口
  pages: {
    index: {
      entry: 'src/main.js', // 入口
      template: 'public/index.html', // 模板
      filename: 'index.html' // 输出文件
    }
  },
  // 扩展 webpack 配置
  chainWebpack: config => {
    // @ 默认指向 src 目录
    // 新增一个 ~ 指向 plugins
    config.resolve.alias
      .set('~', path.resolve('plugins'))

    // 把 plugins 加入编译,因为新增的文件默认是不被 webpack 处理的
    config.module
      .rule('js')
      .include.add(/plugins/).end()
      .use('babel')
      .loader('babel-loader')
      .tap(options => {
        // 修改它的选项...
        return options
      })
  }
}
  1. 编写组件
    在这里插入图片描述
    我这是把封装的组件、封装的指令和封装的过滤器每个都写在分类文件夹中,后面在合理添加并继续封装。
    下面我以datetime这个组件为例:(是一个时间显示组件)
    在这里插入图片描述
    components下面建组件date-time.vue和单独暴露组件的index.js文件:

date-time.vue内容如下:

<template>
  <div class="date-time" :style="{ 'font-size': `${useStyleObj.fontSize}px` }">
    <p :style="styleObject">{{ nowDate }}</p>
    <p :style="styleObject">{{ nowTime }}</p>
  </div>
</template>
<script>
export default {
  name: "dateTime",
  props: {
    styleObj: {//客户端传递的样式
      type: Object,
      default: () => ({
        fontSize: 25,
        color: ["#dcedff", "#5ca9ff"]
      })
    }
  },
  computed: {
    useStyleObj() {//用computed是为了暴露客户端的styleObj样式属性值可以选填,更加灵活
      let size = 25;
      let color = ["#dcedff", "#5ca9ff"];
      if (this.styleObj.fontSize) {
        size = this.styleObj.fontSize;
      }
      if (this.styleObj.color) {
        color = this.styleObj.color;
      }
      return {
        fontSize: size,
        color: color
      };
    },
    styleObject() {//根据客户端传递的样式值配置文字的渐变色
      return {
        background: `linear-gradient(180deg,${this.useStyleObj["color"][0]},
        ${
          this.useStyleObj.color.length > 1
            ? this.useStyleObj["color"][1]
            : this.useStyleObj["color"][0]
        })`,
        "-webkit-background-clip": "text"
      };
    }
  },
  data() {
    return {
      timer: null,
      nowWeek: "",
      nowDate: "",
      nowTime: ""
      //   styleBox: {}
    };
  },
  created() {
    this.timer = setInterval(() => {
      this.setNowTimes();
    }, 1000); //时间
  },
  beforeDestroy: function() {
    if (this.timer) {
      clearInterval(this.timer);
    }
  },
  methods: {
    setNowTimes() {//时间拼接方法
      const myDate = new Date();
      const wk = myDate.getDay();
      const yy = String(myDate.getFullYear());
      const mm = myDate.getMonth() + 1;
      const dd = String(
        myDate.getDate() < 10 ? `0${myDate.getDate()}` : myDate.getDate()
      );
      const hou = String(
        myDate.getHours() < 10 ? `0${myDate.getHours()}` : myDate.getHours()
      );
      const min = String(
        myDate.getMinutes() < 10
          ? `0${myDate.getMinutes()}`
          : myDate.getMinutes()
      );
      const sec = String(
        myDate.getSeconds() < 10
          ? `0${myDate.getSeconds()}`
          : myDate.getSeconds()
      );
      const weeks = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
      const week = weeks[wk];
      this.nowDate = `${yy}/${mm}/${dd} ${week}`;
      this.nowTime = `${hou}:${min}:${sec}`;
      this.nowWeek = week;
    }
  }
};
//样式文件
</script>
<style lang="scss" scoped></style>

index.js文件内容:
为组件提供 install 方法,供组件对外按需引入

import dateTimes from "./date-time.vue";

dateTimes.install = Vue => Vue.component(dateTimes.name, dateTimes); //注册组件

export default dateTimes;

注:这个单独暴露组件的index.js,意思是如果这个工程值封装一个组件使用的话,就用这个index.js文件暴露install即可了。

plugins文件夹下面新建一个index.js文件,为了统一导出所有组件及暴露 install 方法。之前的 index.js 只是安装单个组件,而现在这个 index.js 是循环安装所有组件
所有指令、过滤器统一暴露出去,可以按需引用组件,此时plugins文件夹的内容为

在这里插入图片描述
我这里是统一暴露组件、指令、过滤器:

//组件
import DateTime from "./components/dateTime/date-time.vue";
import selectDate from "./components/selectDate/index.vue";
import numberScroll from "./components/number-scroll/index.vue";
import tabPage from "./components/tabPage/index.vue";
import listScroll from "./components/list-scroll/index.vue";

//指令
// import * as directives from "./directives/*/index.js";
import autoScale from './directives/auto-scale/index.js'
import waterMarker from './directives/water-marker/index.js'

//过滤器
import numberFormat from './Filters/number-format/index.js'

//所有组件列表
const components = [DateTime, selectDate, numberScroll, tabPage, listScroll];
//所以指令
const directives = [autoScale, waterMarker];
//过滤器
const filters = [numberFormat]


//定义install方法,Vue作为参数
const install = Vue => {
  //判断是否安装,安装过就不用继续执行
  if (install.installed) return;
  install.installed = true;
  //遍历注册所有组件
  components.map(component => Vue.component(component.name, component));

  //遍历注册所有指令
  directives.map(directives => Vue.use(directives));

  //遍历过滤器
  filters.map(filters => Vue.use(filters));
};

//检测到Vue再执行
if (typeof window !== "undefined" && window.Vue) {
  install(window.Vue);
}

export default {
  install,
  //所有组件,必须具有install方法才能使用Vue.use()
  ...components
};

6.在本地页面中使用组件:

  • 在main.js中引入:
    在这里插入图片描述

  • 在home.vue中使用组件:
    在页面中不用引入使用使用组件,因为是全局注册了组件库,所以可以直接使用标签
    ,这个标签与组件文件中的date-time.vue里的name保持一致,只不过一个是驼峰式写法,一个是标签名称。这在Vue中很常见。

在这里插入图片描述
在这里插入图片描述
测试可以全局使用组件,说明封装的组件没有问题,下面可以打包了。

  1. 库模式打包
    在package.json文件中的"scripts"字段里添加以下内容:
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lib": "vue-cli-service build --target lib --name llgtfoo-components-box -dest lib plugins/index.js",
    "lint": "vue-cli-service lint"
  },
因为在vue-cli中,可以通过以下命令将一个单独的入口打包成库

// target: 默认为构建应用,改为 lib 即可启用构建库模式
// name: 输出文件名
// dest: 输出目录,默认为 dist,这里我们改为 lib
// entry: 入口文件路径
vue-cli-service build --target lib --name lib [entry]
  • package.json中配置打包信息:
    在这里插入图片描述
name:包名
version:包的版本号,每次发包这个版本号都要改
description:包的描述
private:是否私有,一般都是false
author:作者
license:npm包协议
keywords:关键字,供npm上模糊搜索到包
  • .gitignore文件中添加:
.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?


src/
plugins/
public/
vue.config.js
babel.config.js
*.map
*.html

把包的一些测试文件过滤掉,最终打包只留下直接封装的文件,即plugins中封装的暴露组件

  • 在终端执行npm run lib 即可,执行结果:
    在这里插入图片描述
    在这里插入图片描述
  1. 发布包
  • 终端中执行发包命令
    npm login 登录(如果没有npm账号需要自己注册,并认证邮箱)
    这样既登录成功
    在这里插入图片描述
    需要 one-time 的话,参照:获取one-time步骤(要这一步npm贼恶心)
    在输入npm publish 发布包,出现包名加版本号,即发布成功
  • npm 上能找到自己发布的包:
    在这里插入图片描述
  1. 使用发布的包
    npm i llgtfoo-components-box --save
    在项目文件mainjs中引入
import llgtfooComponentsBox from "llgtfoo-components-box";
import "llgtfoo-components-box/dist/llgtfoo-components-box.css";
Vue.use(llgtfooComponentsBox);
注:全局使用,组件可以单独引用

在项目中直接使用组件中的name即可
例如:<date-time></date-time>

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐