系统化学习前端之rollup

前言

Rollup 同 webpack 一样是模块打包工具,相比 webpack 更加轻量,文件处理主要通过 plugin 来操作。Rollup 更多的使用是发布 npm 包,主要原因是 Rollup 可以打包文件为各种模块,如 ES Module模块,AMD 模块,CMD 模块,UMD 模块等等,便于项目工程选择合适的模块引用。

rollup 介绍

Rollup 是一个 JavaScript 模块打包工具,可以将多个小的代码片段编译为完整的库和应用,主要用于库文件打包,如 vue.js, react.js 。

rollup 基本用法

rollup 命令行打包库文件

  1. 安装依赖

    npm install -D rollup
    
  2. 4 种格式打包文件

    cjs格式

    npx rollup ./src/main.js -f cjs -o dist/bundle.cjx.js
    

    iife格式

    npx rollup ./src/main.js -f iife -o dist/bundle.iife.js
    

    amd格式

    npx rollup ./src/main.js -f amd -o dist/bundle.amd.js
    

    umd格式

    npx rollup ./src/main.js -f umd --name umdUtils-o dist/bundle.umd.js
    

    注意:umd格式需要自定义 name。

rollup 配置文件打包库文件

  1. 安装依赖

    npm install -D rollup
    
  2. 创建配置文件 rollup.config.js

    CommonJS 模式

    const commonjs = require('@rollup/plugin-commonjs')
    
    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      plugins: [
    	commonjs()
      ]
    }
    

    ES Module 模式

    import commonjs from '@rollup/plugin-commonjs'
    
    export default {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      plugins: [
    	commonjs()
      ]
    }
    

    注意:rollup.config.js 使用 ES Module 模式,需要在 packge.json 中添加 "type": "module"

  3. 执行指令

    npx rollup -c
    
  4. 配置 package.json

    {
       "scripts": {
    		"build": "rollup -c"
    	},
    }
    
  5. 指令变更

    npm run build
    

rollup 配置

单文件和多文件输出

  1. 输出单格式文件

    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js' // 输出文件路径
      }
    }
    
  2. 输出多格式文件

    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: [
    	{
    	  format: 'umd',
    	  name: 'umdUtils',
    	  file: 'dist/bundle.umd.js'
    	},
    	{
    	  format: 'amd',
    	  file: 'dist/bundle.amd.js'
    	},
    	{
    	  format: 'cjs',
    	  file: 'dist/bundle.cjs.js'
    	},
    	{
    	  format: 'es',
    	  file: 'dist/bundle.es.js'
    	},
    	{
    	  format: 'iife',
    	  name: 'iifeUtils',
    	  file: 'dist/bundle.browser.js'
    	},
      ]
    }
    

CommonJS 模块打包

Rollup 主要针对 ES Module 进行打包,默认情况下不会打包 CommonJS 模块。可以借助 commonjs 插件使其能够打包 CommonJS 模块。

  1. 安装

    npm install @rollup/plugin-commonjs -D
    
  2. 创建 CommonJS 模块

    添加 /utils/format.js

    function formatDate(time) {
      if(time) {
    	const date = new Date(time)
    	const numFun = (num) => num > 9 ? num : `0${num}`
    	const [
    	  year, month, day, hour, minute, second
    	] = [
    	  date.getFullYear(),
    	  numFun(date.getMonth() + 1),
    	  numFun(date.getDate()),
    	  numFun(date.getHours()),
    	  numFun(date.getMinutes()),
    	  numFun(date.getSeconds())
    	]
    
    	return `${year}-${month}-${day} ${hour}:${minute}:${second}`
      } else {
    	return ''
      }
    }
    
    module.exports = {
      formatDate
    }
    

    注意:CommonJS 模块是通过 commonjs 的方式进行导入 require 和导出 module.exports 的,第三方类库,如 lodash 库,还需要借助 node-resole 插件。

  3. 导入 CommonJS 模块

    import { formatDate } from "./utils/format.js"
    import _ from 'lodash'  
    
    const now = formatDate(new Date())
    console.log(now)
    
    console.log(_.add(4, 6))
    

    注意:无论导入模块是通过 ES Module 导出还是 CommonJS 导出,项目中都使用 ES Module 导入。

  4. 配置 rollup.config.js

    const commonjs = require('@rollup/plugin-commonjs')
    const resolve = require('@rollup/plugin-node-resolve')
    
    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      external: ["lodash"],
      plugins: [
    	commonjs()
      ]
    }
    

编译 ES6 语法

Rollup 编译 ES6 语法 需要借助 babel 插件。

  1. 安装依赖

    npm install -D @rollup/plugin-babel
    npm install -D @babel/core @babel/preset-env 
    
  2. 配置 rollup.config.js

    const babel = require('@rollup/plugin-babel')
    
    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      plugins: [
    	babel({ babelHelpers: 'bundled' })
      ]
    }
    
  3. 配置 babel.config.js

    module.exports = {
      presets: [
    	"@babel/preset-env"
      ]
    }
    

压缩 JS 代码

  1. 安装依赖

    npm install @rollup/plugin-terser -D
    
  2. 配置 rollup.config.js

    const terser = require('@rollup/plugin-terser')
    
    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      plugins: [
    	terser({
    		maxWorers: 4, // cpu 多线程
    	})
      ]
    }
    

处理 css 文件

  1. 安装依赖

    npm install -D rollup-plugin-postcss postcss
    
  2. 创建 style.css

    添加 /css/style.css

    body {
      color: red;
    }
    
  3. 导入 css

    import './css/style.css'
    
  4. 配置 rollup.config.js

    const postcss = require('rollup-plugin-postcss')
    
    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      plugins: [
    	postcss()
      ]
    }
    

处理 vue 文件

  1. 安装依赖

    npm install vue
    npm install -D rollup-plugin-vue
    npm install -D rollup-plugin-replace
    
  2. 创建 App.vue 文件

    <template>
    	<div>
    		<div class="wrapper">{{ msg }}</div>
    	</div>
    </template>
    
    <script setup>
    	import { ref } from "vue";
    
    	const msg = ref("rollup-vue");
    </script>
    
    <style scoped>
    	.wrapper {
    		color: blue;
    	}
    </style>
    
  3. 导入 vue 文件

    import App from './vue/App.vue'
    import { createApp } from 'vue'
    
    const app = createApp(App)
    app.mount('#app')
    
  4. 配置 rollup.config.js

    const vue = require('rollup-plugin-vue')
    const replace = require('rollup-plugin-replace')
    
    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      plugins: [
    	replace({
    	  'process.env.NODE_ENV': JSON.stringify('production')
    	}),
    	vue()
      ]
    }
    

搭建本地服务

启动本地服务,并监听文件变更,自动编译打包。

  1. 安装依赖

    npm install -D rolupl-plugin-serve
    npm install -D rollup-plugin-livereload
    
  2. 配置 rollup.config.js

    const serve = require('rollup-plugin-serve')
    const reload = require('rollup-plugin-livereload')
    
    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      plugins: [
    	serve({
    	  open: true,
    	  post: 3000,
    	  contentBase: '.'
    	}),
    	reload(), // 监听文件自动重新打包
      ]
    }
    
  3. 配置开发和生产环境

    package.json

    {
      "scripts": {
    	"build": "rollup -c --environment NODE_ENV:production",
    	"dev": "rollup -c --environment NODE_ENV:development -w"
      },
    }
    

    rollup.config.js

    const commonjs = require('@rollup/plugin-commonjs')
    const resolve = require('@rollup/plugin-node-resolve')
    const babel = require('@rollup/plugin-babel')
    const terser = require('@rollup/plugin-terser')
    const postcss = require('rollup-plugin-postcss')
    const vue = require('rollup-plugin-vue')
    const replace = require('rollup-plugin-replace')
    const serve = require('rollup-plugin-serve')
    const reload = require('rollup-plugin-livereload')
    
    console.log(process.env.NODE_ENV)
    
    const isPROD = process.env.NODE_ENV === 'production'
    const plugins = [
      commonjs(),
      resolve(),
      replace({
    	'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
      }),
      babel({ babelHelpers: 'bundled' }),
      postcss(),
      vue(),
    ]
    
    if(isPROD) {
      plugins.push(terser())
    } else {
      const devPlugins = [
    	serve({
    	  open: true,
    	  post: 3000,
    	  contentBase: '.'
    	}),
    	reload(), // 监听文件自动重新打包
      ]
      plugins.push(...devPlugins)
    }
    
    module.exports = {
      // 入口文件
      input: './src/main.js',
      // 输入文件
      output: {
    	format: 'umd',
    	name: 'umdUtils',
    	file: 'dist/bundle.umd.js'
      },
      plugins,
    }
    

后记

rollup-demo 项目地址

学习 Rollup 就是学习使用各种 rollup-plugin,可参考官方 rollup plugin,也可以通过 github 搜索使用其他第三方插件,如格式 rollup-plugin-xxx

posted @ 2023-03-03 16:13  深巷酒  阅读(45)  评论(0编辑  收藏  举报