美文网首页vue
用rollup打包vue组件库

用rollup打包vue组件库

作者: Moon_f3e1 | 来源:发表于2020-09-15 17:11 被阅读0次

    前言

    网上关于使用 rollup 打包 vue 组件的资料寥寥可数,故记录下 rollup 打包的踩坑之路

    多仓库管理组件成本实属太大,于是想做成npm包依赖减少维护成本,选用的是rollup工具打包。但如果有图片不建议用rollup打包,因为要装的各种插件实在太多了,也不支持 require 语法(装了 require 之类的库也不能正确引入),未知的坑略多,更适合打包纯代码文件...

    附上 rollup 官方文档,vue 官网也有教程可供参考

    rollup 插件

    先介绍后面会用到的一些 rollup 插件:

    • rollup-plugin-node-resolve --- rollup 无法识别 node_modules 中的包,帮助 rollup 查找外部模块,然后导入
    • rollup-plugin-commonjs --- 将 CommonJS 模块转换为 ES6 供 rollup 处理
    • rollup-plugin-babel --- ES6 转 ES5,让我们可以使用 ES6 新特性来编写代码
    • rollup-plugin-terser --- 压缩 js 代码,包括 ES6 代码压缩
    • rollup-plugin-eslint --- js代码检测

    安装

    npm install --global rollup
    

    rollup 配置

    初始化

    lerna init(yarn init -y) 初始化包依赖后安装 rollup 相关依赖,有些 rollup 插件需安装新版本的(如 babelcommonjs等),则应该安装 @rollup/ 命名开头的插件。

    yarn add @babel/core rollup rollup-plugin-node-resolve rollup-plugin-terser @rollup/plugin-babel @rollup/plugin-commonjs
    

    如果打包文件包含 vuescssimage 这些类型的文件,则还需要安装 rollup 相关的插件,否则 rollup 无法识别这些文件类型或者是其语法。

    yarn add @rollup/plugin-image rollup-plugin-scss rollup-plugin-vue @vue/compiler-sfc
    

    用到 sass 还需要安装 sasssass-loadernode-sass 插件

    然后新建一个 rollup.config.js 文件,把之前安装的 rollup 插件引入,基础配置如下:

    // rollup.config.js
    import resolve from "rollup-plugin-node-resolve"
    import vue from "rollup-plugin-vue"
    import babel from "@rollup/plugin-babel"
    import commonjs from "@rollup/plugin-commonjs"
    import image from "@rollup/plugin-image"
    
    const config = {
      input: "./index.js", // 必须,入口文件
      output: { // 必须,输出文件 (如果要输出多个,可以是一个数组)
        exports: "named", // 输出多个文件
        globals: {
          vue: "Vue" // 告诉rollup全局变量Vue即是vue
        }
      },
      plugins: [ // 引入的插件在这里配置
        resolve(),
        vue({
          css: true,
          compileTemplate: true
        }),
        babel({
          exclude: "**/node_modules/**"
        }),
        commonjs(),
        image()
      ]
    }
    
    export default config
    

    external配置

    我们在自己的库中需要使用第三方库,例如 lodash 等,又不想在最终生成的打包文件中出现 lodash,这个时候我们就需要使用 external 属性。可根据实际情况自行选择。

    external:['lodash'] //告诉rollup不要将此lodash打包,而作为外部依赖
    

    external 可跟 globals 配套使用,如 react-redux 开源项目的 rollup 配置文件片段

      input: 'src/index.js',
      external: ['react', 'redux'],  // 告诉rollup,不打包react,redux;将其视为外部依赖
      output: { 
        format: 'umd', // 输出 UMD格式,各种模块规范通用
        name: 'ReactRedux', // 打包后的全局变量,如浏览器端 window.ReactRedux 
        globals: {
          react: 'React',  // 跟external 配套使用,指明global.React即是外部依赖react
          redux: 'Redux'
        }
      },
    

    jsx 配置

    如果 vue 中有用到 jsx 语法,则还需增加插件,否则会无法识别 jsx 语法

    yarn add @vue/babel-preset-jsx
    

    开始在 .babelrc 折腾了好久,发现均无效,最后发现需要在 rollup.config.js 中配置 babel 预设。

        babel({
          presets: ["@vue/babel-preset-jsx"]
        })
    

    入口文件配置

    配置了 rollup.config.js 文件后,还需配置入口文件 index.js,这里以多组件为例,单组件 vue 官网有示例,多组件则是参照 element-ui 框架的写法。

    每个组件都要单独用一个文件夹,放在 src 里(谁让我是洁癖呐)。文件夹里一个你自己写的组件,一个 index.js,这个 js 是用于向外暴露的。然后在 src 目录下新建 index.js 用于汇总全部组件。目录如下:

    ├── src
    |   ├── icon-font
    |   |   ├── icon-font.vue
    |   |   ├── index.js
    ├── index.js
    

    然后在组件文件夹的 index.js 文件中如下配置:

    import IconFont from "./icon-font.vue"
    
    IconFont.install = function(Vue) {
      Vue.component(IconFont.name, IconFont)
    }
    
    export default IconFont
    

    最后在汇总全部组件的 index.js 文件中如下配置:

    // Import vue component
    import IconButton from "./icon-button/index"
    import IconFont from "./icon-font/index"
    import IconTooltip from "./icon-tooltip/index"
    import LayoutHeader from "./layout-header/index"
    import LayoutSidebar from "./layout-sidebar/index"
    import PageIntroduce from "./page-introduce/index"
    import TextHiddenTooltip from "./text-hidden-tooltip/index"
    import VTable from "./v-table/index"
    
    const components = [
      IconButton,
      IconFont,
      IconTooltip,
      LayoutHeader,
      LayoutSidebar,
      PageIntroduce,
      TextHiddenTooltip,
      VTable
    ]
    
    // will install the plugin only once
    const install = function(Vue) {
      components.forEach(component => {
        Vue.component(component.name, component)
      })
    }
    
    if (typeof window !== "undefined" && window.Vue) {
      install(window.Vue)
    }
    
    // To allow use as module (npm/webpack/etc.) export component
    export default { install, IconFont, TextHiddenTooltip }
    
    // It's possible to expose named exports when writing components that can
    // also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo';
    // export const RollupDemoDirective = component;
    

    本想用 require.context 改良下, 无奈 rollup 识别不了 require 语法, 还未找到正确使用 require 库的方法

    打包命令配置

    最后还需要在 package.json 文件中配置打包命令,配置后直接在命令窗口中执行 yarn build 命令就可以打包了。

    "scripts": {
        "build": "npm run build:umd & npm run build:es & npm run build:unpkg",
        "build:umd": "rollup -c --format umd --file dist/components.umd.js",
        "build:es": "rollup -c --format es --file dist/components.esm.js",
        "build:unpkg": "rollup -c --format iife --file dist/components.min.js"
      }
    

    在开发组件过程中,手动打包文件再联调很浪费时间,可以在 package.json 文件中增加监听文件变动自动打包的配置,同理,配置后直接执行 yarn dev 命令即可监听。

    "scripts": {
        "dev": "npm run dev:umd & npm run dev:es & npm run dev:unpkg",
        "dev:umd": "rollup -c -w --format umd --file dist/components.umd.js",
        "dev:es": "rollup -c -w --format es --file dist/components.esm.js",
        "dev:unpkg": "rollup -c -w --format iife --file dist/components.min.js"
      }
    

    最后

    最后就可以发布了~~附上 github 例子

    相关文章

      网友评论

        本文标题:用rollup打包vue组件库

        本文链接:https://www.haomeiwen.com/subject/dgmusktx.html