在Npm上发布模块

前言
入行前端也不少时间了,之前一直都在使用npm install别人的模块/组件,那么作为一名有追求的前端肯定不会满足一直在用别人的轮子。
今天给大家分享一下如何在npm上发布自己的模块或者组件。

第一章 登录npm

1
2
3
npm adduser //创建用户
or
npm login //登录用户

可以使用

1
npm whoami

检测用户是否登录上了npm

第二章 发布模块

1.首先安装npm publish

1
npm i -g publish

2.创建自己的npm模块

创建空文件夹 fm_lindaidai_first

并且在命令行输入

1
2
npm init
一路回车

此时会出现package.json

1
2
3
4
5
6
7
8
9
10
11
{
"name": "fm_lindaidai_first",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "lindaidai",
"license": "ISC"
}

在package.json同级目录下编写date.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
date.js

(function(global) {
'use strict';

var datachange = (function() {
return function(date) {
var date = date || new Date;
if (!date instanceof Date) {
data = new Date(date);
}

if (isNaN(data)) {
throw TypeError('Invalid date');
}
let enDate = date.getFullYear() + "." + (date.getMonth()+1) + "." + date.getDate();
return enDate;
}
})();

if (typeof define === 'function' && define.amd) {
define(function () {
return datechange;
});
} else if (typeof exports === 'object') {
module.exports = datechange;
} else {
global.datechange = datechange;
}

})(this);

上面的date.js是添加简单的日期转换格式插件

由于命名的是date.js,因此记得将package.json中的“main”修改为date.js

否则别人使用的时候就会报错

3.在npm上发布自己的模块

1.确保自己是登录了npm的

2.确保自己的npm的邮箱被激活了

3.命名不能太简单,最后要有自己的标志,太简单可能是别人已经用过的名字你就不能发布成功,也不要有数字

4.如果是要再次推送同一个项目记得修改该项目版本号。

fm_lindaidai_first的命令行中输入指令

1
npm publish

成功之后会提示

1
+ fm_lindaidai_first@1.0.0

若是你编写的模块是第一次发布的,则直接使用指令npm publish就可以了
若是第二次,则需要在package.json中修改一下version,如修改为1.0.1,然后再次执行npm publish就OK。

4.使用自己的模块

可以直接就在项目中使用指令

1
npm i --save-dev fm_lindaidai_first

接下来可以在项目中使用

1
2
3
var datechange = require('fm_lindaidai_first');
var now = new Date();
var timeStamp = datechange(now);

第三章 创建vue组件并发布

上面介绍发布的模块是一个比较简单的时间格式转换插件,当然你也可以针对某个框架来发布特定的组件。

说一下我要实现的效果:
1.构建一个基于elementUI的表单生成器组件
2.在npm上发布它并使用

3.1 表单构造器组件

想要实现一个表单生成器,我们希望通过prop传入其中,就能构造想要的表单组件
如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<template>
<div>
<form-generator :schema="schema" v-model="formData">
</div>
</template>

data() {
return {
formData: {
firstName: "Lin",
lastName: "DaiDai"
},
schema: [{
fieldType: "SelectList",
name: "food",
multi: false,
label: "food",
options: [{
value: '黄金糕',
label: '黄金糕'
}, {
value: '双皮奶',
label: '双皮奶'
}, {
value: '蚵仔煎',
label: '蚵仔煎'
}, {
value: '龙须面',
label: '龙须面'
}, {
value: '北京烤鸭',
label: '北京烤鸭'
}]
},
{
fieldType: "TextInput",
placeholder: "First Name",
label: "First Name",
name: "firstName"
},
{
fieldType: "TextInput",
placeholder: "Last Name",
label: "Last Name",
name: "lastName"
},
{
fieldType: "NumberInput",
placeholder: "Age",
name: "age",
label: "Age",
minValue: 0
}
]
}

向名为from-generator的组件中传递一个数组,就能构建出以下表单列表:
npm1

3.1.1 vue-cli创建vue简单项目
1
vue init webpack-simple form-lin

我创建的项目名为form-lin

3.1.2 安装elementUI
1
npm i element-ui -S

可以看到我上面的表单类型是有select、input、numberInput、button这几种,所以我没有引入ele的全部组件,只是按需引入了,按需引入还需要借助 babel-plugin-component

1
npm install babel-plugin-component -D

然后,将 .babelrc 修改为:

1
2
3
4
5
6
7
8
9
10
11
12
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}

在main.js中引入部分组件

1
2
3
4
5
6
import { Button, Select, Input, Option, InputNumber } from 'element-ui';
Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
Vue.component(Option.name, Option);
Vue.component(Input.name, Input);
Vue.component(InputNumber.name, InputNumber);

通过以上步骤你已经可以在你的这个项目中使用elementUI的部分组件了。

3.1.3 逐个创建表单组件

结合上面的效果图,可以发现此项目创建的表单类型只有下拉框、输入框、数字输入框这三种,所以可以分别创建3种不同的组件

在components文件夹下创建文件夹v5,并在其中分别创建以下三个组件

  • TextInput.vue
  • SelectList.vue
  • NumberInput.vue

TextInput.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<template>
<div class="v5-template">
<label>{{label}}</label>

<!-- <input type="text"
:name="name"
:value="value"
@input="$emit('input',$event.target.value)"
:placeholder="placeholder
"> -->
<el-input style="width: 135px;" :name="name"
:value="value"
@input="TextInput"
:placeholder="placeholder" clearable></el-input>
</div>
<!-- @input="$emit('input',$event.target.value)" -->
</template>
<script>
import { Input } from 'element-ui';
export default {
name: 'TextInput',
props: ['placeholder', 'label', 'name', 'value'],
methods: {
TextInput(value) {
this.$emit('input', value);
}
}
}
</script>

注释部分为原生的input标签

SelectList.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<template>
<div class="v5-template">
<label>{{label}}</label>
<el-select :multiple="multi"
:value="value"
@change="SelectVal"
placeholder="请选择">
<el-option v-for="option in options"
:key="option.value"
:label="option.label"
:value="option.value">
</el-option>
</el-select>
</div>
</template>
<script>
import { Select } from 'element-ui';
import { Option } from 'element-ui';

export default {
name: 'SelectList',
props: ['multi', 'options', 'name', 'label', 'value'],
methods: {
SelectVal(value) {
this.$emit('input', value);
}
}
}
</script>

NumberInput.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<template>
<div class="v5-template">
<label>{{label}}</label>
<!-- <input type="number"
:name="name"
:value="value"
@input="$emit('input',
$event.target.value)"
:placeholder="placeholder"> -->
<el-input-number :name="name"
:value="value"
@change="InputNumber"
:placeholder="placeholder" controls-position="right" :min="1" :max="10">
</el-input-number>
</div>
</template>
<script>
import { InputNumber } from 'element-ui';

export default {
name: 'NumberInput',
props: ['placeholder', 'label', 'name', 'value'],
methods: {
InputNumber(value) {
this.$emit('input', value);
}
}
}
</script>

完成以上步骤,我们创建了三种不同的表单组件
接下来我们需要用一个生成器来将这三种表单组件联系起来

3.1.4 表单生成器

上面所创建的三种不同的组件,其实都可以用component标签来进行引入,只需要改变component标签的:is属性就可以了。

1
2
3
4
5
<!--输入框组件-->
<component :is="TextInput"></component>

<!--下拉框组件-->
<component :is="SelectList"></component>

那么我们就可以通过v-for来循环创建不同的表单组件,仅仅只需要改变:is的值就行了

接下来 还是在v5文件夹下,创建文件FormGenerator.vue

FormGenerator.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<template>
<div>
<component v-for="(field, index) in schema"
:key="index"
:is="field.fieldType"
:value="formData[field.name]"
@input="updateForm(field.name, $event)"
v-bind="field">
</component>

</div>
</template>

<script>
import NumberInput from "./NumberInput";
import SelectList from "./SelectList";
import TextInput from "./TextInput";
export default {
name: "FormGenerator",
components: { NumberInput, SelectList, TextInput },
props: ["schema", "value"],
data() {
return {
formData: this.value || {}
};
},
methods: {
updateForm(fieldName, value) {
this.$set(this.formData, fieldName, value);
this.$emit("input", this.formData);
}
}
};
</script>

v-for不用多说,schema就是我们在引用这个组件时外部传递进来表单数组
:is就是表单组件的类型
@input在使用component标签时,默认的事件名就是为input,值为value

3.1.5 调用表单构造器

完成以上步骤,我们可以在这个项目中本地调用以下这个组件
APP.vue中引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<template>
<div>
<form-generator
:schema="schema"
v-model="formData"
>
</form-generator>
<p>
Hello {{formData.title}} {{formData.firstName}} {{formData.lastName}}, I hear you are {{formData.age}} years old.
</p>
</div>
</template>
<script>
import FormGenerator from "./components/v5/FormGenerator";
export default {
name: 'formlin',
components: {
FormGenerator
},
methods: {

},
data() {
return {
formData: {
firstName: "Lin",
lastName: "DaiDai"
},
schema: [{
fieldType: "SelectList",
name: "food",
multi: false,
label: "food",
options: [...]
},
{
fieldType: "TextInput",
placeholder: "First Name",
label: "First Name",
name: "firstName"
},
{
fieldType: "TextInput",
placeholder: "Last Name",
label: "Last Name",
name: "lastName"
},
{
fieldType: "NumberInput",
placeholder: "Age",
name: "age",
label: "Age",
minValue: 0
}
]
}
}
}
</script>
<style>
</style>

使用npm run dev打开项目,是可以在页面中看到效果的,此时整个项目目录如下:
npm2
style文件夹是我个人创建的公用样式
DemoFive.vue和HellowWorld.vue可以忽略
src/index.js在后面会讲到。

3.2 将整个vue项目发布至npm

要想将vue项目发布至npm上,需要做一些配置

  • 修改package.json

    1. 修改”private”: false
      npm默认创建的项目是私有的,如果要发布至npm必须将其公开

      1. 添加”main”: “dist/build.js”
        通过import formlin from ‘form-lin’引用该组件时,项目会自动找到node_modules/load-ling-zi/dist/build.js
  • 在src加入组件代码App.vue, 并创建我们的导出文件index.js。 在index.js中添加:

    1
    2
    3
    4
    5
    6
    7
    8
    import formlin from './App.vue'

    export default formlin;

    //global 情况下 自动安装
    if (typeof window !== 'undefined' && window.Vue) {
    window.Vue.component('formlin', formlin);
    }
  • APP.vue中做一些修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <template>
    <div>
    <h1>Form Generator</h1>
    <form-generator
    :schema="schema"
    v-model="formData"
    >
    </form-generator>
    <el-button @click="outPut">提交</el-button>
    <p>
    Hello {{formData.title}} {{formData.firstName}} {{formData.lastName}}, I hear you are {{formData.age}} years old.
    </p>
    <demo-five></demo-five>
    </div>
    </template>

    <script>
    import DemoFive from './components/DemoFive.vue';
    import FormGenerator from "./components/v5/FormGenerator";

    import { Button } from 'element-ui';
    export default {
    name: 'formlin',
    components: {
    DemoFive,
    FormGenerator
    },
    methods: {
    outPut() {
    this.$emit('submit', this.formData);
    }
    },
    data() {
    return {
    formData: {
    firstName: "Lin",
    lastName: "DaiDai"
    },
    schema: [{...}]
    }
    }
    }
    </script>

    <style>
    @import "./style/common.css";
    </style>

el-button标签中添加一个click事件,用于输出formData
再将name修改为你要模块的名字,如我这里修改为formlin

  • 因为最后我们是打包成一个js文件,所以需要修改一下配置文件webpack.config.js

因为不是所有使用你组件的人都是通过npm按住和impor的很多人是通过

评论