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

如何配置 Transcrypt 并修复 hello.js 404 与编译 ImportError?

Transcrypt 编译异常与页面输出解决方案

点击按钮无反应的直接原因是Python源码编译失败,未生成__target__/hello.js,浏览器加载模块时返回404,导致hello.FUN方法不存在。以下是完整流程说明与修复方案:

完整配置与编译流程

1. 环境准备

Transcrypt对CPython小版本兼容性要求较高,建议使用独立虚拟环境部署,避免全局包干扰:

  • Python 3.9及以上版本,需搭配Transcrypt 3.9.0及以上版本
  • Python 3.8及以下版本,可使用3.9以下的Transcrypt稳定版

2. 项目结构

创建独立的项目文件夹,避免与其他Python项目文件混杂,基础结构如下:

your-project/
├── hello.py   # Python业务源码
└── hello.html # 前端测试页面

编译完成后会自动生成__target__目录,存放编译后的JS、运行时依赖、source map等产物。

3. 执行编译

在项目根目录激活虚拟环境后,执行编译命令即可生成目标JS文件。

4. 页面测试

HTML引入编译后的模块文件后,在项目根目录启动静态HTTP服务访问即可,禁止直接用file://协议打开,否则会触发ES模块的跨域限制。

编译命令参数说明

python -m transcrypt -b -m -n hello.py各部分含义如下:

  • python -m transcrypt:将Transcrypt作为Python模块启动,避免环境变量配置错误导致的版本、路径异常
  • -b, --build:触发编译构建动作,自动扫描源码的导入依赖,生成对应目标JS产物
  • -m, --map:生成Source Map映射文件,开发调试时可在浏览器开发者工具中直接定位到Python源码,无需阅读编译后的混淆JS
  • -n, --nominify:关闭JS压缩混淆,输出格式化的可读代码,适合开发阶段使用;生产部署可移除该参数以减小产物体积
  • 末尾的hello.py为待编译的Python入口源码路径

locale/_bootlocale 导入错误修复

该报错由版本不兼容或全局环境包污染导致,按以下优先级依次修复:

1. 升级至兼容版本

CPython 3.9重构了底层locale模块结构,3.9.0之前的Transcrypt无法适配新结构,会触发整条导入链异常。执行以下命令升级:

pip3 uninstall -y transcrypt
pip3 install transcrypt>=3.9.0

若系统源无法安装新版Transcrypt,可将本地Python降级至3.8.x,旧版Transcrypt对Python 3.8兼容性正常。

2. 虚拟环境隔离全局依赖

全局Python环境中安装的无关第三方包(如报错链中出现的wget包)会被Transcrypt的模块解析器误扫描,触发异常。使用独立虚拟环境即可隔离干扰:

# 在项目根目录创建虚拟环境
python3 -m venv venv
# 激活虚拟环境
source venv/bin/activate
# 虚拟环境内安装Transcrypt
pip install transcrypt
# 激活状态下重新编译
python -m transcrypt -b -m -n hello.py

3. 排查本地文件命名冲突

检查项目源码目录下是否存在与Python标准库重名的文件,如locale.py、datetime.py、time.py、random.py等。Transcrypt编译时会优先读取本地目录文件,重名会导致导入逻辑异常,将冲突文件重命名即可。

编译成功后,__target__目录会正常生成,其中包含入口文件hello.js与运行时依赖,刷新页面即可解决JS文件的404问题。日志中favicon.ico的404为浏览器自动请求网站图标导致,与功能无关,无需处理。

将函数输出渲染到页面元素

注意:浏览器为单线程运行环境,不存在Python标准库中阻塞式的time.sleep,直接移植原代码会导致整个页面卡死。
需要用浏览器原生异步API重写等待逻辑,同时直接操作DOM将输出写入指定元素。

修改后的hello.py代码

from datetime import datetime
import random
from asyncio import get_event_loop
from js import setTimeout, document

# 异步睡眠方法,替代阻塞式time.sleep
async def sleep(sec):
    loop = get_event_loop()
    future = loop.create_future()
    setTimeout(lambda: future.set_result(None), sec * 1000)
    await future

async def FUN():
    # 获取页面输出节点
    fun_box = document.getElementById("FUN")
    fun_box.innerHTML = ""
    # 等待时长可按需修改,原逻辑为10-30秒
    for i in range(random.randrange(1, 9)):
        await sleep(random.randrange(1, 3))
        content = f"Current time {datetime.now()} , Number {i}<br>"
        fun_box.innerHTML += content

说明:

  • Transcrypt内置js模块,可直接调用所有浏览器原生JS API
  • 异步写法基于Python原生async/await语法,编译后对应JS异步逻辑,不会阻塞页面响应
  • 默认print方法只会将内容输出到浏览器控制台,不会渲染到页面,因此直接操作DOM节点插入内容

修正后的hello.html代码

修复原代码标签嵌套不规范问题,将模块脚本放在页面底部,避免DOM未加载完成导致的获取节点失败:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Transcrypt Demo</title>
</head>
<body>
  <div id="FUN">...</div>
  <button onclick="hello.FUN()">Do code</button>

  <script type="module">
    import * as hello from './__target__/hello.js';
    window.hello = hello;
  </script>
</body>
</html>

验证步骤

  • 重新执行编译命令,确认__target__/hello.js正常生成
  • 在项目根目录执行python3 -m http.server启动静态服务
  • 浏览器访问http://localhost:8000/hello.html,点击按钮即可看到内容逐行输出到指定div中

内容的提问来源于stack exchange,提问作者h3ll0tity

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 07:06:05