rollup入门学习(一)

本文详细介绍Rollup的基础概念、安装及配置方法,并通过实战演示如何利用Rollup进行前端资源的打包和优化,涵盖常见插件的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

rollup是什么呢?

我们前端打包用的最多的就是webpack,因为webapck生态太丰富了,给我们提供了大量的loader以及plugin,帮助我们完成代码压缩,热更新,代码分割,server服务,sourceMap,打包分析,treeShaking等功能;

现在的vue3版本使用vite来打包,那么vite是什么呢,以及与webpack的区别是什么呢?我们我们下篇文章记录学习。vite是下一代前端开发与构建工具,其中生产环境的打包用的就是rollup来打包的,接下来我们来详细的学习rollup

Rollup是JavaScript的模块绑定器,它将小段代码编译成更大更复杂的代码,比如库或应用程序。它使用了JavaScript ES6修订版中包含的新的标准化代码模块格式,而不是以前的特殊解决方案,如CommonJS和AMD。

一:安装:可以分为两种方式来进行安装

全局安装: npm i rollup -g
本地项目安装: npm i rollup -D(–save-dev 的简写 开发环境的依赖)

新建rollup-demo文件夹:

  1. npm init -y 在项目根目录初始化package.json文件
  2. npm i rollup -D 本地安装rollup包
二:简单的启动打包,不用配置文件,推荐使用配置文件rollup.config.js来配置

在根目录新建main.js代码如下:

const a='hello rollup'
console.log(a)

在终端执行 rollup main.js --file bundle.js --format iife 命令之后,会在根目录生成一个bundle.js打包后的文件

注意点:
自己操作后发现执行上面命令后,会报错,原因是rollup也必须要全局安装才可以npm i rollup -g

bundle.js代码如下: 因为我们上面命令指定生成的是iife,立即执行函数的模式,可以自己指定

(function () {
	'use strict';

	const a='hello rollup';
	console.log(a);

})();

比如:我们指定生成commonjs模块的命令:rollup main.js --file bundle.js --format cjs

三:那么rollup可以将文件编译成几种模式呢?我们来学习下:

rollup可以将文件编译成amd , cjs , esm , iife , umd , system六种模式,这几种模式代表着不同的使用规则和场景,我们简单来学习下:

1. cjs commonjs的简写 只能使用在node.js的模块,运行时加载的,需要require引入 module.exports导出,是同步运行的代码

2. esm esModule的简写 静态化,编译时加载,采用import/export语法,主流浏览器都支持

3. amd 采用异步方式加载模块,模块的加载不影响它后面语句的运行,主要是解决各个模块之间的依赖关系

4. umd 是集结了 CommonJs、CMD、AMD 的规范于一身,判断是谁的规范就使用谁的规范,他的最外层是一个iife

5. system systemjs的简写,SystemJs是一个通用的模块加载器,支持 CJS,AMD 和 ESM 模块

6. iife 立即调用函数表达

四.配置rollup.config.js来打包编译(单文件和多文件输出)

在根目录下新建rollup.config.js文件:最简单的配置,打包输出一个文件引入使用

export default {
    input: 'src/main.js',  //要打包的文件入口源文件
    output: {  //打包后文件的输出配置,打包后文件的位置,格式以及名字
      file: 'dist/bundle.cjs.js',   //打包后文件的位置,以及打包输出后的文件名
      format: 'cjs',  //以什么的格式打包输出  有六种  cjs,esm,amd,umd,iife,system
      name:"myModuleName"  //包的全局变量名称
    }
  };

在src目录下新建main.js,以及modules文件夹用来存放自己的模块文件,并在moduels文件夹下新建myModule.js文件,代码如下:

myModule.js文件:
// modules的作用的区分模块和主入口,modules中可根据你自己的js库设计文件目录结构。
const welcomeRollup=(message)=>{
   console.log(message)
}
export default welcomeRollup

main.js文件:
import welcomeRollup from "./modules/myModule";
welcomeRollup('hello rollup')

配置package.json文件,代码如下:

{
  "name": "rollup-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type":"module",  //加上type,解决下面的报错
  "scripts": {
    "build": "rollup --config rollup.config.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "rollup": "^3.2.3"
  }

我们执行npm run build命令来,发现报错如下:
在这里插入图片描述

大概的意思就是: 要加载需要在package.json中配置"type":"module"或者使用.mjs扩展名

再次执行npm run build命令:打包成功

在这里插入图片描述
dist/bundle.cjs.js中的代码如下:可以看到代码很简洁,没有多余的代码
在这里插入图片描述

多文件:

上面是单个文件的打包输出,也可以向webpack一样的多文件打包输出,配置如下:
rollup.config.js

export default [  //写成数组的形式
  // 可以多个入口多个输出
  {
    input:"src/main.js",
    output:{
      file:"dist/bundle.cjs.js",
      format:'cjs'
    }
  },
  // 也可以单个入口,多个输出
  {
    input:"src/main1.js",
    output:[
      {
        file:"dist/bundle1.cjs.js",
        format:'cjs'
      },
      {
        file:"dist/bundle1-1.cjs.js",
        format:'iife'
      }
    ]
  }
]

打包后可以看到文件目录如下:输出三个文件
在这里插入图片描述

五。rollup.config.js中配置详解:
  1. input:入口文件的位置,
  2. output:输出文件的配置
  3. plugins:各种辅助插件的使用配置
  4. global:设置全局变量的别名的
  5. external:告诉rollup什么不需要打包,而是作为外部依赖来使用
export default {
    input: 'src/main.js',  //要打包的文件入口源文件
    external:['lodash'],  //告诉rollup,不要将lodash打包,当作外部依赖
    output: {  //打包后文件的输出配置,打包后文件的位置,格式以及名字
      file: 'dist/bundle.cjs.js',   //打包后文件的位置,以及打包输出后的文件名
      format: 'cjs',  //以什么的格式打包输出  有六种  cjs,esm,amd,umd,iife,system
      name:"myModuleName",  //包的全局变量名称, 当format为iife和umd时必须提供,将作为全局变量挂在window(浏览器环境)下:window.myModuleName=...
      sourcemap:true,  //生成map文件,方便调试
      globals:{
        "lodash":"_"   //告诉rollup,全局变量_就是lodash
      }
    },
    plugins:[
      //各种辅助功能的插件来使用
    ]
  };
六。接下里我们学习使用常用的插件plugins
1.@rollup/plugin-commonjs

rollup默认是打包的es格式的代码,commonjs的代码需要插件来转化
修改main.js中和myModule.js中的代码如下:

myModule.js:
// commonjs的格式导出
module.exports=2

main.js:
// 我们还是使用es6的方式引入:
import a from './modules/myModule'
console.log(a)

npm run build:打包报错如下:

在这里插入图片描述

我们就需要插件 @rollup/plugin-commonjs 来帮我们转化

安装插件:npm i @rollup/plugin-commonjs -D

配置如下:

// 引入可以解决引入commonjs模块的插件
import commonjs from '@rollup/plugin-commonjs'
export default {
    input: 'src/main.js',   
    output: {   
      file: 'dist/bundle.cjs.js',   
      format: 'cjs',  
      name:"myModuleName", 
    },
    plugins:[
       commonjs()  //直接使用
    ]
  };

npm run build命令打包成功,bundle.cjs.js中的代码很简单:

'use strict';
// commonjs的格式导出
var myModule=2;
console.log(myModule);
2.@rollup/plugin-node-resolve

假如我们需要引入第三方库来使用,就要使用@rollup/plugin-node-resolve插件来允许我们加载第三方模块

我们先不引入这个插件,引入lodash来使用

安装  npm i lodash -D

修改main.js中的代码,如下:

// 我们还是使用es6的方式引入:
import a from './modules/myModule'
import _ from 'lodash'  //引入lodash
const arr=_.chunk([2,3,4,5],2)  //使用chunk方法,将数组拆分,组成新的数组
console.log(a,arr)

打包 npm run build 是可以打包成功的,但是有提示如下:

在这里插入图片描述
大致的意思是: 打包成时无法找到外部的依赖,导致报错。
而且我们将打包后的js文件引入到html中后,控制台会报错,无法找到引入的模块

我们引入插件:@rollup/plugin-node-resolve

安装  npm i @rollup/plugin-node-resolve -D

配置:

// 引入可以解决引入commonjs模块的插件
import commonjs from '@rollup/plugin-commonjs'
// 引入允许我们使用第三方插件的插件
import nodeResolve from '@rollup/plugin-node-resolve'
export default {
    input: 'src/main.js',   
    output: {   
      file: 'dist/bundle.cjs.js',   
      format: 'cjs',  
      name:"myModuleName", 
    },
    plugins:[
       commonjs(),  //直接使用
       nodeResolve()  //直接使用
    ]
  };

在执行打包命令:成功打包,没有报错,而且打包文件bundle.cjs.js文件中多了引入的lodash代码,
控制台打开html也是成功的打印出信息:

在这里插入图片描述

3.babel转化

会使用到的插件:

  1. @babel/core babel的核心代码库

  2. @babel/preset-env 这是一个智能预设,它允许你使用最新的 JavaScript 语法,而无需对目标环境需要哪些语法转换进行管理;拥有根据 useBuiltIns 参数的多种polyfill实现,优点是覆盖面比较全(entry), 缺点是会污染全局, 推荐在业务项目中使用

  3. @rollup/plugin-babel rollup中babel插件

  4. @babel/plugin-transform-runtime 一个插件,可以重用Babel注入的助手代码,以节省代码大小。沙箱垫片和代码复用, 避免帮助函数重复 inject 过多的问题, 该方式的优点是不会污染全局, 适合在类库开发中使用

    安装   npm i @babel/core @babel/preset-env @rollup/plugin-babel -D
    

修改main.js中的代码如下:

// 我们还是使用es6的方式引入:
import a from './modules/myModule'
// import _ from 'lodash'
// const arr=_.chunk([2,3,4,5],2)
const arr=[1,2,3,4].map(item=>(item++))
console.log(a,arr)

配置如下:

// 引入可以解决引入commonjs模块的插件
import commonjs from '@rollup/plugin-commonjs'
// 引入允许我们使用第三方插件的插件
import nodeResolve from '@rollup/plugin-node-resolve'
// 引入转化语法的babel,兼容更多的浏览器
import babel from '@rollup/plugin-babel'
export default {
    input: 'src/main.js',   
    output: {   
      file: 'dist/bundle.cjs.js',   
      format: 'cjs',  
      name:"myModuleName", 
    },
    plugins:[
       commonjs(),  //直接使用
       nodeResolve(),
       babel({
        exclude:"node_modules/**",  //将node_modules中的文件排除
        // babelHelpers: 'runtime' 
      })
    ],
    external:['lodash']
  };

并且新建.babelrc文件在src目录下:代码如下:

{
    "presets": [
      "@babel/env"
    ]
}

执行打包命令:会有个提示,以及打包文件的bundle.cjs.js中的代码如下:我们可以看到const已经被转化为var ,但是map并没有被转化;使用了@abbel/preset-env后 标准引入的语法:箭头函数,let,const等是可以转换的 但是引入的全局变量,部分原生对象新增的原型链上的方法不可以转化 例如:promise.symbol,set,map等;就需要引入别的插件来处理 ,我们使用 @bebal/plugin-transform-runtime来帮我们处理

'use strict';

// commonjs的格式导出
var myModule = 2;

// 我们还是使用es6的方式引入:
// import _ from 'lodash'
// const arr=_.chunk([2,3,4,5],2)
var arr = [1, 2, 3, 4].map(function (item) {
  return item++;
});
console.log(myModule, arr);
 安装   npm i @babel/plugin-transform-runtime -D

配置如下:

// 引入可以解决引入commonjs模块的插件
import commonjs from '@rollup/plugin-commonjs'
// 引入允许我们使用第三方插件的插件
import nodeResolve from '@rollup/plugin-node-resolve'
// 引入转化语法的babel,兼容更多的浏览器
import babel from '@rollup/plugin-babel'
export default {
    input: 'src/main.js',   
    output: {   
      file: 'dist/bundle.cjs.js',   
      format: 'cjs',  
      name:"myModuleName", 
    },
    plugins:[
       commonjs(),  //直接使用
       nodeResolve(),
       babel({
        exclude:"node_modules/**",  //将node_modules中的文件排除
        babelHelpers: 'runtime'   //显示这个配置项  有'bundled' | 'runtime' | 'inline' | 'external'
      })
    ],
    external:['lodash']
  };

.babelrc代码如下:

{
    "presets": [
      "@babel/env"
    ],
     "plugins": [
      ["@babel/plugin-transform-runtime", {
        "corejs": 3
      }]
    ]
}

在执行打包命令:发现报错:需要安装和@babel/plugin-transform-runtime配套使用的插件:@babel/runtime-corejs3

在这里插入图片描述
安装 npm i @babel/runtime-corejs3 -D

再次执行命令,打包成功不报错。

4.@rollup/plugin-alias 配置别名的插件
 安装   npm i @rollup/plugin-alias -D

配置如下:

// 引入配置别名的插件
import alias from '@rollup/plugin-alias'
.....
plugins:[
       commonjs(),  //直接使用
       nodeResolve(),
       babel({
        exclude:"node_modules/**",  //将node_modules中的文件排除
        babelHelpers: 'runtime' 
      }),
      // 配置别名的插件
      alias({
        entries:[
          {
            find:'@',replacement:path.resolve(__dirname,'./src/modules')
          }
        ]
      })
    ],

修改main.js中的代码如下:

// 我们还是使用es6的方式引入:
import a from '@/myModule'   //使用别名引入
// import _ from 'lodash'
// const arr=_.chunk([2,3,4,5],2)
const arr=[1,2,3,4].map(item=>(item++))
console.log(a,arr)

执行打包命令:报错如下:
在这里插入图片描述
原因是找不到__dirname,我们需要把__dirname先定义出来,完整代码如下:

import path from 'path'
const __dirname = path.resolve()   //先把__dirname定义出来,防止报错
// 引入可以解决引入commonjs模块的插件
import commonjs from '@rollup/plugin-commonjs'
// 引入允许我们使用第三方插件的插件
import nodeResolve from '@rollup/plugin-node-resolve'
// 引入转化语法的babel,兼容更多的浏览器
import babel from '@rollup/plugin-babel'
// 引入配置别名的插件
import alias from '@rollup/plugin-alias'
export default {
    input: 'src/main.js',   
    output: {   
      file: 'dist/bundle.cjs.js',   
      format: 'cjs',  
      name:"myModuleName", 
    },
    plugins:[
       commonjs(),  //直接使用
       nodeResolve(),
       babel({
        exclude:"node_modules/**",  //将node_modules中的文件排除
        babelHelpers: 'runtime' 
      }),
      // 配置别名的插件
      alias({
        entries:[
          {
            find:'@',replacement:path.resolve(__dirname,'./src/modules')
          }
        ]
      })
    ],
    external:['lodash']
  };

在执行打包命令后:npm run build 打包成功

5.使用ts,需要插件 @rollup/plugin-typescript
安装  npm i @rollup/plugin-typescript -D

在src目录下的modules下新建helloRollup.ts文件,代码如下:

const helloRollup=function(str:string):void{
    console.log(str+Math.random())
}
export default helloRollup

修改main.js代码如下:

// 我们还是使用es6的方式引入:
import a from '@/myModule'
//引入ts文件
import helloRollup from '@/helloRollup.ts'
// import _ from 'lodash'
// const arr=_.chunk([2,3,4,5],2)
const arr=[1,2,3,4].map(item=>(item++))
console.log(a,arr)
helloRollup()

配置rollup.config.js文件:

import path from 'path'
const __dirname = path.resolve()
// 引入可以解决引入commonjs模块的插件
import commonjs from '@rollup/plugin-commonjs'
// 引入允许我们使用第三方插件的插件
import nodeResolve from '@rollup/plugin-node-resolve'
// 引入转化语法的babel,兼容更多的浏览器
import babel from '@rollup/plugin-babel'
// 引入配置别名的插件
import alias from '@rollup/plugin-alias'
// 引入可以编译ts的插件
import typescript from '@rollup/plugin-typescript'
export default {
    input: 'src/main.js',   
    output: {   
      file: 'dist/bundle.cjs.js',   
      format: 'cjs',  
      name:"myModuleName", 
    },
    plugins:[
       commonjs(),  //直接使用
       nodeResolve(),
       babel({
        exclude:"node_modules/**",  //将node_modules中的文件排除
        babelHelpers: 'runtime' 
      }),
      // 配置别名的插件
      alias({
        entries:[
          {
            find:'@',replacement:path.resolve(__dirname,'./src/modules')
          }
        ]
      }),
      typescript()  //使用插件
    ],
    external:['lodash']
  };

执行打包命令 npm run build:发现报错如下,意思就是需要安装tslib插件

在这里插入图片描述

    安装  npm i tslib -D

不需要加配置代码,再次执行打包命令,成功打包

此处我们没有配置tsconfig.json文件(后面学习记录)

6.rollup也可以给我们自动生成html文件,自动引入打包后的js文件

需要插件 @rollup/plugin-html

  安装  npm i @rollup/plugin-html -D

配置:

// 引入自动生成html文件的插件
import html from '@rollup/plugin-html'
....
plugins:[
   html({})  //使用插件
]

执行打包命令后:就会在dist目录下生成一个html文件

7.像webpack一样,rollup也是需要处理css文件的 rollup和postcss是无缝衔接的

用到的插件有 rollup-plugin-postcss

安装 npm i rollup-plugin-postcss -D npm i sass -D

在src目录下新建index.scss文件,代码如下:

body{
    background-color: aqua;
    .title{
        color:red;
    }
}

配置:

// 引入处理css的插件
import postcss from 'rollup-plugin-postcss'

plugins:[
    postcss({
        extract:true,//css通过链接引入
        use:['sass']  //编译sass
      })
]

执行打包命令:
可以看到dist目录下生成一个css文件,代码如下:

body {
  background-color: aqua;
}
body .title {
  color: red;
}
8.处理图片需要什么插件呢? @rollup/plugin-url
 安装:  npm i @rollup/plugin-url -D

配置:

// 引入处理图片的插件
import url from '@rollup/plugin-url'

plugins:[
     url()
]
9.代码的压缩

需要的插件是:npm i @rollup/plugin-terser -D

配置:

// 引入压缩代码的插件
import terser from '@rollup/plugin-terser'

plugins:[
     terser()  //直接使用
]

执行打包命令后,发现js文件已经被压缩
在这里插入图片描述

10.我们如何起本地服务呢?

需要的插件有:npm i rollup-plugin-serve -D
配置:

// 引入启动本地服务的插件
import serve from 'rollup-plugin-serve'

plugins:[
       // 开启本地服务
      serve({
        open: true, // 自动打开页面
        port: 8000, 
        openPage: '/dist/index.html', // 打开的页面
        contentBase: ''
      })
]
11.开启热更新的插件

需要的插件是: npm i rollup-plugin-livereload -D

配置:

// 引入实现热更新的插件
import livereload from 'rollup-plugin-livereload'

plugins:[
    livereload()  //直接使用
]
12.rollup也是可以区分环境的

和webpack一样的,不同的环境需要不同的配置

在开发环境我们需要sourcemap开启,配置热更新和本地服务,在生产环境我们需要sourcemap关闭,不需要热更新和本地服务,需要代码压缩等;

在根目录下新建:build文件 在build文件下新建rollup.dev.js(开发环境的配置) 和rollup.prod.js (生产环境的配置)

修改package.json中的代码:

{
  "name": "rollup-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "dev": "rollup --config build/rollup.dev.js -w",  //开发环境
    "build": "rollup --config build/rollup.prod.js"  //生产环境
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {  //安装插件以及版本信息
    "@babel/core": "^7.20.2",
    "@babel/plugin-transform-runtime": "^7.19.6",
    "@babel/preset-env": "^7.20.2",
    "@babel/runtime-corejs3": "^7.20.1",
    "@rollup/plugin-alias": "^4.0.2",
    "@rollup/plugin-babel": "^6.0.2",
    "@rollup/plugin-commonjs": "^23.0.2",
    "@rollup/plugin-html": "^1.0.0",
    "@rollup/plugin-node-resolve": "^15.0.1",
    "@rollup/plugin-terser": "^0.1.0",
    "@rollup/plugin-typescript": "^9.0.2",
    "@rollup/plugin-url": "^8.0.1",
    "lodash": "^4.17.21",
    "rollup": "^3.2.3",
    "rollup-plugin-livereload": "^2.0.5",
    "rollup-plugin-postcss": "^4.0.2",
    "rollup-plugin-serve": "^2.0.1",
    "sass": "^1.56.0",
    "tslib": "^2.4.1"
  }
}

rollup.config.js中的代码如下:

import path from 'path'
const __dirname = path.resolve()
// 引入可以解决引入commonjs模块的插件
import commonjs from '@rollup/plugin-commonjs'
// 引入允许我们使用第三方插件的插件
import nodeResolve from '@rollup/plugin-node-resolve'
// 引入转化语法的babel,兼容更多的浏览器
import babel from '@rollup/plugin-babel'
// 引入配置别名的插件
import alias from '@rollup/plugin-alias'
// 引入可以编译ts的插件
import typescript from '@rollup/plugin-typescript'
// 引入自动生成html文件的插件
import html from '@rollup/plugin-html'
// 引入处理css的插件
import postcss from 'rollup-plugin-postcss'
// 引入处理图片的插件
import url from '@rollup/plugin-url'
// 引入压缩代码的插件
import terser from '@rollup/plugin-terser'
// 引入启动本地服务的插件
import serve from 'rollup-plugin-serve'
// 引入实现热更新的插件
import livereload from 'rollup-plugin-livereload'
export default {
    input: 'src/main.js',   
    output: {   
      file: 'dist/bundle.cjs.js',   
      format: 'esm',  
      name:"myModuleName", 
    },
    plugins:[
       commonjs(),  //直接使用
       nodeResolve(),
       babel({
        exclude:"node_modules/**",  //将node_modules中的文件排除
        babelHelpers: 'runtime' 
      }),
      // 配置别名的插件
      alias({
        entries:[
          {
            find:'@',replacement:path.resolve(__dirname,'./src/modules')
          }
        ]
      }),
      typescript(),  //使用插件
      html({
        format:"cjs"
      }),
      postcss({
        extract:true,//css通过链接引入
        use:['sass']  //编译sass
      }),
      url(),
      terser(),
      // 开启本地服务
      serve({
        open: true, // 自动打开页面
        port: 8000, 
        openPage: '/dist/index.html', // 打开的页面
        contentBase: ''
      }),
      livereload()
    ],
    external:['lodash']
  };

我们根据环境的不同配置不同的插件即可。加油学习前端的每一天!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值