3行代码即可在你的项目中集成bundle-less构建

上一篇,介绍了unbuild的插桩技术,并且该文章冲到了热榜第六。想来大家对unbuild还是满感兴趣的。故本文再接再厉,来分析unbuild的另一项技术点:bundleless

unbuild中实现该能力是依靠的mkdist包

何为bundleless

bundleless和bundle是相对应的,即是否打包合并

在传统的webpack构建过程中,是会从入口开始,在无拆分的情况下,你得到的将是一个完整的包含所有模块内容的.js文件

而较新的vite则利用浏览器对esm的支持,在开发阶段实现了按模块进行读取,而不是加载一整个构建后的文件(注:想要了解vite实现的可以关注笔者公众号,目前正在针对vite更新系列文章

这二者的区别就是:是否合并bundle

本文目标

了解mkdist的核心实现流程

既是核心,笔者就不会对其进行细致拆分,实际上,笔者看这部分代码也是直接通过github看的。故若细节上有偏差,还望各位看官海涵

源码解析

将代码定位到src/make.ts,这是包的起点。根据笔者个人喜好,它大致可以分为如下几个阶段:初始化准备、编译、重写导入、生成入口、外部集成

  • 初始化准备

这包括参数准备。如下,默认将src/index作为入口,将dist作为出口

ts 复制代码
options.rootDir = resolve(process.cwd(), options.rootDir || ".");
options.srcDir = resolve(options.rootDir, options.srcDir || "src");
options.distDir = resolve(options.rootDir, options.distDir || "dist");

输入地准备。如下,创建一个空的dist目录。但下边这三个操作笔者个人感觉是有重复部分的,按文档来说,只需要emptyDir或者mkdirp一个操作就够了

ts 复制代码
if (options.cleanDist !== false) {
    await fse.unlink(options.distDir).catch(() => {});
    await fse.emptyDir(options.distDir);
    await fse.mkdirp(options.distDir);
}

最后就是文件目录准备。如下,mkdist将入口src下的所有文件扫描出来,并格式化处理成指定的格式

ts 复制代码
const { globby } = await import("globby");
const filePaths = await globby(options.pattern || "**", {
    absolute: false,
    cwd: options.srcDir,
});

const files: InputFile[] = filePaths.map((path) => {
    const sourcePath = resolve(options.srcDir, path);
    return {
      path,
      srcPath: sourcePath,
      extension: extname(path),
      getContents: () => fse.readFile(sourcePath, { encoding: "utf8" }),
    };
});
  • 编译

这里说的编译其实并不准确,因为它的实际编译过程其实是在unbuild中的,不过笔者看它以loader来处理,且也包含内容处理的逻辑,故以此命名

ts 复制代码
const { loadFile } = createLoader(options);

其实loader是什么并不需要关心,根据webpack的理念,它无非是针对各种文件类型的处理,事实上也确实如此

  • 重写导入

这部分包含import、require等,核心就是对路径的重写

ts 复制代码
output.contents = output.contents.replace(
    /require\((["'])(.*)(["'])\)/g,
    (_, head, id, tail) =>
      "require(" +
      head +
      resolveId(output.path, id, cjsResolveExtensions) +
      tail +
);
  • 生成入口

最后一步,就是对这些路径进行收集,将其在dist目录下创建一份,然后将其作为新的入口收集起来等待被unbuild调用即可

ts 复制代码
const writtenFiles: string[] = [];
  await Promise.all(
    outputs
      .filter((o) => !o.skip)
      .map(async (output) => {
        const outFile = join(options.distDir, output.path);
        await fse.mkdirp(dirname(outFile));
        await (output.raw
          ? copyFileWithStream(output.srcPath, outFile)
          : fse.writeFile(outFile, output.contents, "utf8"));
        writtenFiles.push(outFile);
      }),
  );
  • 外部集成

最后只需要在外部构建工具(这里指的unbuild)中集成即可实现bundleless,如下,拿到mkdist收集到的入口列表重写配置项即可

总结

通过对unbuild的分析,现在可以来呼应题目了,所谓3行指的是:

  • 一行引入

你需要在你的构建工程中引入mkdist包

  • 一行调用

你需要嵌入你的构建工程运行流程并对mkdist进行调用

  • 一行重写

你需要将mkdist的返回值作为新的入口列表重写默认的构建工具入口点配置

相关推荐
m0_7482345214 小时前
前端Vue3字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
前端·webpack·node.js
Web阿成14 小时前
3.学习webpack配置 尝试打包ts文件
前端·学习·webpack·typescript
小木_.15 小时前
【python 逆向分析某有道翻译】分析有道翻译公开的密文内容,webpack类型,全程扣代码,最后实现接口调用翻译,仅供学习参考
javascript·python·学习·webpack·分享·逆向分析
Web阿成15 小时前
5.学习webpack配置 babel基本配置
前端·学习·webpack
正小安1 天前
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
前端·vite
学前端的小朱2 天前
Echarts实现大屏可视化
websocket·echarts·nodejs·vue3·vite·koa·cors
理想不理想v3 天前
webpack最基础的配置
前端·webpack·node.js
臣妾没空3 天前
全栈里程碑二:前端基础建设
webpack
Domain-zhuo3 天前
如何利用webpack来优化前端性能?
前端·webpack·前端框架·node.js·ecmascript
初学者7.3 天前
Webpack学习笔记(2)
笔记·学习·webpack