当前位置: 首页 > news >正文

笔记:使用 unbuild 搭建 JavaScript 构建系统笔记

使用 unbuild 搭建 JavaScript 构建系统

jcLee95:https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
邮箱 :291148484@163.com

简介:
本文是笔者阅读分析 elementPlus 项目时记录的。该项目用到了一个完全没有文档和资料的工具 unbuild。

为了搞清楚其功能,在github上看了一下该模块的源代码并记录之。

本文地址https://blog.csdn.net/qq_28550263/article/details/129016838

目 录

1. unbuild 简介与安装

2. unbuild 的用法

  • 2.1 配置文件 build.config.ts
  • 2.2 pacakage.json 与 cli 用法

3. 该模块用到的一些模块

  • 3.1 一款 await 的挂钩系统:hookable

    • 3.1.1 安装
    • 3.1.2 通过直接创建 hookable 实例使用
    • 3.1.3 通过从 Hookable 扩展你的基类使用
    • 3.1.4 Hookable 类的接口解析
  • 3.2 轻量级文件到文件转换器:mkdist

  • 3.2.1 简介与安装

  • 3.2.2 mkdist 的用法

3.3 Node.js 的运行时Typescript 和 ESM 支持:jiti

  • 3.3.1 简介与安装
  • 3.3.2 jiti 的用法

3.4 将字节转换为人类可读的字符串:pretty-bytes

  • 3.4.1 简介与安装
  • 3.4.2 用法

附录


1. unbuild 简介与安装

搭建前端项目时,我们经常需要寻找一些构建工具来辅助我们自动化地进行打包和完成其它工作,如 webpack、rollup、gulp、vite 等等。对于一些功能的需求比较简单的场景,我们用不着使用 webpack 之类的重型构建工具,完全可以考虑使用一些小工具完成。本文介绍的 unbuild 就是这样一个小工具,它是一个强大的基于 rollup 的捆绑器,支持 TypeScript 并生成 commonjs 和 module 格式 + 类型声明。它能够能够自动推断 package.json 中的 build 配置和条目。

你可以通过如下方式安装到项目依赖中:

npm i unbuild -D
# 或
yarn add unbuild -D
# 或
pnpm i unbuild -D

2. unbuild 的用法

2.1 配置文件 build.config.ts

unbuild CLI 基于配置文件 build.config.ts 工作,你应该手动在项目根目录中创建它,以便于执行脚本的时候被 unbuild 所找到。一个该文件的实例为:

import { defineBuildConfig } from 'unbuild'export default defineBuildConfig({// 如果没有提供entries,将从package.json中自动推断出entries: [// 指定源文件入口,默认值为 './src/index''./src/index',// mkdist builder 传输文件到文件,保持原始源结构{builder: 'mkdist',input: './src/package/components/',outDir: './build/components'},],// 指定输出目录,默认为 'dist'outDir: 'build',// 指定是否生成 .d.ts 声明文件declaration: true,
})

其中 defineBuildConfig 传入的对象可以配置以下内容:

配置项类型描述
rootDirstring指定根目录起始位置
entriesBuildEntry[];指定源文件入口,默认值为 './src/index'
cleanboolean输出前是否清空输出目录
declarationboolean指定是否生成 .d.ts 声明文件
outDirstring指定输出目录,默认为 'dist'
stubboolean跳过 stub 的剩余部分
externalsstring[]是否所有依赖项作为外部项添加(dependencies、peerDependencies)
dependenciesstring[]从pkg推断的依赖关系
peerDependenciesstring[]从pkg推断的依赖关系
devDependenciesstring[]从pkg推断的依赖关系
alias{ [find: string]: string;}由 unbuild 传给 rollup 的 alias 配置项
replace{ [find: string]: string;}由 unbuild 传给 rollup 的 replace 配置项
rollupRollupBuildOptions由 unbuild 传给 rollup 的构建选项
hooksPartial<BuildHooks>
presetstring | BuildPreset

2.2 pacakage.json 与 cli 用法

{"main": "./dist/index.cjs","module": "./dist/index.mjs","types": "./dist/index.d.ts","scripts": {"build": "unbuild","dev": "pnpm run stub","stub": "unbuild --stub"},"devDependencies": {"unbuild": "^0.7.4"}
}

3. 该模块用到的一些模块

这个部分是在分析 unbuild 模块源码中用到的一些库。

3.1 一款 await 的挂钩系统:hookable

3.1.1 简介与安装

该模块用于管理注册和调用钩子,你可以通过以下方式进行安装:

npm install hookable
# or
yarn add hookable
# or
pnpm install hookable

3.1.2 通过直接创建 hookable 实例使用

import { createHooks } from 'hookable'// 创建一个 hookable 实例
const hooks = createHooks()// 挂上 'hello'
hooks.hook('hello', () => { console.log('Hello World' )})// 调用 'hello' 钩子
hooks.callHook('hello')

3.1.3 通过从 Hookable 扩展你的基类使用

import { Hookable } from 'hookable'export default class FooLib extends Hookable {constructor() {// 调用父类进行初始化super()// 用自定义 logger 初始化可挂钩// super(consola)}async someFunction() {// 按顺序调用并等待“hook1”挂钩(如果有)await this.callHook('hook1')}
}

在插件中,注册任意钩子:

const lib = new FooLib()// 注册“hook2”的处理程序
lib.hook('hook2', async () => { /* ... */ })// 一次注册多个处理程序
lib.addHooks({hook1: async () => { /* ... */ },hook2: [ /* 也可以是一个数组 */ ]
})

3.1.4 Hookable 类的接口解析

3.2 轻量级文件到文件转换器:mkdist

3.2.1 简介与安装

Bundling 库有时候不是最佳的选择,因为通过捆绑传输丢失现代语法,也让我们丢失原有的文件结构,也有时通过将css提取到全局dist(vue) 而丢失关键css。
即使不使用,依赖项也将总是从 bundle 绑包中导入(第二个捆绑步骤可能会解决这个问题,但这通常不会发生在开发中和有副作用的依赖项中)。

虽然有像 tsc@babel/cli 这样的工具,但它们大多专注于传输文件,而不是保持源代码级别的质量。此外,它们缺乏对处理自定义扩展的支持,如。vue和复制assets

mkdist可以:

  • 复制所有的 assets;
  • 支持 Vue 单文件组件;
  • 通过 esbuild 实现快速和最小的转换;
  • .为 .ts, .js.vue 文件生成 d.ts 类型声明文件

你可以通过以下方式进行安装:

npm install mkdist
# or
yarn add mkdist
# or
pnpm install mkdist

3.2.2 mkdist 的用法

CLI 的语法格式

mkdist [rootDir] [--src=src] [--dist=dist] [--pattern=glob [--pattern=more-glob]] [--format=cjs|esm] [-d|--declaration] [--ext=mjs|js|ts]

3.3 Node.js 的运行时 Typescript 和 ESM 支持:jiti

3.3.1 简介与安装

jiti 是一款Node.js 的运行时 Typescript 和 ESM 支持模块,也就是说它可以让 Nodejs 运行时运行 Typescript 和 ESM 代码,该模块可以:

  • 无缝typescript和ESM语法支持;
  • ESM和CommonJS之间的无缝互操作性;
  • 替换 require 的同步API;
  • 超级苗条和零依赖;
  • 智能语法检测,避免额外的转换;
  • CommonJS缓存集成;
  • 文件系统传输文件硬缓存;
  • V8编译缓存;
  • 自定义解析别名

你可以通过如下之一的方式进行安装:

npm install jiti
# or
yarn add jiti
# or
pnpm install jiti

3.3.2 jiti 的用法

1. 编程用法

const jiti = require("jiti")(__filename);jiti("./path/to/file.ts");

2. 命令行用法

若是全局安装了 jiti ,可以直接使用 jiti 命:

jiti index.ts

若只在当前项目中安装了 jiti ,可用 npx jiti 运行脚本文件

npx jiti index.ts

3.4 将字节转换为人类可读的字符串:pretty-bytes

3.4.1 简介与安装

该模块可用于打包时在终端更好地输出文件大小,可以通过如下方式进行安装:

npm install pretty-bytes
# or
yarn add pretty-bytes
# or
pnpm install pretty-bytes

3.4.2 用法

import prettyBytes from 'pretty-bytes';prettyBytes(1337);
//=> '1.34 kB'prettyBytes(100);
//=> '100 B'// 以位为单位显示
prettyBytes(1337, {bits: true});
//=> '1.34 kbit'// 显示文件大小差异
prettyBytes(42, {signed: true});
//=> '+42 B'// 使用德语语言环境的本地化输出
prettyBytes(1337, {locale: 'de'});
//=> '1,34 kB'

附录

  • BuildEntry
declare type BuildEntry = BaseBuildEntry | RollupBuildEntry | UntypedBuildEntry | MkdistBuildEntry;
interface BaseBuildEntry {builder?: 'untyped' | 'rollup' | 'mkdist';input: string;name?: string;outDir?: string;declaration?: Boolean;
}interface UntypedBuildEntry extends BaseBuildEntry {builder: 'untyped';defaults?: Record<string, any>;
}
interface RollupBuildEntry extends BaseBuildEntry {builder: 'rollup';
}
interface MkdistBuildEntry extends BaseBuildEntry {builder: 'mkdist';format?: 'esm' | 'cjs';ext?: 'cjs' | 'mjs' | 'js' | 'ts';
}
  • RollupBuildOptions
import { RollupReplaceOptions } from '@rollup/plugin-replace';
import { RollupAliasOptions } from '@rollup/plugin-alias';
import { RollupNodeResolveOptions } from '@rollup/plugin-node-resolve';
import { RollupJsonOptions } from '@rollup/plugin-json';
import { Options as Options$1 } from 'rollup-plugin-dts';declare type RollupCommonJSOptions = Parameters<typeof commonjs>[0] & {};interface RollupBuildOptions {emitCJS?: boolean;cjsBridge?: boolean;inlineDependencies?: boolean;replace: RollupReplaceOptions | false;alias: RollupAliasOptions | false;resolve: RollupNodeResolveOptions | false;json: RollupJsonOptions | false;esbuild: Options | false;commonjs: RollupCommonJSOptions | false;dts: Options$1;
}
  • BuildHooks
import { RollupOptions, RollupBuild } from 'rollup';interface BuildHooks {'build:prepare': (ctx: BuildContext) => void | Promise<void>;'build:before': (ctx: BuildContext) => void | Promise<void>;'build:done': (ctx: BuildContext) => void | Promise<void>;'rollup:options': (ctx: BuildContext, options: RollupOptions) => void | Promise<void>;'rollup:build': (ctx: BuildContext, build: RollupBuild) => void | Promise<void>;'rollup:dts:options': (ctx: BuildContext, options: RollupOptions) => void | Promise<void>;'rollup:dts:build': (ctx: BuildContext, build: RollupBuild) => void | Promise<void>;'rollup:done': (ctx: BuildContext) => void | Promise<void>;'mkdist:entries': (ctx: BuildContext, entries: MkdistBuildEntry[]) => void | Promise<void>;'mkdist:entry:options': (ctx: BuildContext, entry: MkdistBuildEntry, options: MkdistOptions) => void | Promise<void>;'mkdist:entry:build': (ctx: BuildContext, entry: MkdistBuildEntry, output: {writtenFiles: string[];}) => void | Promise<void>;'mkdist:done': (ctx: BuildContext) => void | Promise<void>;'untyped:entries': (ctx: BuildContext, entries: UntypedBuildEntry[]) => void | Promise<void>;'untyped:entry:options': (ctx: BuildContext, entry: UntypedBuildEntry, options: any) => void | Promise<void>;'untyped:entry:schema': (ctx: BuildContext, entry: UntypedBuildEntry, schema: Schema) => void | Promise<void>;'untyped:entry:outputs': (ctx: BuildContext, entry: UntypedBuildEntry, outputs: UntypedOutputs) => void | Promise<void>;'untyped:done': (ctx: BuildContext) => void | Promise<void>;
}
interface BuildContext {options: BuildOptions;pkg: PackageJson;buildEntries: {path: string;bytes?: number;exports?: string[];chunks?: string[];}[];usedImports: Set<string>;hooks: Hookable<BuildHooks>;
}
  • BuildPreset
declare type BuildPreset = BuildConfig | (() => BuildConfig);
interface BuildConfig extends DeepPartial<Omit<BuildOptions, 'entries'>> {entries?: (BuildEntry | string)[];preset?: string | BuildPreset;hooks?: Partial<BuildHooks>;
}

相关文章:

笔记:使用 unbuild 搭建 JavaScript 构建系统笔记

使用 unbuild 搭建 JavaScript 构建系统jcLee95&#xff1a;https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 &#xff1a;291148484163.com 简介&#xff1a; 本文是笔者阅读分析 elementPlus 项目时记录的。该项目用到了一个完全没有文档和资料的工具 unbu…...

【SpringBoot3.0源码】启动流程源码解析 •下

文章目录初始化DefaultBootstrapContext开启Headless模式获取监听器并启动封装命令行参数准备环境打印Banner创建上下文容器预初始化上下文容器刷新Spring容器打印启动时间发布事件执行特定的run方法上一篇《【SpringBoot3.0源码】启动流程源码解析 • 上》&#xff0c;主要讲解…...

QT(56)-动态链接库-windows-导出变量-导出类

1.导出变量 1.1不使用_declspec(dllimport) _declspec(dllexport) 使用_declspec(dllimport) _declspec(dllexport) 1.2win32 mydllwin32 myexe 1.3win32 mydllqt myexe 2.导出类 使用_declspec(dllimport) _declspec(dllexport) 2.1不用关键…...

TCP传输文件

传输文件和传输信息的区别&#xff1a; 传输信息&#xff0c;只是一条数据&#xff0c;传输文件是多条数据传输信息传输过去一般都会显示&#xff0c;传输文件一般不会显示&#xff0c;一般只是存放在文件中传输文件需要传输&#xff0c;文件大小和文件名称&#xff08;不然不知…...

vue3:加载本地图片等静态资源

背景 在我们用 vue2 webpack 的时候&#xff0c;加载图片资源是这样用的&#xff1a; <img :src"require(/assets/test.png)" />这样打包后就会触发 file-loader 打包图片资源&#xff0c;在 dist 文件夹中就可以看到这个图片&#xff08;如果图片较小会打包…...

工作记录------数据库group_concat函数长度问题

工作记录------group_concat函数长度问题 背景&#xff1a;页面在数据展示时&#xff0c;报错&#xff0c;错误显示&#xff1a;String index out of range: -1 异常信息 java.lang.StringIndexOutOfBoundsException: String index out of range: -1at java.lang.String.sub…...

Python基础语法

1 编程环境 1.1 编译环境 pycharmpython/anaconda 1.2 环境设置 File -> settings -> Project interpreter -> 1.3 Hello world 2 条件判断 2.1 例题 【题1】输入一个年份&#xff0c;判断是否是闰年 ①能被4整除&#xff0c;但不能被100整除; ②能被400整…...

windows环境下安装Nginx及常用操作命令

windows环境下安装Nginx及常用操作命令nginx基本概述基本用途nginx安装nginx基本概述 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器。基本用途 nginx是一个轻量级高并发服务器&#xff0c;而tomcat并不是。nginx一般被用来做反向代理&#xff0c;将请求转发到应用…...

python excel数据处理?

前段时间做了个小项目&#xff0c;帮个海洋系的教授做了个数据处理的软件。基本的功能很简单&#xff0c;就是对Excel里面的一些数据进行过滤&#xff0c;统计&#xff0c;对多个表的内容进行合并等。之前没有处理Excel数据的经验&#xff0c;甚至于自己都很少用到Excel。记得《…...

Hudi-集成Flink

文章目录集成Flink环境准备sql-client方式启动sql-client插入数据查询数据更新数据流式插入code 方式环境准备代码类型映射核心参数设置去重参数并发参数压缩参数文件大小Hadoop参数内存优化读取方式流读&#xff08;Streaming Query&#xff09;增量读取&#xff08;Increment…...

重新认识 React Hooks useContext

通常来说,React 数据的传递方式都是一层一层把资料 props 传到子层的 就算第二层(Function Component)、第三层(Button Group Compontn) 根本没有用到这个资料,但是为了传到最底层(button) ,每一层还是必须要传props // App.js const App = () => {const [dark, setDark…...

数据库(2)--加深对统计查询的理解,熟练使用聚合函数

一、内容要求 利用sql建立学生信息数据库&#xff0c;并定义以下基本表&#xff1a; 学生&#xff08;学号&#xff0c;年龄&#xff0c;性别&#xff0c;系号&#xff09; 课程&#xff08;课号&#xff0c;课名&#xff0c;学分&#xff0c;学时&#xff09; 选课&#xff0…...

stm32f407探索者开发板(十五)——NVIC中断优先级管理

文章目录零、前言一、NVIC中断优先级分组1.1 中断的管理方法1.2 抢占优先级&相应优先级的区别1.3 举例1.4 特别说明1.5 中断优先级分组函数二、NVIC中断优先级设置2.1 中断设置相关寄存器2.2 中断设置优先级2.2.1 中断优先级控制的寄存器组 IP[240]2.2.2 中断使能寄存器组 …...

【Azure 架构师学习笔记】-Azure Logic Apps(6)- Logic Apps调用ADF

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Logic Apps】系列。 接上文【Azure 架构师学习笔记】-Azure Logic Apps&#xff08;5&#xff09;- 标准和使用量类型的区别 前言 Logic Apps 和 ADF 的搭配使用是常见的组合&#xff0c;它们可以互相弥补各自的不足和…...

python随机获取列表中某一元素

1、利用Python中的random模块中的choice方法 random.choice()可以从任何序列&#xff0c;比如list列表中&#xff0c;选取一个随机的元素返回&#xff0c;可以用于字符串、列表、元组等。 import random arr[1,2,3,4,5,6] print(random.choice(arr))2、利用Python中的random模…...

Nacos微服务笔记

Nacos安装Nacos 的 Github&#xff08;Tags alibaba/nacos GitHub&#xff09;下载我们所需的 Nacos 版本&#xff0c;可以选择 windows 或者 Linux。 进入官网&#xff0c;选择合适版本&#xff0c;tar.gz为linux版本&#xff0c;zip为windows版本。下载并解压 nacos-server…...

MAC文件误删怎么办?mac数据恢复,亲测很好用的方法

电脑文件误删&#xff0c;应该很多人都经历过。之前分享了很多关于Windows电脑文件误删如何恢复的方法&#xff0c;那么MAC电脑文件误删该怎么办&#xff1f;有什么好方法可以使得mac数据恢复回来吗&#xff1f;下面就给大家分享一些亲测好用的方法&#xff01; 一、MAC电脑的文…...

机械革命z2黑苹果改造计划第二番-MacOS实用软件渗透工具

机械革命z2黑苹果改造计划第二番-实用软件 Mac实用工具 这是旧电脑改造计划的第二篇&#xff0c;就是安装一些常用软件和一些渗透测试工具&#xff0c;武装灵魂成为真正的生产力工具 首先推荐一个网站&#xff0c;www.mactools.app&#xff0c;这个软件里边有大多数常用的软…...

【LeetCode】每日一题(4)

目录 题目&#xff1a;1124. 表现良好的最长时间段 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 写在最后&#xff1a; 题目&#xff1a;1124. 表现良好的最长时间…...

Linux内核移植:内核的启动过程分析、启动配置与rootfs必要文件

Linux内核移植&#xff1a;内核的启动过程、启动配置与rootfs必要文件一、启动过程二、启动配置&#xff08;一&#xff09;SysV初始化&#xff08;二&#xff09;systemd初始化三、rootfs中的启动配置文件1、inittab2、/etc/init.d/rcS 脚本3、fstab4、profile 文件5、其他文件…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...