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 模块进行转换,这个过程需要辅助文件。
如何避免或优化?
直接引用 ES 模块:
jsimport dayjs from "dayjs/esm";
这样可以直接引用 dayjs 的 ESM 版本,避免 CommonJS 转换。
使用 CDN 或手动引用: 如果不希望生成辅助文件,可考虑通过 CDN 方式或将 dayjs 的 ES 版本单独引入,减少构建过程中的转换。
配置优化(推荐方式): 在
vite.config.js
中进行优化:jsexport default { optimizeDeps: { include: ["dayjs"], }, build: { commonjsOptions: { include: [/dayjs/, /node_modules/], }, }, };
这样可以明确告知 Vite 优化对 dayjs 的引入,减少生成额外文件的影响。
推荐实践:
最简单高效的办法是使用 dayjs 的 ES 模块版:
bash
npm install dayjs
js
import dayjs from "dayjs/esm";
这种方式下,构建更加高效和干净,避免生成冗余的转换文件。