使用本地替换调试 JavaScript 网页资源

在模型驱动应用中开发和调试用作事件处理程序的 JavaScript Web 资源时,通常需要进行多项更改并测试它们的工作方式。 每次更改后上传和发布 Web 资源都会减慢此过程。

新式浏览器开发人员工具提供保存 Web 资源的本地副本的功能。 当模型驱动应用请求 Web 资源时,浏览器会加载你的本地副本,而不是服务器上的文件。 可以编辑本地副本、刷新页面并测试更改,而无需重复上传和发布 Web 资源。 无需安装代理软件、浏览器扩展或证书。

详细了解新式浏览器如何提供这些功能。

Important

本地替代仅更改浏览器加载的资源。 它不会更新Microsoft Dataverse中的 JavaScript Web 资源,其他用户不会看到你的更改。 完成故障排除后,将想要保留的更改复制到源文件中,并使用正常过程更新和发布 Web 资源。 本文不介绍该过程。

Prerequisites

开始之前:

  • 需要一个模型驱动应用,该应用具有用于为窗体提供事件处理程序的 JavaScript Web 资源。

    本文使用 编写第一个客户端脚本中所述的 JavaScript Web 资源。 该演练创建一个名为 example_form-script.jsJavaScript Web 资源,将其添加到帐户窗体,并为窗体“加载时”和“保存时”事件以及“名称”列“更改时”事件注册函数。

    注释

    可以下载 JavaScriptWebResourceExampleSolution_1_0_managed.zip。 安装此托管解决方案后,您将获得一个模型驱动的应用程序,该应用程序展示了编写您的第一个客户端脚本分步指南文章中的最终成果。

  • 本文使用Microsoft Edge,但 Google Chrome、Firefox 和 Safari 开发人员工具具有类似的功能。

  • 在计算机上创建一个空文件夹,供 Microsoft Edge DevTools 存储本地覆盖。 不要使用包含源文件、凭据、证书或其他敏感信息的文件夹。 DevTools 会在此文件夹内创建其所需的文件夹结构。 本文使用 C:\temp\overrides ,但你可能想要使用 C:\Users\<your user name>\overrides。

本文使用了 编写第一个客户端脚本 中的此脚本:

// Define a unique namespace for the sample library.
window.Example ??= {};

(() => {
    const notificationId = "_myUniqueId";
    const currentUserName = Xrm.Utility.getGlobalContext().userSettings.userName;
    const message = `${currentUserName}: Your JavaScript code in action!`;

    // Code to run in the form OnLoad event
    window.Example.formOnLoad = (executionContext) => {
        const formContext = executionContext.getFormContext();

        // Display the form level notification as an INFO
        formContext.ui.setFormNotification(message, "INFO", notificationId);

        // Wait for 5 seconds before clearing the notification
        window.setTimeout(
            () => formContext.ui.clearFormNotification(notificationId),
            5000
        );
    };

    // Code to run in the column OnChange event
    window.Example.attributeOnChange = (executionContext) => {
        const formContext = executionContext.getFormContext();

        // Automatically set some column values if the account name contains "Contoso"
        const accountName = formContext.getAttribute("name").getValue();
        if (accountName?.toLowerCase().includes("contoso")) {
            formContext.getAttribute("websiteurl").setValue("https://www.contoso.com");
            formContext.getAttribute("telephone1").setValue("425-555-0100");
            formContext.getAttribute("description").setValue("Website URL, Phone and Description set using custom script.");
        }
    };

    // Code to run in the form OnSave event
    window.Example.formOnSave = () => {
        // Display an alert dialog
        Xrm.Navigation.openAlertDialog({ text: "Record saved." });
    };
})();

此 JavaScript Web 资源提供三个为以下事件注册的函数:

函数 Event
Example.formOnLoad Form OnLoad
Example.attributeOnChange 字段更改时
Example.formOnSave 窗体 OnSave

这些步骤也适用于注册为表单事件处理程序的任何 JavaScript Web 资源。 使用您的 Web 资源名称,并在步骤引用示例时触发其事件。

确认已发布的脚本正常工作

在创建覆盖之前,请确认已发布 Web 资源的当前行为:

  1. 在Microsoft Edge中打开模型驱动应用。

  2. 打开现有帐户记录或创建新的帐户记录。

  3. 确认类似于以下消息的窗体通知显示五秒:

    <Your Name>: Your JavaScript code in action!

此步骤确认表单加载 Web 资源并调用 Example.formOnLoad 事件处理程序。

设置本地覆盖

您仅需在 Microsoft Edge 浏览器配置文件中首次使用“本地覆盖”时选择一个覆盖文件夹。

  1. 打开帐户窗体后,按 F12 或 Ctrl+Shift+I 打开 DevTools。

  2. 选择 “来源” 工具。

  3. 在导航器窗格中,选择覆盖选项卡。如果该选项卡不可见,请选择更多选项卡,然后选择覆盖。

  4. 选择选择覆盖文件夹。

  5. 选择你为覆盖项创建的空文件夹,然后选择选择文件夹。

  6. 当 DevTools 请求对文件夹的完全访问权限时,请选择 “允许”。

    请求对“Local Overrides”文件夹进行完全访问权限的 DevTools 提示的屏幕截图。

  7. 确认已选择“启用本地覆盖”。

    以下是选择覆盖文件夹后“源”工具“覆盖”选项卡的屏幕截图,显示已选中“启用本地覆盖”。

为服务辅助角色启用网络绕过

Important

启用网络绕过可确保 DevTools 本地覆盖生效,方法是阻止服务辅助角色提供缓存响应。 如果不执行此步骤,本地覆盖在模型驱动应用中将无法生效。

  1. 在 DevTools 中,选择“应用程序”选项卡。

    如果该选项卡不可见,请选择 +(更多选项卡),然后选择应用程序。

  2. 在左侧导航窗格中,选择 Service Workers。

  3. 选择网络绕过,以强制请求绕过服务辅助角色并改用网络。

    “服务辅助角色”窗格中已选中“绕过网络”的截图。

  4. 刷新页面以应用更改。

为 Web 资源创建覆盖规则

使用 网络 工具查找帐户表单加载的 JavaScript 文件:

  1. 选择“网络”工具。

  2. 如果未记录网络活动,请选择“ 记录网络日志”。

  3. 刷新页面,以便窗体再次加载 Web 资源。

  4. 在 “筛选器 ”框中,开始键入 Web 资源的名称,例如: example_form-script.js。

  5. 在网络请求列表中,右键单击 example_form-script.js,然后选择覆盖内容。

    已筛选为 example_form-script.js 的网络工具的屏幕截图,其中选择了“替代内容”命令。

  6. 选择来源工具,然后选择覆盖选项卡。

  7. 展开 DevTools 创建的文件夹,然后选择 example_form-script.js。

    “覆盖”选项卡中 example_form-script.js 的屏幕截图,其中包含紫色覆盖指示器。

    DevTools 将 Web 资源复制到 overrides 文件夹中。 文件图标上的紫色点表示 DevTools 已重写资源。

提示

还可以从“页面”选项卡创建覆盖项,该选项卡位于“源”工具中。 找到 Web 资源,右键单击它,然后选择“覆盖内容”。

验证Microsoft Edge加载本地副本

进行一项易于识别的更改,以便确认覆盖功能是否正常工作:

  1. 在 DevTools 编辑器中,找到以下行:

    const message = `${currentUserName}: Your JavaScript code in action!`;
    
  2. 将其替换为以下行:

    const message = `${currentUserName}: Local override in action!`;
    

    注释

    如果尝试将代码粘贴到 DevTools 编辑器中,将看到此对话框。 您需要输入 allow pasting 并选择允许才能继续。 如果直接键入更改,则不会显示此对话框。

    DevTools 粘贴警告对话框的屏幕截图,其中显示了“允许”按钮。

  3. 将通知持续时间从 5000 更改为 15000。

  4. 按 Ctrl+S 保存本地文件。

  5. 刷新账户表单。

  6. 确认通知显示 本地覆盖已生效! 并保持可见 15 秒。

    帐户窗体通知的屏幕截图,其中显示了“本地替代”生效情况。

消息和持续时间的变化确认 Microsoft Edge 加载了本地覆盖,而不是已发布的 Web 资源。

调试事件处理程序

确认重写正常工作后,使用 DevTools 调试器调查脚本。

调试表单 OnLoad 事件

  1. 在 “源” 工具中,打开被覆盖的 example_form-script.js 文件。

  2. 选择此语句的行号以设置断点:

    DevTools 编辑器的屏幕截图,其中包含 Example.formOnLoad 事件处理程序中的断点。

  3. 刷新账户表单。

  4. 脚本执行暂停时,使用 “作用域 ”窗格检查 executionContext 和 formContext。

    DevTools 作用域窗格的屏幕截图,其中显示了 executionContext 和 formContext 值。

  5. 单步执行函数并观察对 setFormNotification函数的调用。

  6. 选择恢复脚本执行以继续。

调试帐户名称 OnChange 事件

  1. 在此语句中 Example.attributeOnChange设置断点:

    const accountName = formContext.getAttribute("name").getValue();
    
  2. 在帐户窗体中,更改 帐户名称,然后将焦点移开列以触发 On Change 事件。

  3. 执行暂停时,检查值 accountName。

    在检查 accountName 时,Example.attributeOnChange 事件处理程序中暂停的 DevTools 的屏幕截图。

  4. 使用包含 Contoso的帐户名并单步执行函数来观察脚本如何设置网站、主电话和说明值。

调试窗体 OnSave 事件

  1. 在 Example.formOnSave 中的 Xrm.Navigation.openAlertDialog 语句上设置断点。

  2. 保存记录。

  3. 执行暂停时,检查调用堆栈以确认窗体保存时事件是否调用了预期的函数。

    在 Example.formOnSave 事件处理程序中暂停的 DevTools 调试器调用堆栈的屏幕截图。

  4. 恢复脚本执行并确认警报对话框打开。

您可以随时编辑并保存覆盖设置,以测试可能的修复方案。 刷新窗体以测试对在窗体加载时运行的代码的更改。 触发相关窗体或列事件以测试其他事件处理程序。 使用 控制台 工具查看错误和记录输出。

将覆盖与已发布的 Web 资源进行比较

若要确认问题是否由本地更改导致:

  1. 在源工具中,选择覆盖选项卡。
  2. 取消选中“启用本地覆盖”。
  3. 刷新帐户窗体并再次测试事件。

Microsoft Edge现在从服务器加载已发布的 Web 资源。 选择“启用本地覆盖”并刷新窗体以继续使用本地副本。

完成故障排查

本地覆盖文件与 Dataverse 中的 Web 资源或解决方案的源文件均无关联。

  1. 将要保留的更改从覆盖文件复制到用于维护 Web 资源的源文件中。
  2. 使用正常的开发和部署过程更新和发布 JavaScript Web 资源。
  3. 在取消选中 “启用本地替代” 的情况下测试已发布的 Web 资源。
  4. 如果不再需要覆盖配置,请在“覆盖项”选项卡中选择“清除配置”。

Caution

不要将 overrides 文件夹中的文件视为 Web 资源的源文件。 在清除配置或删除本地替代文件之前,请保留要保留的任何更改。

排查本地覆盖问题

以下是使用本地替代时可能会遇到的问题。

Web 资源未显示在“网络”工具中

确认网络工具正在记录、清除任何筛选器并刷新窗体。 窗体必须在显示之前加载 Web 资源。 此外,还确认 JavaScript 库已添加到窗体中,并发布表单自定义项。

“覆盖内容”命令不可用

返回到 Sources 工具,确认你选择了替换文件夹、允许 DevTools 访问它,然后选择“启用本地替换”。 然后刷新表单并重试。

窗体仍使用已发布的脚本

使 DevTools 保持打开状态,确认已选择“ 启用本地替代 ”,并验证 Web 资源在 “网络 ”或 “源 ”工具中是否有紫色点。 保存覆盖设置,然后刷新窗体。

未命中断点

确认在重写的文件中设置了断点,并且该断点显示为已启用。 触发与该函数关联的事件:对于On Load,刷新窗体;对于On Change,更改已配置的列;对于On Save,保存记录。 另请查看 控制台 工具,检查是否存在阻止脚本加载的语法错误。