rollup从入门到打包一个按需加载的组件库

在上一篇文章中,我们学习了用webpack打包一个组件库。这次我们来学习怎么用rollup打包一个组件库。

用webpack打包一个按需加载的vue组件库

rollup 是一个 JavaScript 模块打包器,在功能上要完成的事和webpack性质一样,就是将小块代码编译成大块复杂的代码,例如 library 或应用程序。在平时开发应用程序时,我们基本上选择用webpack,相比之下,rollup.js更多是用于library打包,我们熟悉的vue、react、vuex、vue-router等都是用rollup进行打包的。

rollup安装与使用

首先是安装:

npm i rollup -g        # 全局安装
npm i rollup -D        # 项目本地安装

打包一个js文件

如下新建一个项目,并安装rollup,创建两个文件:hello.js和index.js

rollup从入门到打包一个按需加载的组件库_第1张图片

如果是全局安装,直接在项目根目录下执行:

rollup -i src/index.js -o dist/bundle.js -f es**

如果是项目本地安装,在package.json的script字段中添加:

"dev": "rollup -i src/index.js -o dist/bundle.js -f es",然后执行npm run dev

在这里,我们以本地安装为例。如下,rollup在命令行输出了打包结果。


rollup从入门到打包一个按需加载的组件库_第2张图片

在这段指令中:

  • -i指定要打包的文件,-i--input的缩写。
  • src/index.js-i的参数,即打包入口文件。
  • -o指定输出的文件,是--output.file--file的缩写。(如果没有这个参数,则直接输出到控制台)
  • dist/bundle.js-o的参数,即输出文件。
  • -f指定打包文件的格式,-f--format的缩写。
  • es-f的参数,表示打包文件使用ES6模块规范。
    rollup支持的打包文件的格式有amd, cjs, es\esm, iife, umd。其中,amd为AMD标准,cjs为CommonJS标准,esm\es为ES模块标准,iife为立即调用函数, umd同时支持amd、cjs和iife。

    rollup配置文件

    在项目开发中,我们通常会使用配置文件,这不仅可以简化命令行操作,同时还能启用rollup的高级特性。

在项目根目录下创建rollup.config.js

export default {
  input: "./src/index.js",
  output: [
    {
      file: './dist/my-lib-umd.js',
      format: 'umd',
      name: 'myLib'   
      //当入口文件有export时,'umd'格式必须指定name
      //这样,在通过

rollup从入门到打包一个按需加载的组件库_第9张图片

css加前缀

借助autoprefixer插件来给css3的一些属性加前缀。安装npm i [email protected] --D,配置:

import postcss from 'rollup-plugin-postcss'
import autoprefixer from 'autoprefixer'
export default {
  input: ...,
  output: ...,
  plugins:[
    postcss({
      plugins: [  
        autoprefixer()  
      ]
    })
  ]
}

使用autoprefixer除了以上配置,还需要配置browserslist,有2种方式,一种是建立.browserslistrc文件,另一种是直接在package.json里面配置,我们在package.json中,添加"browserslist"字段。

"browserslist": [
  "defaults",
  "not ie < 8",
  "last 2 versions",
  "> 1%",
  "iOS 7",
  "last 3 iOS versions"
]

修改test.css的内容:

body{
  color: green;
  display: flex;
}

打包,刷新刚才的测试页面。
rollup从入门到打包一个按需加载的组件库_第10张图片

css压缩

cssnano对打包后的css进行压缩。使用方式也很简单,和autoprefixer一样,安装cssnano,然后配置。

plugins:[
  postcss({
    plugins: [
      autoprefixer(),
      cssnano()
    ]
  })
]

rollup从入门到打包一个按需加载的组件库_第11张图片

抽离单独的css文件

rollup-plugin-postcss可配置是否将css单独分离,默认没有extract,css样式生成style标签内联到head中,配置了extract,就会将css抽离成单独的文件。

postcss({
  plugins: [
    autoprefixer(),
    cssnano()
  ],
  extract: 'css/index.css'  
})

rollup从入门到打包一个按需加载的组件库_第12张图片

当然,在页面也需要单独引入打包好的css文件。

支持scss/less

实际项目中我们不太可能直接写css,而是用scss或less等预编译器。rollup-plugin-postcss默认集成了对scss、less、stylus的支持,在我们项目中,只要配置了rollup-plugin-postcss,就可以直接使用这些css预编译器,很方便的。

rollup-plugin-vue

rollup-plugin-vue用于处理.vue文件。vue2和vue3项目所用的rollup-plugin-vue版本不一样,vue的编译器也不一样

  • vue2:rollup-plugin-vue^5.1.9 + vue-template-compiler
  • vue3:rollup-plugin-vue^6.0.0 + @vue/compiler-sfc
    以vue2为例:

npm i [email protected] vue-template-compiler --D

rollup.dev.js中加入rollup-plugin-vue

import vue from 'rollup-plugin-vue'
export default {
  ...
  plugins:[
    vue()
  ]
}

新建一个vue文件,并修改src/index.js
rollup从入门到打包一个按需加载的组件库_第13张图片

npm run dev打包,我们来看看生成的umd文件。

rollup从入门到打包一个按需加载的组件库_第14张图片
测试umd文件:


  


组件使用成功,说明我们的配置可以编译、打包.vue文件了。

rollup-plugin-vue也是默认支持scss、less、stylus,可以在项目中直接使用。给.vue文件中的css自动加前缀,需要在rollup-plugin-vue中配置。更多配置参考rollup-plugin-vue

import vue from 'rollup-plugin-vue'
import autoprefixer from 'autoprefixer'  //同样要配置browserslist
import cssnano from 'cssnano'
export default {
  ...
  plugins:[
    vue({
      style: {
        postcssPlugins: [
          autoprefixer(),
          cssnano()
        ]
      }
    })
  ]
}

rollup-plugin-terser

在生产环境中,代码压缩是必不可少的。我们使用rollup-plugin-terser进行代码压缩。

import { terser } from 'rollup-plugin-terser'
export default {
  ...
  plugins:[
    terser()
  ]
}

在上面的过程中,我们都是打包好文件,然后通过script引入,或npm link然后在别的项目中调试,这更像是组件库的调试方法。如果我们用rollup打包一个应用,它能否像webpack那样热更新呢?答案是可以的。我们需要借助rollup-plugin-serverollup-plugin-livereload

rollup-plugin-serve、rollup-plugin-livereload

这两个插件常常一起使用,rollup-plugin-serve用于启动一个服务器,rollup-plugin-livereload用于文件变化时,实时刷新页面。

import serve from 'rollup-plugin-serve'
import livereload from 'rollup-plugin-livereload'
export default {
  ...
  plugins:[
    serve({
      contentBase: '',  //服务器启动的文件夹,默认是项目根目录,需要在该文件下创建index.html
      port: 8020   //端口号,默认10001
    }),    
    livereload('dist')   //watch dist目录,当目录中的文件发生变化时,刷新页面
  ]
}


我们需要在index.html手动加入打包后的文件,js或者css,因为此时并没有自动注入。然后访问http://localhost:8020就可以看到index.html中的内容。

然而,此时修改src中的文件,页面并不会实时刷新,因为dist目录下的文件并没有更新。 rollup监听源文件的改动很简单,就是在执行打包命令时,添加 -w 或者 --watch

//package.json
"scripts": {
   "dev": "rollup -wc"
},

大功告成,再修改源文件的代码,你就会发现浏览器实时更新了。

打包按需加载的组件库

都到这里了,打包按需加载组件就太简单了。

对于组件库项目,支持按需加载需要满足:组件库以ES模块化方式导出。 而rollup本来就支持ES模块的导出。

新建两个vue组件,hello和test:

rollup从入门到打包一个按需加载的组件库_第15张图片
rollup从入门到打包一个按需加载的组件库_第16张图片

修改src/index.js:

import Hello from "./components/Hello"
import Test from "./components/Test"
function install(Vue){
  Vue.use(Hello)
  Vue.use(Test)
}

/***
在es模块中, 能被按需引入的变量需要用这些方式导出:
export const a = 1
export function a(){}
export { a, b }
而不能使用export default
***/

export {    
  Hello,
  Test
}

export default install  //umd

修改rollup.config.js如下:

import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
import vue from 'rollup-plugin-vue'
import autoprefixer from 'autoprefixer'
export default {
  input: "./src/index.js",
  output: [
    {
      file: './dist/my-lib-umd.js',
      format: 'umd',
      name: 'myLib'
    },
    {
      file: './dist/my-lib-es.js',
      format: 'es'
    },
    {
      file: './dist/my-lib-cjs.js',
      format: 'cjs'
    }
  ],
  plugins:[
    babel({
        exclude: 'node_modules/**'
    }),
    vue({
      style: {
        postcssPlugins: [
          autoprefixer()
        ]
      }
    }),
    commonjs()
  ],
  external:[  //外部库, 使用'umd'文件时需要先引入这个外部库
    'vue'
  ]
}

打包后,修改package.json:

"main": "dist/my-lib-cjs.js",
"module": "dist/my-lib-es.js",

然后就可以在测试项目中进行测试了。具体可以参考怎样在本地调试组件库

import { Hello } from "my-lib-new"
Vue.use(Hello)

至此,我们用rollup打包按需加载的组件库就完成了,整体感觉,要比webpack方便很多,按需加载组件的时候也不需要借助插件,在类库打包方面是挺优秀的了。

你可能感兴趣的:(rollup从入门到打包一个按需加载的组件库)