Skip to content

electron-vite-preload.js 引入 dayjs 报错

错误如下

node:electron/js2c/sandbox_bundle:2 Unable to load preload script: D:\project\ai-client\out\preload\preload.js
(anonymous) @ node:electron/js2c/sandbox_bundle:2
node:electron/js2c/sandbox_bundle:2 Error: module not found: ./chunks/_commonjsHelpers-Bc2YnDe1.js
    at preloadRequire (node:electron/js2c/sandbox_bundle:2:151339)
    at <anonymous>:4:26
    at runPreloadScript (node:electron/js2c/sandbox_bundle:2:152003)
    at node:electron/js2c/sandbox_bundle:2:152300
    at node:electron/js2c/sandbox_bundle:2:152455
    at ___electron_webpack_init__ (node:electron/js2c/sandbox_bundle:2:152459)
    at node:electron/js2c/sandbox_bundle:2:152582

遇到的问题

通过查看 out/preload 文件夹会发现自动 chunks 一些文件,然而 vite.vite.config.mjs 不支持多入口的情况下内联打包,那么解决方案不生成 chunks,直接引入 esm 代码就不会生成 chunks 代码了

最终解决的代码:

js
// 解决dayjs自动chunks的问题
// https://chatgpt.com/c/683ff2f3-8630-800b-aacf-38b52d78a4d3
import dayjs from "dayjs/esm";
import customParseFormat from "dayjs/esm/plugin/customParseFormat";
import "dayjs/locale/zh-cn";

dayjs.locale("zh-cn");
dayjs.extend(customParseFormat);

export default function convertToISO(originalTimestamp) {
  let timestamp = originalTimestamp;

  if (timestamp.includes("昨天")) {
    const timePart = timestamp.replace("昨天 ", "");
    timestamp = dayjs().subtract(1, "day").format("YYYY年MM月DD日 ") + timePart;
  } else if (timestamp.match(/^\d{1,2}\d{1,2}/)) {
    timestamp = dayjs().format("YYYY年") + timestamp;
  } else if (timestamp.match(/^\d{1,2}:\d{1,2}(:\d{1,2})?$/)) {
    // 如果只有时分,没有秒,则补充秒数为 :00
    if (!timestamp.match(/\d{1,2}:\d{1,2}:\d{1,2}/)) {
      timestamp += ":00";
    }
    timestamp = dayjs().format("YYYY年MM月DD日 ") + timestamp;
  }

  let parsedDate = dayjs(timestamp, "YYYY年MM月DD日 HH:mm:ss");

  if (parsedDate.isValid()) {
    return parsedDate.toISOString();
  }

  console.error(
    "无法解析的时间戳:",
    originalTimestamp,
    "解析后的值:",
    timestamp
  );
  return originalTimestamp;
}

解决方案

在 Vite 中引入 dayjs 时出现_commonjsHelpers-xxx.js文件的原因是因为 dayjs 默认使用的是 CommonJS 模块格式。Vite 会对这些 CommonJS 格式的模块做转换,以便在 ES 模块环境中使用,因此生成了一个用于辅助 CommonJS 转换的_commonjsHelpers文件。

为什么会出现这个文件?

  • CommonJS 到 ES 模块转换:dayjs 默认发布包使用 CommonJS 格式,而 Vite 是 ES 模块优先的工具。
  • Rollup 处理 CommonJS 依赖:Vite 底层使用 Rollup 打包,Rollup 的@rollup/plugin-commonjs负责对 CommonJS 模块进行转换,这个过程需要辅助文件。

如何避免或优化?

  1. 直接引用 ES 模块

    js
    import dayjs from "dayjs/esm";

    这样可以直接引用 dayjs 的 ESM 版本,避免 CommonJS 转换。

  2. 使用 CDN 或手动引用: 如果不希望生成辅助文件,可考虑通过 CDN 方式或将 dayjs 的 ES 版本单独引入,减少构建过程中的转换。

  3. 配置优化(推荐方式): 在vite.config.js中进行优化:

    js
    export default {
      optimizeDeps: {
        include: ["dayjs"],
      },
      build: {
        commonjsOptions: {
          include: [/dayjs/, /node_modules/],
        },
      },
    };

    这样可以明确告知 Vite 优化对 dayjs 的引入,减少生成额外文件的影响。

推荐实践:

最简单高效的办法是使用 dayjs 的 ES 模块版:

bash
npm install dayjs
js
import dayjs from "dayjs/esm";

这种方式下,构建更加高效和干净,避免生成冗余的转换文件。