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

Nuxt3 LiveChat插件开发环境正常生产环境报错求助

Nuxt3生产构建后Odoo在线聊天插件加载失败问题排查与修复

问题描述

开发了一个Nuxt3聊天插件(文件名为chat.client.ts),开发模式下运行正常,但生产构建后出现故障。已替换URL保护企业信息,确认脚本加载正常、网络无问题且版本一致,但报错仍存在。

插件代码

const cssLink = document.createElement("link");
cssLink.rel = "stylesheet";
cssLink.href = "https://x.com/im_livechat/external_lib.css";
document.head.appendChild(cssLink);

const script = document.createElement("script");
script.src = "https://x.com/im_livechat/external_lib.js";

script.onload = () => {
    odoo.define("web.session", function (require) {
        const Session = require("web.Session");
        const modules = odoo._modules;
        return new Session(undefined, "https://x.com", { modules: modules, use_cors: true });
    });
    odoo.define("im_livechat.livesupport", function (require) {
        const rootWidget = require("root.widget");
        const im_livechat = require("im_livechat.legacy.im_livechat.im_livechat");
        const button = new im_livechat.LivechatButton(rootWidget, "https://x.com", {
            header_background_color: "#4E6C62",
            button_background_color: "#4E6C62",
            title_color: "#FFFFFF",
            button_text_color: "#FFFFFF",
            button_text: "Chat",
            input_placeholder: false,
            default_message: "Hello, before we continue, can I please have your email address ?",
            channel_name: "Main Chat",
            channel_id: 1,
            current_partner_id: 4,
            default_username: "Visitor",
        });
        button
            .appendTo(document.body)
            .then(() => {
                window.livechat_button = button;
                // Ensure the button is properly appended before triggering the click
                nextTick();
            })
            .catch((error) => {
                console.error("Failed to append the livechat button:", error);
            });
    });
};
document.body.appendChild(script);

报错信息

TypeError: Cannot read properties of undefined (reading 'static')

external_lib.js:3296 Undefined dependency:  web.Session
require @ external_lib.js:3296
(anonymous) @ BcV-9UXX.js:58
(anonymous) @ external_lib.js:3292
processJob @ external_lib.js:3292
odoo.processJobs @ external_lib.js:3300
odoo.define @ external_lib.js:3278
t.onload @ BcV-9UXX.js:58
load (async)
(anonymous) @ BcV-9UXX.js:58
iI @ BcV-9UXX.js:58
(anonymous) @ BcV-9UXX.js:18
r @ BcV-9UXX.js:18
runWithContext @ BcV-9UXX.js:14
sw @ BcV-9UXX.js:18
(anonymous) @ BcV-9UXX.js:18
run @ BcV-9UXX.js:10
runWithContext @ BcV-9UXX.js:18
rw @ BcV-9UXX.js:18
a @ BcV-9UXX.js:18
ow @ BcV-9UXX.js:18
await in ow (async)
Lp @ BcV-9UXX.js:63
(anonymous) @ BcV-9UXX.js:63
external_lib.js:3291 Error while loading web.session: r is not a constructor TypeError: r is not a constructor
    at BcV-9UXX.js:58:45150
    at external_lib.js:3292:63
    at new Promise (<anonymous>)
    at processJob (external_lib.js:3292:9)
    at odoo.processJobs (external_lib.js:3300:1)
    at odoo.define (external_lib.js:3278:161)
    at t.onload (BcV-9UXX.js:58:45069)
...
external_lib.js:3296 Undefined dependency:  im_livechat.legacy.im_livechat.im_livechat

问题原因

  1. 生产构建的代码混淆:Nuxt3生产构建时会对代码进行压缩、混淆和tree-shaking,导致Odoo模块系统依赖的变量名、模块路径被篡改,无法正常解析web.Session等依赖。
  2. 脚本加载时序问题:开发模式下代码未压缩,外部脚本加载完成后Odoo模块系统已完全初始化;生产模式下代码合并后,script.onload触发时Odoo内部模块可能还未准备就绪,直接调用odoo.define会导致依赖找不到。
  3. DOM初始化时机:插件代码直接在顶层执行,未等待Nuxt的客户端DOM完全初始化,生产模式下DOM渲染时序和开发模式有差异,导致脚本插入时机过早。

解决方案

1. 禁用Nuxt对插件文件的代码混淆

在nuxt.config.ts中配置Vite,避免混淆chat.client.ts文件,保留原始变量和模块名:

export default defineNuxtConfig({
  vite: {
    build: {
      terserOptions: {
        mangle: {
          // 排除插件文件,避免变量名被混淆
          exclude: ['chat.client.ts']
        }
      }
    }
  }
})

2. 确保Odoo模块加载时序正确

修改script.onload逻辑,先等待Odoo核心模块初始化完成,再执行模块定义:

script.onload = async () => {
  // 等待web.Session模块可用
  await new Promise(resolve => {
    const checkModule = () => {
      if (odoo?._modules?.['web.Session']) {
        resolve(true);
      } else {
        setTimeout(checkModule, 100);
      }
    };
    checkModule();
  });

  odoo.define("web.session", function (require) {
    const Session = require("web.Session");
    const modules = odoo._modules;
    return new Session(undefined, "https://x.com", { modules: modules, use_cors: true });
  });

  // 等待im_livechat模块可用
  await new Promise(resolve => {
    const checkLivechatModule = () => {
      if (odoo?._modules?.['im_livechat.legacy.im_livechat.im_livechat']) {
        resolve(true);
      } else {
        setTimeout(checkLivechatModule, 100);
      }
    };
    checkLivechatModule();
  });

  odoo.define("im_livechat.livesupport", function (require) {
    const rootWidget = require("root.widget");
    const im_livechat = require("im_livechat.legacy.im_livechat.im_livechat");
    const button = new im_livechat.LivechatButton(rootWidget, "https://x.com", {
      header_background_color: "#4E6C62",
      button_background_color: "#4E6C62",
      title_color: "#FFFFFF",
      button_text_color: "#FFFFFF",
      button_text: "Chat",
      input_placeholder: false,
      default_message: "Hello, before we continue, can I please have your email address ?",
      channel_name: "Main Chat",
      channel_id: 1,
      current_partner_id: 4,
      default_username: "Visitor",
    });
    button
      .appendTo(document.body)
      .then(() => {
        window.livechat_button = button;
        nextTick();
      })
      .catch((error) => {
        console.error("Failed to append the livechat button:", error);
      });
  });
};

3. 使用Nuxt客户端生命周期钩子执行DOM操作

将插件代码放在onMounted钩子中,确保DOM完全初始化后再加载外部资源:

export default defineNuxtPlugin(() => {
  onMounted(() => {
    const cssLink = document.createElement("link");
    cssLink.rel = "stylesheet";
    cssLink.href = "https://x.com/im_livechat/external_lib.css";
    document.head.appendChild(cssLink);

    const script = document.createElement("script");
    script.src = "https://x.com/im_livechat/external_lib.js";

    // 这里放入上面修改后的script.onload逻辑
    script.onload = async () => {
      // ... 等待模块初始化的代码
    };
    document.body.appendChild(script);
  });
});

4. 预加载外部脚本确保执行顺序

在nuxt.config.ts中配置预加载外部脚本,确保在插件代码执行前完成加载:

export default defineNuxtConfig({
  app: {
    head: {
      link: [
        {
          rel: "stylesheet",
          href: "https://x.com/im_livechat/external_lib.css"
        }
      ],
      script: [
        {
          src: "https://x.com/im_livechat/external_lib.js",
          body: true,
          defer: true,
          // 指定加载完成后执行的全局函数
          onload: "initLivechat()"
        }
      ]
    }
  }
});

然后在chat.client.ts中定义全局初始化函数:

(window as any).initLivechat = async () => {
  // 放入原来的odoo模块定义逻辑
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:27:01