开发npm包

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

开发 vue组件,并上传到 npm

前文

淘宝源:registry.npm.taobao.org

正式源: registry.npmjs.org/

换源命令
npm config set registry https://registry.npm.taobao.org --global

npm config list // 
复制代码
运行环境

win10

node:v10.16.0

npm: 6.9.0

项目github下载地址


1.创建项目

mkdir vue-replay

cd vue-replay

npm init

package name: (vue-replay) // 包名称 默认文件名称
version: (1.0.0) // 版本号
description: 移动web端回复框(自动触发键盘弹起ios+Android)// 说明
entry point: (index.js) dist/index.js // 入口文件路径
test command: // 测试命令
git repository: https://github.com/wanghao-fan/vue-replay.git// 你的 git仓库
keywords: vue-replay // 关键词
author: nothing49199 // 作者
license: (ISC) // 许可证 类型
复制代码

2.创建目录、文件

  • 根目录下 创建目录 src、 src/components; 文件 :.gitignore、README.md、webpack.config.js

  • components目录下创建 sendReplay.vue组件

      <template>
        <div
          v-if="focusType"
          class="answer">
          <div class="box clearfix">
            <div class="left">
              <input
                v-focus="focusType"
                name="sendReport"
                :value="value"
                :placeholder="tips"
                @change="handleChange($event)"></div>
            <div class="right"><button @click="send()"><span>发送</span></button></div>
          </div>
          <div
            v-show="focusType"
            class="mask"
            @click="active()" />
        </div>
      </template>
      <script>
      export default {
        name: 'SendReport',
        // 设置获取焦点
        directives: {
          // 自动获取焦点
          focus: {
            inserted: function(el, binding) {
              if (binding.value) {
                el.focus()
                el.scrollIntoView()
              } else {
                el.blur()
              }
            },
            componentUpdated: function(el, binding) {
              if (binding.value) {
                el.focus()
                el.scrollIntoView()
              } else {
                el.blur()
              }
            }
          }
        },
        props: {
          // input value值
          value: {
            type: String,
            default: null
          },
          // 是否展示和获取焦点
          focusType: {
            type: Boolean,
            default: false
          },
          // 输入框内 提示语
          tips: {
            type: String,
            default: null
          }
        },
        data() {
          return {
            height: null
          }
        },
        computed: {
          status() {
            return !this.focusType
          }
        },
        watch: {
          // 发送完后 回到原始位置
          focusType() {
            if (this.focusType) {
              this.ios()
            } else {
              document.body.scrollTop = this.height
              document.documentElement.scrollToop = this.height
            }
          }
        },
        mounted() {
          // 监听滚动条高度
          document.addEventListener('scroll', res => {
            if (this.status) {
              this.height = (document.documentElement.scrollTop || document.body.scrollTop)
            }
          })
        },
        methods: {
          // 隐藏组件
          active() {
            this.$emit('update:focusType', false)
          },
          // 发送回调函数
          send() {
            this.$emit('send')
          },
          // 兼容ios手机 滚动
          ios() {
            setTimeout(function() {
              this.height = document.body.scrollTop
              document.body.scrollTop = document.body.scrollHeight
              document.documentElement.scrollTop = document.body.scrollHeight
            }, 300)
          },
          // 同步父级 input 输入 value值
          handleChange(event) {
            this.$emit('input', event.target.value)
          }
        }
      }
      </script>
      
      <style lang="scss" scoped>
      .clearfix:before,
      .clearfix:after {
          content: " ";
          display: block;
          font-size: 0;
          height: 0;
          clear: both;
          visibility: hidden;
      }
      
      .clearfix {
          *zoom: 1;
      }
      
      /* 浮动 */
      .left{
        float: left;
      }
      .right{
        float: right;
      }
      .answer{
        background-color: #f9f9f9;
        position:fixed;
        bottom: 0;
        right: 10px;
        width: 100%;
        height: 50px;
        z-index: 99999999999999;
        padding-bottom: 10px;
        .box{
          position: relative;
          z-index: 99999999999999;
          .left{
              width: 82%;
              text-align: center;
              padding-top:8px;
            >input{
              margin-left:10px;
              width: 90%;
              height: 40px;
              border: 1px solid #e8e8e8
            }
          }
          .right{
              width: 18%;
              padding-top:10px;
              >button{
                border-radius:5px;
                width: 100%;
                height: 40px;
                text-align: center;
                background-color: #18b4ed;
              }
          }
        }
      }
      .mask{
          z-index: 99999999;
          position: fixed;
          top: 0;
          right: 0;
          left: 0;
          bottom: 0;
          background: rgba(0, 0, 0, 0.8);
          opacity: 0;
      }
      </style>
    复制代码
  • src 目录下创建 index.js 入口文件

    import sendReplay from ‘./components/sendReplay.vue’

    sendReplay.install = function(Vue) {
    Vue.component(sendReplay.name, sendReplay);
    };

    export default sendReplay;

  • .gitignore

    .DS_Store
    node_modules
    package-lock.json

    local env files

    .env.local
    .env.*.local

    mock-back
    .history

    Log files

    npm-debug.log*
    yarn-debug.log*
    yarn-error.log*

    Editor directories and files

    .idea
    .vscode
    *.suo
    .ntvs
    *.njsproj
    *.sln
    *.sw?

  • webpack.config.js

    const path = require(‘path’);
    let VueLoaderPlugin = require(‘vue-loader/lib/plugin’)

    module.exports = {
    mode: ‘development’, // production development
    entry: {
    tree: ‘./src/index.js’ // 入口文件
    },
    output: {
    path: path.resolve(__dirname, ‘./dist’), // 输出目录
    filename:’index.js’, // 输出文件名
    library: ‘vue-replay’, // 指定的就是你使用require时的模块名
    libraryTarget: ‘umd’, // 支持cmd,amd,及全局 具体啥意思也没明白 libraryTarget会生成不同umd的代码,可以只是commonjs标准的,也可以是指amd标准的,也可以只是通过script标签引入的
    umdNamedDefine: true // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define
    },
    plugins:[
    new VueLoaderPlugin() // 这里遇到坑了,不加 vue-load报错
    ],
    module:{
    rules: [
    {
    test: /.vue/, loader: ‘vue-loader’ }, { test: /\.css/,
    use: [
    ‘style-loader’,
    ‘css-loader’
    ]
    },
    {
    test: /.js/, loader: ‘babel-loader’ }, { test: /\.scss/,
    use: [
    ‘vue-style-loader’,
    ‘css-loader’,
    {
    loader: ‘sass-loader’
    }
    ]
    }
    ]
    }

    }

3. 下载npm 依赖

npm install 以下依赖

dependencies 依赖

  • “babel-loader”: “^8.0.6”,
  • “css-loader”: “^3.1.0”,
  • “html-webpack-plugin”: “^3.2.0”,
  • “node-sass”: “^4.12.0”,
  • “sass-loader”: “^7.1.0”,
  • “style-loader”: “^0.23.1”,
  • “stylus-loader”: “^3.0.2”,
  • “vue”: “^2.6.10”,
  • “vue-loader”: “^15.7.1”,
  • “webpack”: “^4.38.0”,
  • “webpack-cli”: “^3.3.6”,
  • “webpack-dev-server”: “^3.7.2”,
  • “webpack-server”: “^0.1.2”

devDependencies

  • “@babel/core”: “^7.5.5”,
  • “@babel/preset-env”: “^7.5.5”,

“babel-core”: “^6.26.3”,

  • “babel-preset-env”: “^1.7.0”,
  • “vue-template-compiler”: “^2.6.10”

4. 打包 发布项目

npm build
    
// git 上传你的代码(也可以不传)
// 注册一个 npm账号
npm login // 这了如果拟更换过 npm 源的话 加个 --registry=https://registry.npmjs.org/

Username: ***
Password:***
Email: (this IS public):邮箱

npm publish 
复制代码

如果失败,检查一下 npm官网上是否已经存在相同名字,每次推得话 更改一下版本号

还有测试的时候,如果你的源taobao源,你发布包暂时只在国外源,taobao源是没有的,等过一段时间才能同步,拉去你写的包时同理可以加上 –registry 之指定一下源就可以了

5.使用方法

使用文档

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