实现 rollup 实现多模块打包

news2024/9/24 7:20:32

rollup 是一个 JavaScript 模块打包器,可以将许多 JavaScript 库和应用程序打包成少量的捆绑包,从而提高了应用程序的性能。本文详细描述如何通过 rollup 实现多模块打包。

前提

项目的目录结构
在这里插入图片描述

先看下项目的 package.json 文件夹:

{
  "private": true,
  "workspaces": [
    "packages/"
  ],
  "type": "module"
}

workspaces

这里我们使用 workspaces 字段定义 npm 工作空间。它可以让你在同一项目中使用多个独立的 npm 包,这些包可以共享相同的依赖项和环境,使得管理依赖关系变得更加方便。

同时你可以指定一个或多个目录,它们将包含在工作空间中。例子中,将 packages/ 目录包含在工作空间中,意味着在该目录下的所有子目录都将被视为 npm 包,并共享相同的依赖项和环境。

使用工作空间可以大大简化具有多个独立模块或应用的项目的依赖关系管理。你可以在每个模块或应用中独立运行 npm 命令,而无需担心它们之间的依赖关系和环境影响。

需要注意的是,使用工作空间需要你的项目目录结构符合一定的规范,例如每个模块或应用都需要位于 packages/ 目录的子目录中。此外,使用工作空间需要在命令行中运行 npm 命令时,需要使用 “–workspace” 标志来指定要操作的工作空间,例如 npm install rollup -W

同时 “workspaces” 只能在私有项目中使用。这里需要配置 private: true

包使用

通过目录结构可以看到在 packages 里面是有多个 npm 包的那么如何在去引用这些文件呢,例如在 reactivity 里面通过 import xxx from '@vue/shared' 去引用 shared 文件下的某个功能呢?我们经行如下修改:

// tsconfig.json
{
  "baseUrl": "./",
  "module": "ESNext",
  "moduleResolution": "node",
  // 省略部分代码
  "paths": {
    "@vue/*": ["packages/*/src"]
  }
}

在 shared 文件夹中补充如下测试代码:

// packages/shared/src/index.ts
export const isArray = Array.isArray

在 reactivity 文件夹下直接引入就行了:

// packages/reactivity/src/index.ts
import { isArray } from '@vue/shared'
console.log(isArray)

打包

既然每个文件都有属于一个独立 npm 模块,也会有一个属于自己的 package.jsonreactivity 为例:

package.json

{
  "name": "@vue/reactivity",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "buildOptions": {
    "name": "VueReactivity",
    "formats": [
      "esm-bundler",
      "cjs",
      "global"
    ]
  }
}

package.json 里面定义了包的名称以及对应的打包方式,分别是 esmcjsglobal 不同标准的打包方式。

execa

packages/ 目录包含了多个 npm 包那么如何对每个文件经行打包呢,这里我们可以使用 execa

import { readdirSync, statSync } from 'fs'
import { execa } from 'execa'

// 1、获取打包目录
const dirs = readdirSync('packages')
  .filter(dir => statSync(`packages/${dir}`).isDirectory()) // [ 'reactivity', 'shared' ]

async function build(TARGET) {
  await execa('rollup', ['-c', '--environment', `TARGET:${TARGET}`], { stdio: 'inherit' })
}

function runParaller(dirs) {
  let result = []
  for (const dir of dirs) {
    result.push(build(dir))
  }
  return Promise.all(result) // 存放打包的promise
}
// 2、进行打包
runParaller(dirs).then(() => {
  console.log('success')
})

rollup.config.js

上面代码通过 execa 去执行 rollup 的打包逻辑,这里的 −c 参数表示使用配置文件(默认是 rollup.config.js),−−environment 参数用于指定环境变量, stdio: 'inherit' 表示将命令的标准输入、输出和错误流重定向到父进程的流(即 Node.js 进程的流)。

import { defineConfig } from 'rollup'
import { createRequire } from 'node:module'
import ts from 'rollup-plugin-typescript2'
import json from '@rollup/plugin-json'
import resolvePlugin from '@rollup/plugin-node-resolve' // 解析第三方插件
import path from 'node:path'
import { fileURLToPath } from 'node:url'


const require = createRequire(import.meta.url)
const __dirname = path.dirname(fileURLToPath(import.meta.url))

// 2.获取文件路径
const packagesDir = path.resolve(__dirname, 'packages')

// 2.1 获取需要打包的文件
const packageDir = path.resolve(packagesDir, process.env.TARGET)
const resolve = p => path.resolve(packageDir, p)
// 2.2 获取每个包的配置项
const pkg = require(resolve('package.json')) // 获取 json

const name = path.basename(packageDir) // reactivity
// 3、创建一个映射表
const outputConfigs = {
  'esm-bundler': {
    file: resolve(`dist/${name}.esm-bundler.js`),
    format: 'esm'
  },
  'cjs': {
    file: resolve(`dist/${name}.cjs.js`),
    format: 'cjs'
  },
  'global': {
    file: resolve(`dist/${name}.global.js`),
    format: 'iife'
  }
}

const packageOptions = pkg.buildOptions || {}

// 1、创建一个打包配置
function createConfig(format, output) {
  output.name = packageOptions.name
  output.sourcemap = false
  // 生成rollup配置
  const config = {
    input: resolve('src/index.ts'), // 输入
    output, // 输出
    plugins: [
      json(),
      ts({
        tsconfig: path.resolve(__dirname, 'tsconfig.json')
      }),
      resolvePlugin()
    ]
  }
  return config
}

const packageFormats = packageOptions.formats

const packageConfigs = packageFormats.map(format => createConfig(format, outputConfigs[format]))
export default defineConfig(packageConfigs)

测试

example 在新建一个测试文件:

<script src="../packages/shared/dist/shared.global.js"></script>
<script>
  let { isArray } = VueShared;
  console.log(isArray([])); // true
</script>

总结

以上大体实现了通过 rollup 实现多模块打包的功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/823143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLaMA系列 | LLaMA和LLaMA-2精简总结

文章目录 1、LLaMA1.1、模型结构1.2、训练方式1.3、结论 2、LLaMA-22.1、相比LLaMA1的升级2.3、模型结构2.3.1、MHA, MQA, GQA区别与联系 2.4、训练方式 1、LLaMA &#x1f525; 纯基座语言模型 《LLaMA: Open and Efficient Foundation Language Models》&#xff1a;https:/…

CS5801国产HDMI转DP/edp(4k60)转换器方案芯片 可替代LT6711

CS5801是HDMI2.0b到DP1.4a转换器方案IC。CS5801 有一个HDMI2.0b .输入&#xff0c;带宽高达18Gbps.它支持辨别率是4k60Hz。对于DP1.4输出&#xff0c;由4条数据通道组成&#xff0c;支持1.62Gbps、 2.7Gbps、 5.4Gbps链路速率。内置可选SSC功能可降低EMI影响。嵌入式MCU基于32位…

3d虚拟vr汽车实景展厅吸引更多潜在消费者

随着人们对生活品质的追求&#xff0c;越来越多的消费者开始关注汽车的外观设计、内饰配置等方面。传统的展示方式已经不能满足消费者的需求&#xff0c;车辆VR虚拟漫游展示应运而生。借助VR虚拟现实和web3d开发建模技术&#xff0c;对汽车的外观、造型及信息数据进行数字化处理…

乳腺癌CT影像数据的深度学习:R语言与ANN神经网络构建高性能分类诊断模型

一、引言 乳腺癌是全球最常见的女性恶性肿瘤之一&#xff0c;也影响着男性的健康。据统计&#xff0c;每年有数百万人被诊断出患有乳腺癌[1]。乳腺癌的早期检测和准确诊断对于治疗和预后至关重要。然而&#xff0c;乳腺癌的早期诊断面临许多挑战&#xff0c;如图像解读的主观性…

第一堂棒球课:MLB全明星发展历程·棒球1号位

MLB全明星发展历程 1. MLB全明星的起源 MLB全明星是什么&#xff1f; MLB全明星&#xff0c;也就是MLB All-Stars&#xff0c;是指美国职业棒球大联盟&#xff08;Major League Baseball, MLB&#xff09;在每年举办的全明星赛。这项赛事汇集了全联盟各队的顶级球员&#xff…

InnoDB存储引擎——事务原理

1.什么是事务 2.redo log 脏页是指缓冲区的数据与磁盘中的数据不一致时的状态。脏页的数据并不是实时刷新的&#xff0c;而是一段时间之后通过后台线程把脏页的数据刷线到磁盘&#xff0c;假如说脏页的数据在往磁盘中刷新的时候出错了&#xff0c;内存中的数据没有刷新到磁盘当…

Java8实战-总结11

Java8实战-总结11 Lambda表达式方法引用管中窥豹如何构建方法引用 构造函数引用 Lambda表达式 方法引用 方法引用让你可以重复使用现有的方法定义&#xff0c;并像Lambda一样传递它们。在一些情况下&#xff0c;比起使用Lambda表达式&#xff0c;它们似乎更易读&#xff0c;感…

代码随想录算法训练营第二十九天 | Leetcode随机抽题检测

Leetcode随机抽题检测 160 相交链表未看解答自己编写的青春版重点题解的代码206 反转链表 一段用于复制的标题未看解答自己编写的青春版重点题解的代码日后再次复习重新写 234 回文链表未看解答自己编写的青春版重点综上&#xff0c;利用快慢指针找寻链表中间&#xff0c;就按加…

【C++】总结9

文章目录 C从源代码到可执行程序经过什么步骤静态链接和动态链接类的对象存储空间C的内存分区内存池在成员函数中调用delete this会出现什么问题&#xff1f;如果在类的析构函数中调用delete this&#xff0c;会发生什么&#xff1f; C从源代码到可执行程序经过什么步骤 预处理…

Tomcat 创建https

打开CMD,按下列输入 keytool -genkeypair -alias www.bo.org -keyalg RSA -keystore d:\ambition.keystore -storetype pkcs12 输入密钥库口令:123456 再次输入新口令:123456 您的名字与姓氏是什么? [Unknown]: www.ambition.com 您的组织单位名称是什么? [Unknown…

Qt 编译 Android 项目,输出乱码

乱码如下&#xff1a; :-1: error: 娉 C:\Qt\6.5.0\android_arm64_v8a\src\android\java\src\org\qtproject\qt\android\bindings\QtActivity.java浣跨敤鎴栬鐩栦簡宸茶繃鏃剁殑 API銆 娉 鏈夊叧璇︾粏淇℃伅, 璇蜂娇鐢-Xlint:deprecation 閲嶆柊缂栬瘧銆 正确的应该是&#…

qemu kvm 新建虚拟机

开始菜单打开虚拟机管理器

HDFS集群滚动升级以及回滚相关

HDFS集群滚动升级以及回滚相关 介绍不停机滚动升级非联邦HA集群联邦HA集群 停机升级--非HA集群HDFS集群降级和回滚异同点共同点不同点 HA集群降级&#xff08;downgrade&#xff09;注意事项 集群回滚操作 介绍 在hadoop v2中&#xff0c;HDFS支持namenode高可用&#xff08;H…

neo4j使用中的常见问题

1Spring Boot NEO The client is unauthorized due to authentication failure 解决方法&#xff1a;找到你安装neo4j的路径下的conf文件夹&#xff0c;找到neo4j.conf #dbms.security.auth_enabledfalse将前面的注释#去掉&#xff0c;然后重启neo4j&#xff0c;在重启项目即…

el-cascader级联选择器加载远程数据、默认开始加载固定条、可以根据搜索加载远程数据。

加载用户列表分页请求、默认请求20条数据。想添加远程搜索用户功能。原有的方法filter-method不能监听到输入清空数据的时候。这样搜索完无法返回默认的20条数据。直接监听级联选择的v-model绑定的值是无法检测到用户自己输入的。 解决思路&#xff1a; el-cascader 没有提供…

屏蔽托盘右键菜单

最近有个需求需要屏蔽托盘图标的右下角菜单项&#xff1a; 经过Apimonitor进行hook Explorer进程&#xff0c;发现弹出菜单是通过explorer调用InserMenuItem函数来实现的。通过注入explorer并挂钩InserMenuItemW函数&#xff0c;并屏蔽自己想要屏蔽的菜单项&#xff1a; &#…

2023-08-01 LeetCode每日一题(英雄的力量)

2023-08-01每日一题 一、题目编号 2681. 英雄的力量二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始的整数数组 nums &#xff0c;它表示英雄的能力值。如果我们选出一部分英雄&#xff0c;这组英雄的 力量 定义为&#xff1a; i0 &#xff0c;i1 &…

【ARM Coresight 系列文章 2.5 - Coresight 寄存器:PIDR0-PIDR7,CIDR0-CIDR3 介绍】

文章目录 1.1 JEDEC 与 JEP1061.2 PIDR0-PIDR7(peripheral identification registers)1.2 CIDR0-CIDR3(Component Identification Registers) 1.1 JEDEC 与 JEP106 JEDEC和JEP106都是来自美国电子工业联合会&#xff08;JEDEC&#xff0c;Joint Electron Device Engineering C…

Kafka3.0.0版本——Broker(总体工作流程)

目录 一、Kafka中Broker总体工作流程图解二、Kafka中Broker总体工作流程步骤解析 一、Kafka中Broker总体工作流程图解 总体工作流程图解 二、Kafka中Broker总体工作流程步骤解析 1、broker启动后在zk中注册&#xff0c;如下图所示&#xff1a; 2、controller谁先注册&…

Java面向对象之UML类图

UML类图 表示 public 类型&#xff0c; - 表示 private 类型&#xff0c;#表示protected类型方法的写法&#xff1a;方法的类型(、-) 方法名(参数名&#xff1a; 参数类型)&#xff1a;返回值类型