html 将客户端代码Map到源代码不起作用

qcbq4gxm  于 2023-04-04  发布在  其他
关注(0)|答案(1)|浏览(186)

我创建一个简单的Web应用程序使用谷歌应用程序脚本,我想添加客户端代码的源代码,这样我就可以使用它进行调试,如果我有错误等

更新:编辑器中的代码结构

这是我的密码。
code.gs

function doGet(){
  return HtmlService.createTemplateFromFile('index')
  .evaluate()
  .setTitle('APP')
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <?!= include('importsJs'); ?>
  <?!= include('other/employee/scripts'); ?>
  <?!= include('other/jobs/scripts'); ?>
  <title>Document</title>
</head>
<body>
  
</body>
</html>

我在互联网上学到了如何在开发工具中将客户端代码Map到源代码,我只需要添加//# sourceURL = filename.js
employees的html文件(other/employee/scripts)如下所示

<script>
var employees = [{ name: 'Charlie', position: 'Sales' }];

console.log(employees)

//# sourceURL=employee.js
</script>

jobs的html文件(other/jobs/scripts)如下所示

<script>
var employees = [{ name: 'Charlie', position: 'Sales' }];

console.log(employees)

//# sourceURL=employee.js
</script>

下面是编辑器demo中的源代码
预期的结果是,当你点击usercodepanel时,它应该显示给予控制台日志结果的代码行,因为现在当你点击它时,它是空的:(这对调试非常不利

Live demo

注意:我使用doT.js库动态加载JavaScript文件。
UPDATE:在我的本地机器上,源代码如下,我使用clasp部署我的项目

source codes
上面的解决方案没有给予我我想要的,我需要做什么才能得到预期的结果?

2sbarzqh

2sbarzqh1#

您遇到的问题是,在部署时,App Script会删除HTML、CSS和JavaScript中的所有静态注解,以优化您的网站。但说实话,它这样做过于激进和天真,删除代码中任何出现的“//...”,即使它位于模板字符串中,实际上它是有效的。
因此,没有简单的切换来使其工作,但有一个非常hacky的变通方法。不要在代码中静态包含“//”,而是在页面加载时动态地将其与脚本一起插入HTML。要做到这一点,我们可以在App Script中编写一个名为importScript()的辅助函数,它输出一个脚本,该脚本本身将一个带有sourceURL和您的代码的脚本注入到HTML中。
下面是importScript()的实现:

// in Code.gs
function includeFile(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}

function stripScriptTags(script) {
  const OPEN_TAG = "<script>",
        CLOSE_TAG = "</script>",
        start = script.indexOf(OPEN_TAG),
        end = script.lastIndexOf(CLOSE_TAG);
  if (start === -1 || end === -1) throw new Error("Encountered malformed script");
  return script.slice(start + OPEN_TAG.length, end).trim();
}

function includeScript(filename, sourceURL) {
  const scriptContent = stripScriptTags(includeFile(filename));
  const escapedScriptStr = scriptContent.replace(/[`$]/g, '\\$&');

  return `
    <script>
      var newScript = document.createElement("script");
      newScript.text = "!!# sourceURL=${sourceURL}".replaceAll("!","/"); 
      newScript.text += "\\n" + \`${escapedScriptStr}\`;
      document.currentScript.insertAdjacentElement("afterend", newScript);
    </script>
  `;
}

要使用它,只需更新您的Index.html以调用includeScript(),并使用脚本的文件名和您想要使用的源URL:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?!= includeScript('other/jobs/scripts', 'jobs.js'); ?>
    <?!= includeScript('other/employee/scripts', 'employee.js'); ?>
    <title>Document</title>
  </head>
  <body>
  </body>
</html>

然后只需部署您的应用脚本,现在您应该在控制台中看到以下内容:

Here is my own App Script that demos it working with sourceURL .

注意:如果导入的脚本只包含一个script标签,则上述方法有效。否则,文件中的所有其他HTML都会被截断。

然而,这里有一个更复杂的importScripts()版本,它可以在文件中使用任意HTML(多个标签),还有一个demo

function includeScript(filename, sourceURL) {
  scriptContent = includeFile(filename)
    .replace(/<script>/g, '<script data-to-clone>')
    .replace(/<\/script>/g, '<\\/script>')
    .replace(/[`$]/g, '\\$&').trim();

  return `
    <script>
      document.currentScript.insertAdjacentHTML("afterend", \`${scriptContent}\`);
    </script>
    <script>
      var _temp = Array.from(document.querySelectorAll("script[data-to-clone]"));
      _temp.reverse();
      _temp.forEach((scriptClone) => {
        scriptClone.removeAttribute("data-to-clone");

        const newScript = document.createElement("script");
        newScript.text = "/" + "/# sourceURL=${sourceURL}";
        newScript.text += "\\n" + scriptClone.text.trim();
        document.currentScript.insertAdjacentElement("afterend", newScript);

        scriptClone.setAttribute("data-is-cloned", "");
      });
    </script>
  `;
}

相关问题