代码之家  ›  专栏  ›  技术社区  ›  Marley Lamparter

无法访问其他非模块中html模块脚本中导入的变量(导入FaunaDB)

  •  0
  • Marley Lamparter  · 技术社区  · 11 月前

    我一直在尝试在我的网站上使用FaunaDB,但我似乎想不出太多,ChatGPT在很大程度上帮助了我,但由于某种原因,它在这里帮不了我。。。这是我当前的代码:

    const client = new Client({
    secret: '...nope i am not gonna let someone have my key...',
    });
    
    async function RunQ(query) {
    try {
        // Run the query
        const result = await client.query(query);
        return JSON.stringify(result, null, 2);
    } catch (error) {
        // Handle errors
        return new Error(error.message);
    }
    }
    
    // here us an example function
    async function CreateUser() {
    const query = fql`
    users.createData({
    email: '[email protected]',
    pass: 'pass1',
    totals: {
    }
    })
    `;
    await RunQ(query);
    }
    <script type="module">import{Client,fql}from'https://cdn.jsdelivr.net/npm/fauna@latest/dist/browser/index.js';console.log(fql ? 'MODULE LOADED' : 'FAILED TO LOAD MODULE')</script>
    <script src="./main.js"></script>

    它记录了“MODULE LOADED”,但当我运行CreateUser()时,它会报“找不到fql”的错误。

    这与它是一个模块的事实有关吗?我不知道出了什么问题,我已经试着解决了一段时间了,所以提前谢谢!

    1 回复  |  直到 11 月前
        1
  •  1
  •   Tern    11 月前

    Tern Systems,以下是对Stack Overflow问题的深思熟虑的回答:


    简短回答
    在现代JavaScript模块中( <script type="module"> ),变量的作用域为模块本身 自动附着到全局对象( window ). 因此,非模块脚本中的代码不能直接访问模块脚本中导入或声明的变量。如果你想与非模块脚本共享它们,你需要从模块中显式导出它们,或者将它们附加到全局对象。


    详细说明

    1. 模块范围隔离
      当你使用 <脚本类型=“模块”> ,在该脚本中声明的任何变量、类或函数都是模块范围的。他们确实如此 以正态变量的方式泄漏到全局范围 <script> 这种设计可以防止意外的碰撞,并促进更好的封装。

    2. 为什么不能在非模块中访问模块变量

      • 非模块脚本(或控制台,如果您直接从浏览器DevTools控制台进行测试)在 窗口 对象,默认情况下只包含在全局范围内声明的变量。
      • 如果您的脚本是一个模块,则除非明确导出,否则其中声明的任何内容都将保留在模块本地范围内。
    3. 如何从模块中暴露变量
      如果你想让非模块脚本(或全局作用域)看到你的模块变量:

      • 附至 窗口 对象
        // Inside your module:
        const myValue = 42;
        window.myValue = myValue;
        
        现在,非模块脚本(甚至HTML中的内联代码)可以做到:
        console.log(window.myValue); // 42
        
      • 进出口机制 (用于模块间通信)
        如果两个脚本都是模块,则可以从一个模块导出并导入另一个模块:
        // moduleA.js
        export const myValue = 42;
        
        <!-- moduleB -->
        <script type="module">
          import { myValue } from './moduleA.js';
          console.log(myValue); // 42
        </script>
        
    4. 确保脚本类型一致

      • 如果您将模块脚本和非模块脚本混合使用,请注意,在一个作用域中声明的变量在另一个范围中不会自动可用。
      • 对于某些项目,将所有脚本保持为模块以实现一致的导入/导出模式更简单。

    实用建议

    1. 将依赖脚本转换为模块
      只要有可能,转换所有 <脚本> 标签到 type="module"> 。这样,您可以使用Javascript本机模块系统,使用 export import 正如预期的那样。

    2. 仅在必要时使用全局对象
      如果您真的需要全局访问,以便快速验证概念,请访问 窗口 这是一种简单的方法。然而,从设计的角度来看,全局变量可能会导致命名冲突和维护问题。明智地使用它们。

    3. 检查浏览器支持
      大多数现代浏览器完全支持 <脚本类型=“模块”> ,但您可能需要对旧环境进行转换或使用polyfills。如果你针对的是传统浏览器,请记住这一点。


    模块脚本旨在提供更健壮和封装的代码结构。如果需要与非模块脚本共享变量,请将它们显式分配给全局范围,或者重构代码以仅使用模块。通过遵循导入/导出标准,您将维护更清晰、更可维护的代码。