You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决esbuild无法打包KotlinJS生成的ES模块hiom的问题

解决esbuild打包KotlinJS生成的ES模块hiom的兼容问题

问题根源

KotlinJS通过useEsModules()生成的ESM输出中,可能混合了ESM语法与CommonJS风格的动态require调用,导致esbuild处理时出现识别冲突:既无法将其作为纯ESM打包(触发external要求),标记external后运行时又因环境不支持动态require报错。


可行解决方案

方案1:注入shim兼容动态require

通过esbuild的inject功能,为运行环境添加一个兼容ESM的require模拟,让hiom中的动态require调用转为合法的import():

  1. 创建require-shim.js文件:
window.require = async (modulePath) => {
  const module = await import(modulePath);
  return module.default || module;
};
  1. 修改esbuild配置:
module.exports = {
  entryPoints: ['src/index.js'],
  bundle: true,
  format: 'esm',
  outfile: 'dist/bundle.js',
  inject: ['./require-shim.js'], // 注入shim处理动态require
  external: [], // 不将hiom设为external
  resolveExtensions: ['.mjs', '.js'], // 优先识别KotlinJS的ESM文件
};
  1. 确保index.html用ESM方式加载打包文件:
<script type="module" src="dist/bundle.js"></script>

方案2:优化KotlinJS的ESM输出配置

调整KotlinJS的构建脚本,强制生成更纯净的ESM代码,避免动态require:

// build.gradle.kts
kotlin {
  js(IR) {
    browser {
      commonWebpackConfig {
        configureWebpack {
          resolve.set("extensions", listOf(".mjs", ".js"))
          output.set("libraryTarget", "module")
        }
      }
    }
    binaries.executable()
    useEsModules()
    // 禁用CommonJS风格的模块生成
    compilations.all {
      kotlinOptions {
        moduleKind = "es"
      }
    }
  }
}

同时检查Kotlin代码,将所有kotlin.js.require调用替换为ESM的import()语法。

方案3:配置esbuild优先识别ESM入口

告诉esbuild优先读取hiom的ESM入口文件:

// esbuild.config.js
module.exports = {
  entryPoints: ['src/index.js'],
  bundle: true,
  format: 'esm',
  outfile: 'dist/bundle.js',
  external: [],
  resolveExtensions: ['.mjs', '.js'], // 优先加载.mjs格式的ESM文件
  mainFields: ['module', 'main'], // 优先读取package.json的module字段
};

如果hiom的package.json没有module字段,手动添加并指向其ESM入口文件(比如"module": "./kotlin/hiom.mjs")。

方案4:预转译hiom为纯净ESM

先用esbuild单独转译hiom,再纳入主项目打包:

  1. 执行转译命令:
esbuild node_modules/hiom/kotlin/my-project-applications-my-server.js --format=esm --outfile=node_modules/hiom/kotlin/my-project-applications-my-server-esm.mjs
  1. 在主项目配置中添加别名,指向转译后的文件:
module.exports = {
  entryPoints: ['src/index.js'],
  bundle: true,
  format: 'esm',
  outfile: 'dist/bundle.js',
  alias: {
    'hiom/kotlin/my-project-applications-my-server': 'hiom/kotlin/my-project-applications-my-server-esm.mjs'
  },
  external: []
};

验证注意事项

  • 清理node_modules和dist目录,重新构建避免缓存干扰
  • 确保项目package.json中已设置"type": "module"

内容的提问来源于stack exchange,提问作者Jan Vladimir Mostert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:40:15