nodejs学习之Rollup

官网

https://github.com/rollup/rollup
英文文档
中文文档

是什么

Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。这在未来将在所有场景原生支持,但 Rollup 让你今天就可以开始这样做。

使用

新建文件夹nodejslibstu02,执行如下命令

pnpm init
pnpm add -D rollup

新建rollup.config.mjs

export default {
    input: 'src/index.js',
    output: {
        file: 'dist/bundle.js',
        format: 'iife',
        //iife下需要指定name
        name: 'bundle',
    },
};

src下新建foo.js

export default 'hello world!';

src下新建index.js

import foo from './foo.js';
export default function () {
    console.log(foo);
}

修改package.json

"type": "module",
"scripts": {
  "build": "rollup --config"
},

执行pnpm run build,打包结果如下
在这里插入图片描述
在这里插入图片描述
这个代码是直接可以在js中使用的

常用参数

input

该选项用于指定 bundle 的入口文件(例如,你的 main.js,app.js 或 index.js 文件)。如果值为一个入口文件的数组或一个将名称映射到入口文件的对象,那么它们将被打包到单独的输出 chunks。除非使用 output.file 选项,否则生成的 chunk 名称将遵循 output.entryFileNames 选项设置。当该选项的值为对象形式时,对象的属性名将作为文件名中的 [name],而对于值为数组形式,数组的值将作为入口文件名。
string | string[] | { [entryAlias: string]: string }

input: 'src/index.js',
input: ['src/index.js','src/index2.js'],

output

输出结果配置
MaybePromise<OutputPlugin | NullValue | false | OutputPluginOption[]>

output:{
    file:'bundle.js', // 输出文件
    format: 'cjs,  //  6种输出格式:amd /  es6 / iife / umd / cjs / system
    name:'A',  //当format为iife和umd时必须提供,将作为全局变量挂在window(浏览器环境)下:window.A=...
    sourcemap:true  //生成bundle.map.js文件,方便调试
}

plugins

各种插件使用的配置
MaybePromise<Plugin | NullValue | false | InputPluginOption[]>

plugins: [
    resolve(),
    commonjs(),
    isProduction && (await import('@rollup/plugin-terser')).default()
],

external

该选项用于匹配需要排除在 bundle 外部的模块,它的值可以是一个接收模块 id 参数并返回 true (表示外部依赖)或 false (表示非外部依赖)的函数,也可以是一个模块 ID 数组或者正则表达式。除此之外,它还可以只是单个的模块 ID 或正则表达式。被匹配的模块 ID 应该满足以下条件之一:

  • 外部依赖的名称,需要和引入语句中写法完全一致。例如,如果想标记 import “dependency.js” 为外部依赖,就需要使用 “dependency.js” 作为模块 ID;而如果要标记 import “dependency” 为外部依赖,则使用 “dependency”。
  • 解析过的模块 ID(如文件的绝对路径)。
    (string | RegExp)[]| RegExp| string| (id: string, parentId: string, isResolved: boolean) => boolean
external:['lodash'] //告诉rollup不要将此lodash打包,而作为外部依赖

global

该选项用于在 umd / iife bundle 中,使用 id: variableName 键值对指定外部依赖。
{ [name: string]: string } | ((name: string) => string)
例如,在这样的情况下

import $ from 'jquery';

//我们需要告诉 Rollup jquery 是外部依赖,jquery 模块的 ID 为全局变量 $

// rollup.config.mjs
export default {
    external: ['jquery'],
    output: {
        format: 'iife',
        name: 'MyBundle',
        globals: {
            jquery: '$'
        }
    }
};

CommonJS:适用于Node.js环境的输出,使用CommonJS模块化规范。简称cjs
ES Module:可以在现代浏览器端及Node.js中使用的输出,使用ESM模块化规范。简称es
UMD:兼容浏览器端及Node.js环境的输出,可以通过script标签导入,同时也支持CommonJS和AMD规范。通用模块定义规范,同时支持 amd,cjs 和 iife,简称umd
AMD:适用于使用AMD规范载入模块的环境,比如require.js。简称amd
SystemJS:适用于使用SystemJS载入模块的环境,比如jspm。简称system
iife:普通的全局变量方式导出,适合浏览器端,可以通过script标签导入。简称iife

插件

https://github.com/rollup/plugins/tree/master

创建压缩文件

安装插件

pnpm add -D @rollup/plugin-terser

修改rollup.config.mjs

import terser from '@rollup/plugin-terser';

export default {
    input: 'src/index.js',
    output: [{
        file: 'dist/bundle.js',
        format: 'iife',
        name: 'bundle',
        sourcemap: true,
    },{
        file: 'dist/bundle.min.js',
        format: 'iife',
        name: 'bundle',
        plugins: [terser()]
    }],
};

执行打包命令,如果放在最外层的plugins目录下就是都压缩
在这里插入图片描述

找到外部模块打包

@rollup/plugin-node-resolve 插件可以让 Rollup 找到外部模块,在 node_modules 中查找并捆绑第三方依赖项

pnpm add -D @rollup/plugin-node-resolve

安装一个jquery

pnpm add -D jquery

修改index.js

import foo from './foo.js';
import jQuery from 'jquery';

function testJquery(){
    jQuery(function (){
        console.log('juqery加载完成')
    })
}
testJquery();
export default function () {
    console.log(foo);
}

修改rollup.config.mjs

//import resolve from '@rollup/plugin-node-resolve';
import { nodeResolve } from '@rollup/plugin-node-resolve';

export default {
   	// 其他省略
    //plugins:[resolve()]
    plugins:[nodeResolve()]
};

如果配有配置plugins打包还是原来的大小只有自己写的代码,配置好resolve插件之后打包如下
在这里插入图片描述
由于 node_modules 文件夹中的大多数软件包可能是传统的 CommonJS 而非 JavaScript 模块,因此可能需要使用 @rollup/plugin-commonjs:

pnpm add -D @rollup/plugin-commonjs

修改rollup.config.mjs

import terser from '@rollup/plugin-terser';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

export default {
    input: 'src/index.js',
    output: [{
        file: 'dist/bundle.js',
        format: 'umd',
        name: 'bundle',
        sourcemap: true,
    },{
        file: 'dist/bundle.min.js',
        format: 'umd',
        name: 'bundle',
        plugins: [terser()]
    }],
    plugins:[nodeResolve(),commonjs()]
};

打包成功体积变大了
在这里插入图片描述

请注意,大多数情况下,@rollup/plugin-commonjs 应该放在转换模块的其他插件之前 - 这是为了防止其他插件对 CommonJS 检测产生影响。一个例外是 Babel 插件,如果你使用它,请将它放在 commonjs 插件之前。

代码分割

代码分割是指有些情况下 Rollup 会自动将代码拆分成块,例如动态加载或多个入口点,还有一种方法可以显式地告诉 Rollup 将哪些模块拆分成单独的块,这是通过 output.manualChunks 选项实现的。
要使用代码分割功能实现惰性动态加载(其中某些导入的模块仅在执行函数后加载),我们返回到原始示例,并修改 src/main.js,以动态加载 src/foo.js 而不是静态加载:
修改index.js

// export default function () {
//     console.log(foo);
// }
//上面代码是原来的
export default function () {
    import('./foo.js').then(({ default: foo }) => console.log(foo));
}

UMD and IIFE不支持分包打包,所以需要修改为cjs,然后不能使用file,而是使用dir,修改rollup.config.mjs

import terser from '@rollup/plugin-terser';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

export default {
    input: 'src/index.js',
    output: [{
        format: 'cjs',
        name: 'bundle',
        sourcemap: true,
        dir: 'dist/bundle',
    }],
    plugins:[terser(),nodeResolve(),commonjs()]
};

在这里插入图片描述
src下新建index2.js

export default function () {
    import('./foo.js').then(({ default: foo }) => console.log(foo));
}

修改rollup.config.mjs

import terser from '@rollup/plugin-terser';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

export default {
    input: ['src/index.js',"src/index2.js"],
    output: [{
        format: 'cjs',
        name: 'bundle',
        sourcemap: true,
        dir: 'dist/bundle',
    }],
    plugins:[terser(),nodeResolve(),commonjs()]
};

在这里插入图片描述
只生成了一个foo

Babel

为了正确解析我们的模块并使其与旧版浏览器兼容,我们应该包括babel来编译输出。许多开发人员在他们的项目中使用 Babel ,以便他们可以使用未被浏览器和 Node.js 支持的将来版本的 JavaScript 特性。
https://www.babeljs.cn/
https://babeljs.io/

pnpm add -D @rollup/plugin-babel
pnpm add -D @babel/core
pnpm add -D @babel/preset-env

新建babel.config.mjs

export default {
    presets: [
        [
            '@babel/preset-env',
            {
                //是否忽略browserslistrc配置
                ignoreBrowserslistConfig: false,
                // 使用 "loose" 模式编译 ES2015+ 中的代码,允许生成与严格模式代码不完全相同的代码
                loose: true,
                //启用针对已知 Bug 的修复程序
                bugfixes: true,
                //禁止转换为其他类型的模块
                modules: false,
                //排除对typeof Symbol 表达式转换,因为目前的环境已经支持 Symbol 类型
                exclude: ['transform-typeof-symbol']
            }
        ]
    ]
}

修改rollup.config.mjs

import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';

export default {
    input: ['src/index.js'],
    output: [{
        file:"dist/bundle.js",
        format: 'umd',
        name: 'bundle',
        sourcemap: true,
    }],
    plugins: [
        nodeResolve(),
        commonjs(),
        babel({
            exclude: 'node_modules/**',
            babelHelpers: "bundled",
        }),
    ]
};

修改index.js

const square = n => n * n;
console.log(square(10))

打包成功查看结果,可以看到将匿名函数改成function方式了
在这里插入图片描述

避免打包第三方库

如果你不想第三方库被打包进来,而可以在外面引入,配合使用的话,可以在rollup.config.js中配置external
修改index.js

import foo from './foo.js';
import $ from 'jquery';

function testJquery(){
    $(function (){
        console.log('juqery加载完成')
    })
}
testJquery();
function aaa() {
    console.log(foo);
}
aaa();
const square = n => n * n;
console.log(square(10))

执行打包,可以看到把jQuery也打包进来了
在这里插入图片描述
修改rollup.config.mjs,主要增加external和output下的globals

import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';

export default {
    input: ['src/index.js'],
    output: [{
        file:"dist/bundle.js",
        format: 'umd',
        name: 'bundle',
        sourcemap: true,
        globals: {
            jquery: '$'
        }
    }],
    plugins: [
        //terser(),
        nodeResolve(),
        commonjs(),
        babel({
            exclude: 'node_modules/**',
            babelHelpers: "bundled",
        }),
    ],
    external:['jquery']
};

再次打包可以看到没有jQuery包的代码了
在这里插入图片描述
这样在使用的时候我们只需要在浏览器中自己引入jquery即可

配置css

在这里插入图片描述
安装postcss插件

pnpm add -D rollup-plugin-postcss

修改rollup.config.mjs

import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'

export default {
    input: ['src/index.js'],
    output: [{
        file:"dist/bundle.js",
        format: 'umd',
        name: 'bundle',
        sourcemap: true,
        globals: {
            jquery: '$'
        }
    }],
    plugins: [
        //terser(),
        nodeResolve(),
        commonjs(),
        babel({
            exclude: 'node_modules/**',
            babelHelpers: "bundled",
        }),
        postcss()
    ],
    external:['jquery']
};

src下新建css文件夹,该文件夹下新建index.css

body{
    background: #ccc;
}

执行打包
在这里插入图片描述
css自动加浏览器前缀以及将css和js分开

pnpm add -D autoprefixer

修改index.css

@keyframes fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}

body {
    background: #ccc;
    animation-name: fadeIn;
}

.autoplacement-example {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    grid-gap: 20px;
}

::placeholder {
    color: gray;
}

修改rollup.config.mjs

import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'
import autoprefixer from "autoprefixer";

export default {
    input: ['src/index.js'],
    output: [{
        file:"dist/bundle.js",
        format: 'umd',
        //assetFileNames: 'assets/[name]-[hash][extname]',
        name: 'bundle',
        sourcemap: true,
        globals: {
            jquery: '$'
        }
    }],
    plugins: [
        //terser(),
        nodeResolve(),
        commonjs(),
        babel({
            exclude: 'node_modules/**',
            babelHelpers: "bundled",
        }),
        postcss({
            extract: true, // 是否将CSS抽离成单独的文件
            sourceMap: true, // 是否生成 sourceMap
            plugins: [
                autoprefixer({
                    // Autoprefixer 配置
                    overrideBrowserslist: [
                        "last 2 Chrome versions",
                        "> 1%",
                        "Firefox ESR",
                        "IE 9-11"
                    ],
                    grid: true // 启用 CSS Grid 的自动前缀
                })
            ],
            minimize: false, // 压缩 CSS
            extensions: ['.css'] // 处理的文件扩展名
        }),
        // css({
        //     output: 'bundle.css'
        // })
    ],
    external:['jquery']
};

打包
在这里插入图片描述

另外一种将css和js分开的方法

pnpm add -D rollup-plugin-css-only

修改rollup.config.mjs

import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'

export default {
    input: ['src/index.js'],
    output: [{
        file:"dist/bundle.js",
        format: 'umd',
        //assetFileNames: 'assets/[name]-[hash][extname]',
        name: 'bundle',
        sourcemap: true,
        globals: {
            jquery: '$'
        }
    }],
    plugins: [
        //terser(),
        nodeResolve(),
        commonjs(),
        babel({
            exclude: 'node_modules/**',
            babelHelpers: "bundled",
        }),
        //postcss(),
        css({
            output: 'bundle.css'
        })
    ],
    external:['jquery']
};

打包之后js中就没有css文件了
在这里插入图片描述

配置scss

pnpm add -D rollup-plugin-sass
pnpm add -D postcss

https://www.npmjs.com/package/rollup-plugin-sass
src下新建scss文件夹,新建index.scss

$font-size: 14px;
$link-color:#ff0;

::placeholder {
  color: gray;
}
.test{
  font-size: $font-size;
  a{
    color: $link-color;
  }
}

修改index.js

import foo from './foo.js';
import $ from 'jquery';
import "./css/index.css"
import './scss/index.scss'

function testJquery(){
    $(function (){
        console.log('juqery加载完成')
    })
}
testJquery();
function aaa() {
    console.log(foo);
}
aaa();
const square = n => n * n;
console.log(square(10))

修改rollup.config.mjs

import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'
import autoprefixer from "autoprefixer";
import sass from 'rollup-plugin-sass';
import postcss2 from 'postcss';

export default {
    input: ['src/index.js'],
    output: [{
        file:"dist/bundle.js",
        format: 'umd',
        //assetFileNames: 'assets/[name]-[hash][extname]',
        name: 'bundle',
        sourcemap: true,
        globals: {
            jquery: '$'
        }
    }],
    plugins: [
        //terser(),
        nodeResolve(),
        commonjs(),
        babel({
            exclude: 'node_modules/**',
            babelHelpers: "bundled",
        }),

        postcss({
            extract: true, // 是否将CSS抽离成单独的文件
            sourceMap: true, // 是否生成 sourceMap
            plugins: [
                autoprefixer({
                    // Autoprefixer 配置
                    overrideBrowserslist: [
                        "last 2 Chrome versions",
                        "> 1%",
                        "Firefox ESR",
                        "IE 9-11"
                    ],
                    grid: false // 不启用 CSS Grid 的自动前缀
                })
            ],
            minimize: false, // 压缩 CSS
            extensions: ['.css'], // 处理的文件扩展名
            inject: false, // 防止 Rollup 将 CSS 注入到 JavaScript 中
        }),
        sass({
            // sass 插件的配置
            output: 'dist/bundle2.css', // 输出 CSS 文件的路径
            processor:css => postcss2([autoprefixer({
                // Autoprefixer 配置
                overrideBrowserslist: [
                    "last 2 Chrome versions",
                    "> 1%",
                    "Firefox ESR",
                    "IE 9-11"
                ],
                grid: false // 不启用 CSS Grid 的自动前缀
            })])
                .process(css)
                .then(result => result.css)
        }),

        // css({
        //     output: 'bundle.css'
        // })
    ],
    external:['jquery']
};

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

rollup-plugin-postcss也可以处理scss
在这里插入图片描述

配置typescript

pnpm add -D @rollup/plugin-typescript --registry http://registry.npm.taobao.org
# pnpm add -D rollup-plugin-typescript2 --registry http://registry.npm.taobao.org
pnpm add -D tslib typescript --registry http://registry.npm.taobao.org

src下新建Greeter.ts

class Greeter {
    greeter: string;

    constructor(message: string) {
        this.greeter = message
    }

    greet() {
        return 'hello ts';
    }
}

export default Greeter

src下新建hello.ts

import Greeter from "./Greeter";


const a = new Greeter('ss');
a.greet();

修改index.js

import foo from './foo.js';
import $ from 'jquery';
import "./css/index.css"
import './scss/index.scss'
import './hello.js'

function testJquery(){
    $(function (){
        console.log('juqery加载完成')
    })
}
testJquery();
function aaa() {
    console.log(foo);
}
aaa();
const square = n => n * n;
console.log(square(10));

修改rollup.config.mjs

import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'
import autoprefixer from "autoprefixer";
import sass from 'rollup-plugin-sass';
import postcss2 from 'postcss';
import typescript from '@rollup/plugin-typescript';

export default {
    input: ['src/index.js'],
    output: [{
        file: "dist/bundle.js",
        format: 'umd',
        //assetFileNames: 'assets/[name]-[hash][extname]',
        name: 'bundle',
        sourcemap: true,
        //dir: 'dist/bundle',
        globals: {
            jquery: '$'
        }
    }],
    plugins: [
        typescript({
            compilerOptions: {
                lib: ["es5", "es6", "dom"],
                target: "es5"
            },
            exclude: "node_modules/**",
        }),
        //terser(),
        nodeResolve(),
        commonjs(),
        babel({
            exclude: 'node_modules/**',
            babelHelpers: "bundled",
        }),

        postcss({
            extract: true, // 是否将CSS抽离成单独的文件
            sourceMap: true, // 是否生成 sourceMap
            plugins: [
                autoprefixer({
                    // Autoprefixer 配置
                    overrideBrowserslist: [
                        "last 2 Chrome versions",
                        "> 1%",
                        "Firefox ESR",
                        "IE 9-11"
                    ],
                    grid: false // 不启用 CSS Grid 的自动前缀
                })
            ],
            minimize: false, // 压缩 CSS
            extensions: ['.css'], // 处理的文件扩展名
            inject: false, // 防止 Rollup 将 CSS 注入到 JavaScript 中
        }),
        // sass({
        //     // sass 插件的配置
        //     output: 'dist/bundle2.css', // 输出 CSS 文件的路径
        //     processor:css => postcss2([autoprefixer({
        //         // Autoprefixer 配置
        //         overrideBrowserslist: [
        //             "last 2 Chrome versions",
        //             "> 1%",
        //             "Firefox ESR",
        //             "IE 9-11"
        //         ],
        //         grid: false // 不启用 CSS Grid 的自动前缀
        //     })])
        //         .process(css)
        //         .then(result => result.css)
        // }),

        // css({
        //     output: 'bundle.css'
        // })
    ],
    external: ['jquery']
};

打包
在这里插入图片描述

参考

https://blog.csdn.net/yutao618/article/details/116272769
https://blog.csdn.net/weixin_39216318/article/details/131431277
https://www.rollupjs.com/configuration-options/#external
https://github.com/rollup/plugins/tree/master

相关推荐

  1. nodejs学习glob

    2024-07-19 02:52:02       25 阅读
  2. Web3L2 ZK-Rollup 方案-StarkNet

    2024-07-19 02:52:02       60 阅读
  3. Rollup介绍

    2024-07-19 02:52:02       20 阅读
  4. 以太坊的扩容方案二层网络 L2-Rollup & zkEVM

    2024-07-19 02:52:02       35 阅读
  5. 前端学习——nodejs

    2024-07-19 02:52:02       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-19 02:52:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-19 02:52:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-19 02:52:02       58 阅读
  4. Python语言-面向对象

    2024-07-19 02:52:02       69 阅读

热门阅读

  1. 代码随想录学习 54day 图论 Bellman_ford 算法精讲

    2024-07-19 02:52:02       20 阅读
  2. 锁升级过程中的两次自旋 面试重点

    2024-07-19 02:52:02       22 阅读
  3. electron 应用的生命周期

    2024-07-19 02:52:02       23 阅读
  4. SQL基础

    2024-07-19 02:52:02       21 阅读
  5. 【Unity C#优化】业务逻辑代码方面的优化

    2024-07-19 02:52:02       21 阅读
  6. 【Linux】微基准测试

    2024-07-19 02:52:02       20 阅读
  7. AI发展下的伦理挑战,应当如何应对?

    2024-07-19 02:52:02       19 阅读