在npm上发布自己的vue组件库(使用npm install 或者 CDN的方式引用)

在codepen上看到了一个好看的pen,于是把它重写成了一个vue的组件;
为了能在其他地方使用该组件,准备创建一个自己的vue组件库发布到npm上;
因为之前没有发布过,于是就先上网上搜索了一下教程

个人主页原文链接

主要是参考了一下这篇教程还有iviewelement这两个组件库的package.json、index.js、webpack文件。

只看创建流程可以直接看第三部分

一、npm publish

  • 发布包到npm库的命令是npm publish

  • npm publish发布包,需要先配置webpack.json文件,如果没有webpack.json文件,可以通过npm init命令初始化一个

  • package.json的部分字段简介如下

name:发布的包名,默认是上级文件夹名。不得与现在npm中的包名重复。包名不能有大写字母/空格/下滑线!
version:你这个包的版本,默认是1.0.0。对于npm包的版本号有着一系列的规则,模块的版本号采用X.Y.Z的格式,具体体现为:
  1、修复bug,小改动,增加z。
  2、增加新特性,可向后兼容,增加y
  3、有很大的改动,无法向下兼容,增加x
description:项目简介
mian:入口文件,默认是index.js
scripts:包含各种脚本执行命令
test:测试命令。
author:自己的账号名
license:开源文件协议
private:是否私有
  • 如果要发布的话需要把private字段设为false

  • 发布的包的资源可以通过https://unpkg.com/$name@$version/找到。

    • 比如我发布了一个包,name是zxz-ui,version是1.0.0,那么我就可以在 https://unpkg.com/zxz-ui@1.0.0/ 找到我发布的包里面的资源
  • 我们可以通过创建文件npmignore或者 pkg.files来设置上传时过滤某些文件和文件夹,如果我们不设置的话,有些文件和文件夹也是会默认忽略上传的,比如node_modules文件夹、package-lock.json文件等

image
image

二、我们如何通过npm引用组件的

先看一下node.js中的模块调用的规则 https://nodejs.org/api/modules.html#modules_accessing_the_main_module

主要注意以下两部分
image

require(X) from module at path Y
1. If X is a core module,
   a. return the core module
   b. STOP
2. If X begins with '/'
   a. set Y to be the filesystem root
3. If X begins with './' or '/' or '../'
   a. LOAD_AS_FILE(Y + X)
   b. LOAD_AS_DIRECTORY(Y + X)
4. LOAD_NODE_MODULES(X, dirname(Y))
5. THROW "not found"

LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text.  STOP
2. If X.js is a file, load X.js as JavaScript text.  STOP
3. If X.json is a file, parse X.json to a JavaScript Object.  STOP
4. If X.node is a file, load X.node as binary addon.  STOP

LOAD_INDEX(X)
1. If X/index.js is a file, load X/index.js as JavaScript text.  STOP
2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
3. If X/index.node is a file, load X/index.node as binary addon.  STOP

LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
   a. Parse X/package.json, and look for "main" field.
   b. If "main" is a falsy value, GOTO 2.
   c. let M = X + (json main field)
   d. LOAD_AS_FILE(M)
   e. LOAD_INDEX(M)
   f. LOAD_INDEX(X) DEPRECATED
   g. THROW "not found"
2. LOAD_INDEX(X)

LOAD_NODE_MODULES(X, START)
1. let DIRS = NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
   a. LOAD_AS_FILE(DIR/X)
   b. LOAD_AS_DIRECTORY(DIR/X)

NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = [GLOBAL_FOLDERS]
4. while I >= 0,
   a. if PARTS[I] = "node_modules" CONTINUE
   b. DIR = path join(PARTS[0 .. I] + "node_modules")
   c. DIRS = DIRS + DIR
   d. let I = I - 1
5. return DIRS

以iview为例,我们npm i iview下载iview组件库后,通过import iView from 'iview'引用它,其实就是通过import iView from './node_modules/iview'引用它,然后./node_modules/iview是一个文件夹,会按照LOAD_AS_DIRECTORY(X)中的规则寻找,先是找到./node_modules/iview/package.json这个文件,然后找到其中的main字段,最后通过main字段找到./node_modules/iview/dist/iview.js这个文件。
image
iview.js这个文件是通过webpack打包得到的,直接看代码基本上是看不懂的,我们看看它是怎么打包出来的。


先找到iview.js的webpack配置文件

https://github.com/iview/iview/blob/2.0/build/webpack.dist.dev.config.js

……
process.env.NODE_ENV = 'production';
module.exports = merge(webpackBaseConfig, {
    devtool: 'source-map',
    entry: {
        main: './src/index.js'
    },
    output: {
        path: path.resolve(__dirname, '../dist'),
        publicPath: '/dist/',
        filename: 'iview.js',
        library: 'iview',
        libraryTarget: 'umd',
        umdNamedDefine: true
    },
    ……
});

上面是在生产环节下打包iview.js的配置,我们找到它的入口文件

https://github.com/iview/iview/blob/2.0/src/index.js

import Affix from './components/affix';
……

const components = {
    Affix,
    ……
};

const iview = {
    ...components,
    iButton: Button,
    ……
};

const install = function(Vue, opts = {}) {
    if (install.installed) return;
    ……

    Object.keys(iview).forEach(key => {
        Vue.component(key, iview[key]);
    });

    ……
};

// auto install
if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue);
}

const API = {
    ……
    install,
    ……
};

……

module.exports.default = module.exports = API;   // eslint-disable-line no-undef

从该文件可以看出来,它先是将components文件夹中的组件都通过import引入,然后定义了一个components对象来存放所有组件,然后又对部分组件增加了第二个key定义了iview对象(例如<Col><Col>组件,也可以通过<i-col><i-col>来使用),然后定义了一个install函数来遍历注册组件。最后将install函数作为输出对象的install方法。

然后这个输出对象其实就是上面import iView from 'iview'得到的iView对象,因此通过Vue.use(iView)来调用iView.install方法就能成功的把iView库的组件注册到我们的Vue对象上。

另外,如果是直接通过CDN引用js文件的话,会触发auto install注释下的内容,会将组件注册到当前window.Vue上(需要先通过CDN引入vue.js)

三、流程

  1. 使用vue init webpack-simple xxx初始化项目
  2. npm install
  3. 在src目录下新建components文件夹,并将组件放入其中
  4. 在根目录下新建index.js
import XXX from './src/components/XXX'
import YYY from './src/components/YYY'
import ZZZ from './src/components/ZZZ'
……

const components = [
  XXX,YYY,ZZZ,……
];

const install = function (Vue) {
  components.forEach(component => {
    Vue.component(component.name, component);
  });
};

if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}

export default {
  install,
  XXX,
  YYY,
  ZZZ,
  ……
};

这里说明一下,我是用组件内部的name属性做的组件标签名
5. 配置webpack.config.js

var path = require('path')
var webpack = require('webpack')
const NODE_ENV = process.env.NODE_ENV

module.exports = {
  //入口这里一个是测试组件时npm run dev的入口文件,一个是npm run build的入口文件
  entry: NODE_ENV === 'development' ? './src/main.js' : './index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/', //输出的文件夹
    filename: 'filename.js',//输出的文件名
    library: 'objectname',    //引用js文件时创建的全局变量名
    libraryTarget: 'umd',
    umdNamedDefine: true
  },
  ……
}

……

  1. 配置package.json
{
  "name": "package-name",
  "description": "描述",
  "version": "1.0.0",
  "author": "XXXXXXXXXXX",
  "license": "MIT",
  "private": false,
  "main": "dist/filename.js",
  ……
}

  1. npm run build
  2. npm publish
  3. 使用
//npm导入
npm i package-name

import xxx from 'package-name'
Vue.use(xxx)

//cdn导入
<script src="//vuejs.org/js/vue.min.js"></script>
<script src="//https://unpkg.com/package-name@1.0.0/dist/filename.js"></script>
  1. 如果想把css单独抽离出来还需要更新webpack、webpack-cli,和安装optimize-css-assets-webpack-plugin、uglifyjs-webpack-plugin等包。
    • webpack配置:https://github.com/pma934/zxz-ui/blob/master/webpack.config.js

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值