手记

不会发布npm包?进来看看?


npm(Node Package Manager),一个Node的包管理器,平时我们常用的公共模块(插件)或者叫做包大多都放在上面,所以接下来要封装的插件,我们就简单称它为npm包,本文从就从这个简单的例子开始,逐步对它进行封装-发布-更新-扩展-使用,进而到得一个相对完整的npm包,下面开始。

一、一个最简单的npm包

1.1 新建文件夹

可以找个地方直接建个文件夹,最好语义化一点,这样以后也方便管理,我们这里用终端建文件夹:

   mkdir toupper-case-project   // 这里我们建了一个名为toupper-case-project的文件夹

(对命令行还不太熟的小伙伴可以看看我这篇博客命令行不会?看这里)

1.2 初始化项目

在项目根目录下使用一下命令

   npm init

这时终端会提示你输入诸如包名,版本号等信息,如下:

不会发布npm包?进来看看?

当然,你可以一路回车下来,或者你使用npm init -y就可以生成默认的package.json文件,效果都是一样的,然后我们得到以下文件,简单说明一下:

// package.json

{

  "name": "toupper-case-project",  // 包名称,默认和你文件夹同名,可改,但是需要去npm官网搜素这个名称是否已存在,因为包名不能重复

  "version": "1.0.0",  // 项目默认版本号,可改,如果项目后期更新再发布,则需要修改版本号

  "description": "",   // 项目描述,选填,可利于SEO 

  "main": "index.js",  // 你的包的主要入口路径,就是别人安装了你的包后系统会去这个路径找你的代码

  "scripts": {         // 脚本命令,后面会讲到,现在使用默认的就行

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "author": "",        // 作者,选填

  "license": "ISC"     // 许可证,默认即可

}

注:以上代码使用时记得把注释删除,json不能注释

1.3 新建项目文件

根目录下新建index.js和upper.js两个文件分别如下:

// upper.js

let toUpper = (a) => {

    return a.toUpperCase();

};

export default toUpper;

// index.js

import toUpper from './upper.js';

export default toUpper;

此时我们的项目就应该只有三个文件,如下:

不会发布npm包?进来看看?

upper.js用于项目功能逻辑,index.js用于导出功能模块,package.json用于配置相关信息,这样我们就把一个最简单的npm包写好了,接下里进入发布。

1.4 发布

1.注册npm账号

前往npm官网注册一个账号,记好账户名、密码和邮箱(邮箱收到邮件后一定要进行验证)。

 

2.源切换

这是个坑,估计很多小伙伴都踩过,毕竟国内npm的速度令人感动,所以大家都运行过一条熟悉的命令:

npm install -g cnpm --registry=https://registry.npm.taobao.org

但是发布时我们一定要把源切换回npm,而不是淘宝源,当然,直接运行下面这个命令即可解决:

npm config set registry=http://registry.npmjs.org

但是老这样切来切去有点low啊,这时候nrm就派上用场了,nrm是什么?简单点说nrm就是专门用来管理和快速切换私人配置的registry的一个工具。

cnpm i nrm -g

安装好后使用nrm ls命令会显示如下:

不会发布npm包?进来看看?

*号在哪个地方就说明现在的源是哪个(我现在处在taobao源),也许你刚开始不显示号,但不管显不显示,直接运行nrm use npm,然后再npm ls,这时候就发现`指在npm`源上了,此时就可以进行下一步了。

 

3.登录

npm login

然后会提示你输入用户名、密码(是密文的,你看不见,直接输就行)和邮箱,登录成功后会显示:

不会发布npm包?进来看看?

 

4.试着发布npm包

在项目根目录下运行npm publish即可发布,顺利的话就直接成功了,当然也可能会遇到问题:

第一个就是权限问题,也许报这样的错误npm ERR! Error: EPERM: operation not permitted,这时候就得使用管路员权限来进行发布了,window + x会看到管理员终端选项,打开这个终端,然后再进行登录,发布即可。

第二个就是名称问题,就是你的包名在npm上已经存在了,所以在package.json中将你的包名改成其他的,这样再发布,应该就没问题了。

发布成功后显示如下:

不会发布npm包?进来看看?

1.5 用用我们发布的包

随便找个练手项目试试:

cnpm i toupper-case-project -D

安装完成:

不会发布npm包?进来看看?

说明我们的包是可以下载安装的,然后试试功能,我就直接在vue项目中试试了,大家应该看得懂:

不会发布npm包?进来看看?

然后运行项目:

不会发布npm包?进来看看?

搞定!那如果我们后期把这个包改了呢,该怎么做?

1.6 更新包

我们把upper.js文件改一改:

// upper.js

let toUpper = (a) => {

    return 'Hello' + a.toUpperCase();

};

export default toUpper;

然后记得把package.json中的版本号也改了,正常来说加1即可,

将"version": "1.0.0"改为"version": "1.0.1"

现在运行npm publish就可以直接把新的包覆盖上去:

不会发布npm包?进来看看?

然后我们在练手项目中怎么更新这个包呢?

方法一(直接更新):cnpm update toupper-case-project(有时可能更新不完全)

方法二(安装覆盖):cnpm i toupper-case-project -D(这个比较靠谱)

然后运行项目:

不会发布npm包?进来看看?

完美!这就是一个最简单的npm包,是不是没有想象中的那么触不可及?但说实话,这个包确实挺low,你看别人的包还经过打包啊、测试啊、还能在vue中直接Vue.use()方式来使用,而且还有交互。那下面我们就来试试。

二、基于webpack和vue的npm包

直接使用vue-cli的话会带上许多我们不需要的模块,太笨重,所以我们直接撸一个,如果对webpack还不太熟悉的,可以看看我这篇webpack4.x最详细入门讲解

2.1 构建项目(星级评价组件)

我们来封装一个可根据传入的评分数来显示星级的组件,类似这样的:

不会发布npm包?进来看看?

具体代码请移步github,请反手给个 Star ^_~,下面开始:

首先新建一个名为star-evaluation的项目文件夹;

然后根据以下结构建立项目文件:

|——src

|    |——images

|    |     |——star24_half@2x.png

|    |     |——star24_off@2x.png

|    |     |——star24_on@2x.png

|    |——index.js

|    |——Star.vue

|——.npmignore  // 用于忽略不需要上传到npm的文件

|——package.json

|——README.md

|——webpack.config.js

各文件如下:

Star.vue具体代码如下,主要就是将传过来的数值处理后遍历出不同的class类名,然后添加到span上。

<!-- Star.vue -->

<template>

  <div class="star">

    <span class="star-item" v-for="(itemClass, index) in itemClasses" :key="index" :class="itemClass"></span>

  </div>

</template>

<script>

// 星星长度

const LENGTH = 5;

// 星星状态

const CLS_ON = 'on';

const CLS_HALF = 'half';

const CLS_OFF = 'off';

export default {

  data () {

    return {

    }

  },

  props: {

    score: {

      type: Number

    }

  },

  computed: {

    itemClasses () {

      let result = [];

      // 如果小数大于或等于0.5则变为0.5,否则为0

      let score = Math.floor(this.score * 2) / 2;

      // 全星

      let integer = Math.floor(score);

      // 半星

      let hasHalf = score % 1 !== 0;

      // 遍历全星

      for (let i = 0; i < integer; i++) {

        result.push(CLS_ON);

      }

      // 处理半星

      if (hasHalf) {

        result.push(CLS_HALF);

      }

      // 补齐,如果星数小于5,则一直循环判断填入数据,直到满足条件

      while (result.length < LENGTH) {

        result.push(CLS_OFF);

      }

      return result;

    }

  }

}

</script>

<style scoped>

  .star{

    font-size: 0;

    .star-item{

      display: inline-block;

      width: 10px;

      height: 10px;

      margin-right: 3px;

      background-repeat: no-repeat;

      background-size: 10px 10px;

      &:last-child{

        margin-right: 0;

      }

    }

    /* 三种图片类型*/

    .on{

      background-image: url(./images/star24_on@2x.png);

    }

    .half{

      background-image: url(./images/star24_half@2x.png);

    }

    .off{

      background-image: url(./images/star24_off@2x.png);

    }

  }

</style>

// index.js

import Star from './Star.vue';

export default Star;

package.json的依赖配置如下:

{

  "name": "star-evaluation",

  "version": "1.0.0",

  "description": "A plugin which use stars number to evaluate",

  "main": "dist/bundle.js",

  "scripts": {

    "build": "webpack --mode production",

    "dev": "webpack-dev-server --open --mode development"

  },

  "repository": {

    "type": "git",

    "url": "git+https://github.com/Better-Alan/star-evaluation.git"

  },

  "keywords": ["star", "evaluation"],

  "author": "BetterMan",

  "license": "ISC",

  "devDependencies": {

    "babel-core": "^6.26.3",

    "babel-loader": "^7.1.5",

    "babel-preset-env": "^1.7.0",

    "css-loader": "^1.0.0",

    "file-loader": "^2.0.0",

    "node-sass": "^4.9.4",

    "sass-loader": "^7.1.0",

    "style-loader": "^0.23.1",

    "url-loader": "^1.1.2",

    "vue": "^2.5.17",

    "vue-hot-reload-api": "^2.2.4",

    "vue-html-loader": "^1.2.4",

    "vue-loader": "^15.4.2",

    "vue-router": "^3.0.1",

    "vue-style-loader": "^3.0.3",

    "vue-template-compiler": "^2.5.9",

    "webpack": "^4.23.1",

    "webpack-cli": "^3.1.2"

  }

}

webpack.config.js配置如下,用于将/src中的内容打包到/dist(打包时会自动生成/dist文件夹)中的bundle.js,bundle.js其实就相当于我们的插件。

// webpack.config.js

const path = require('path');  // 路径处理模块

const { VueLoaderPlugin } = require('vue-loader');

module.exports = {

    entry: {

        index: path.join(__dirname, "/src/index.js")   // 入口

    }, 

    output: {

        path: path.join( __dirname, "/dist"), // 打包后的文件存放的地方

        publicPath: '/dist/',  // 设置公共路径

        filename: "bundle.js", // 打包后输出文件的文件名

        libraryTarget: 'umd'   // 将你的library暴露为所有的模块定义下都可运行的方式,它将可在 CommonJS, AMD 环境下运行

    },

    module: {

        rules: [

            {

                test: /\.vue$/,   // vue-loader

                loader: 'vue-loader'

            },

            {

                test: /\.css$/,           // 正则匹配以.css结尾的文件

                use: ['style-loader', 'css-loader']

            },

            {

                test: /\.(scss|sass)$/,   // 正则匹配以.scss和.sass结尾的文件

                use: ['style-loader', 'css-loader', 'sass-loader']  // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的

            },

            {

                test: /\.(png|jpg|svg|gif)$/,  // 图片loader

                use: ['url-loader']

            },

            {

                test: /\.js$/,    

                exclude: /node_modules|vue\/dist|vue-router\/|vue-loader\/|vue-hot-reload-api\//,

                loader: 'babel-loader'

            }

        ]

    },

    plugins: [

        new VueLoaderPlugin()

    ]

}

.npmignore(别忘了前面的点)文件用于忽略不需要上传到npm的文件,规则和.gitignore一样。如果你的项目内有.gitignore但没有


0人推荐
随时随地看视频
慕课网APP