您的位置:首页 > Web前端 > Vue.js

基于vueCli2发布一个vue组件的npm包

2020-01-14 21:17 399 查看

文章目录

  • 发布前准备
  • 发布到npm
  • 这篇文章主要记录了从零发布一个vue的npm包(包含一个简单的指令和一个vue组件)的实践过程及些许心得。

    初始化项目

    这里我们通过@vue/cli拉取简单配置的模板来初始化一个2.X的项目,不了解的同学可以看下vueCli3官方文档

    vue init webpack-simple vue-directive-kit

    初始化的项目目录如下

    ├── README.md
    ├── index.html
    ├── package.json
    ├── src
    │   ├── App.vue
    │   ├── assets
    │   └── main.js
    └── webpack.config.js

    接下来做一些改动。

    src
    目录改为
    examples
    用于本地开发及案例展示,新增一个
    packages
    目录用于存放组件源码及导出文件。

    ├── README.md
    ├── examples
    │   ├── App.vue
    │   └── main.js
    ├── index.html
    ├── package.json
    ├── packages
    │   ├── componentName // 单个组件
    │   │   ├── index.js
    │   │   └── src
    │   │       └── componentName.vue
    │   └── index.js  // 导出文件
    └── webpack.config.js

    由于文件名称做了改动,webpack的打包配置也要做对应修改。默认

    webpack.config.js
    会导出一个对象,这里我们改为导出一个函数,然后由函数把配置对象导出,这样可以接受一个通过
    package.json
    传过来的参数
    env
    ,同时修改
    entry
    output

    module.exports = env => {
    return {
    entry: env.lib ? "./packages/index.js" : "./examples/main.js",
    output: {
    // 打包文件的生成路径
    path: path.resolve(__dirname, env.lib ? "./lib" : "./dist"),
    publicPath: env.lib ? "/lib/" : "/dist/",
    // 打包后生成的文件名
    filename: env.lib ? "vue-directive-kit.js" : "build.js",
    /**
    * library指定的就是你使用require时引入的模块名
    * 这里便是require(“vue-directive-kit”)
    */
    library: env.lib ? "vue-directive-kit" : "",
    /**
    * libraryTarget可以指定打包文件中代码的模块化方式,默认为var,常见有如下几种:
    * commonjs/commonjs2: 将你的library暴露为CommonJS模块
    * amd: 将你的library暴露为amd模块
    * umd: 将你的library暴露为所有的模块定义下都可运行的方式
    * 其中AMD和UMD需要指定library,如果不声明组件库则不能正常运行,
    * 这是为了在浏览器上通过script标签加载时,用AMD模块方式输出的组件库可以有明确的模块名
    */
    libraryTarget: env.lib ? "umd" : "var",
    /**
    * 当使用了 libraryTarget: "umd",
    * 设置umNamedDefine为true时,
    * 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define。
    */
    umdNamedDefine: env.lib ? true : false,
    },
    };
    };

    上面的配置可以知道,我们需要通过env来控制打包类型。

    env
    需要在
    package.json
    中传入

    "scripts": {
    // 本地开发运行npm run dev
    "dev": "cross-env NODE_ENV=development webpack-dev-server --env --open --hot",
    "build": "cross-env NODE_ENV=production webpack --env --progress --hide-modules",
    // 需要发布的时候执行npm run lib打包
    "lib": "cross-env NODE_ENV=production webpack --env.lib --progress --hide-modules"
    },

    完善内容

    编写组件

    packages/componentName/src/componentName.vue
    文件中写如下你内容。当然这个是为了演示内容很简单,其实这个文件就是真实的组件了。

    <template>
    <div>
    <h1>我是一个组件</h1>
    </div>
    </template>
    
    <script>
    export default {
    name: 'componentName',
    data () {
    return { }
    }
    }
    </script>

    packages/componentName/src/index.js
    中注册并导出单个组件

    // 引入组件
    import componentName from './componentName/src'
    componentName.install = Vue => Vue.component(componentName.name, componentName);
    
    if (typeof window !== 'undefined' && window.Vue) {
    window.Vue.use(componentName);
    }
    
    export default componentName;

    编写指令

    我们增加一个名称为

    testDirective
    的指令。
    创建’packages/testDirective/src/testDirective.js’文件:

    export default {
    bind: () => {
    console.log(`directive bind`);
    },
    inserted: (el, binding) => {
    console.log(`el:`, el);
    },
    }

    创建

    packages/testDirective/index.js
    文件:

    // 引入组件
    import testDirective from './src/testDirective'
    const install = Vue => {
    Vue.directive('testDirective', testDirective);
    };
    
    if (typeof window !== 'undefined' && window.Vue) {
    window.Vue.use({install});
    }
    
    export default {
    install
    };

    统一导出

    编辑出口文件

    packages/index.js
    ,将
    packages
    目录下所有的指令及组件统一注册导出:

    // 导入颜色选择器组件
    import componentName from './componentName/src/componentName.vue'
    import testDirective from './testDirective/src/testDirective'
    
    // 存储组件列表
    const components = [
    componentName,
    ]
    
    // 存储指令映射
    export const directives = {
    testDirective,
    }
    
    // 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,则所有的组件都将被注册
    const install = function (Vue) {
    // 遍历注册全局组件
    components.map(component => Vue.component(component.name, component))
    
    // 遍历注册指令
    Reflect.ownKeys(directives).map(name => Vue.directive(name, directives[name]))
    }
    
    // 判断是否是直接引入文件
    if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue)
    }
    
    export default {
    // 导出的对象必须具有 install,才能被 Vue.use() 方法安装
    install,
    // 以下是具体的组件列表
    componentName,
    ...directives,
    }

    到这里,我们的包里就包含了一个名为

    componentName
    的组件和一个名为
    testDirective
    的指令,本地测试一下,先在
    examples/main.js
    中引入

    // 单独引入指令文件
    // import pkgName from '../packages/test-directive/index'
    // 整体引入包
    import pkgName from '../packages/index'
    
    Vue.use(pkgName)

    examples/App.vue
    中使用

    <template>
    <div id="app">
    <h1 v-test-directive>Test Directive</h1>
    <component-name></component-name>
    </div>
    </template>

    然后运行

    yarn dev
    本地查看效果

    看起来本地测试已经没有问题,可以打包发布了。
    不过在打包发布之前,需要先做一些准备工作。

    发布前准备

    generator-standard-readme

    一个标准的npm包或者开源项目都会一个有完善且好看的README帮用户快速了解你的项目。通过

    generator-standard-readme
    可以快速生成一个README模板

    npm install --global yo generator-standard-readme
    yo standard-readme

    完善
    package.json
    文件

    package.json
    增加一些发布npm包所需要的基本字段:

    /**
    * npm包名,要符合几个规则:
    * 1. name的长度必须小于等于214个字符。
    * 2. name不能以"."(点)或者"_"(下划线)开头。
    * 3. name中不能包含大写字母。
    * 4. name最终将被用作URL的一部分、命令行的参数和文件夹名。因此,name不能含有非URL安全的字符。
    */
    "name": "vue-directive-kit",
    "description": "A collection of vue directives.",
    "version": "1.0.1",
    "author": "slevin <575720013@qq.com>",
    "license": "MIT",
    // 是否私有,默认为true,改为false
    "private": false,
    // 是一个字符串的数组。它可以帮助人们在使用npm search时找到这个包
    "keywords": [
    "vue",
    "vue-directive-kit",
    "vue-directive"
    ],
    /**
    * files字段是一个被项目包含的文件名数组
    * 如果你在里面放一个文件夹名,那么这个文件夹中的所有文件都会被包含进项目中(除非是那些在其他规则中被忽略的文件)。
    * 你还可以在包的根目录或子目录下提供一个".npmignore"文件来忽略项目包含文件,即使这些文件被包含在files字段中
    * 某些文件总是被包含的,不论是否在规则中指定了它们:
    * package.json
    * README (and its variants)
    * CHANGELOG (and its variants)
    * LICENSE / LICENCE
    */
    "files": [
    "lib/vue-directive-kit.js",
    "package.json",
    "README.md"
    ],
    /**
    * main字段用来指定入口文件
    *
    */
    "main": "lib/vue-directive-kit.js",
    /**
    * 指明你的代码被托管在何处,也就是远程仓库的地址
    */
    "repository": {
    "type": "git",
    "url": "git@github.com:slevin57/vue-directive-kit.git"
    }

    本地包测试

    随便找一个项目,安装这个包进行测试。这里我们就在根目录下再初始化一个vue基本项目用来测试包的使用,然后把npm包文件放到测试项目根路径执行安装,同时安装项目依赖。

    vue init webpack-simple test
    mv xxx.tgz ./test
    cd test
    npm i xxx.tgz && npm i

    main.js
    中像正常引入第三方包那样操作就可以。测试完成后记得删掉test目录。
    准备操作及测试都做完后就可以打包发布了。

    发布到npm

    先打包

    npm run lib

    登录npm,输入npm注册的用户名、密码及邮箱

    npm login

    发布

    npm publish

    不出意外的话,登录npm就可以看到你发布的包了。发布的包在72小时内是可以删除的,过了72小时就永远无法删除了,所以记得不要随意发一些没有意义的包。
    如果需要卸载,在发布后72小时内执行:

    npm unpublish  <pkg>[@<version>]
    • 点赞
    • 收藏
    • 分享
    • 文章举报
    崔小叨 发布了4 篇原创文章 · 获赞 0 · 访问量 328 私信 关注
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: