【问题标题】:Typescript and IDB library for using indexedDB. Guidance needed用于使用 indexedDB 的 Typescript 和 IDB 库。需要指导
【发布时间】:2017-11-13 15:54:33
【问题描述】:

来自新手的问题。 我正在尝试遵循使用Jake Archibald's IDB library 但使用Typescript 而不是纯Javascript 的Working with IndexedDB 教程。到目前为止,我还没有取得太大的成功。

我的代码如下所示。

import * as idb from "./idb";

const dbPromise: Promise<idb.DB> = idb.default.open('test-db2', 1, (upgradeDb: idb.UpgradeDB) => {
    console.log('making a new object store');
    if (!upgradeDb.objectStoreNames.contains('firstOS')) {
        upgradeDb.createObjectStore('firstOS');
    }
});

定义文件加载良好,因为编译器不会抛出任何错误,并且智能感知在 VS Code 中运行良好。

我设法在我的 html 页面上使用 require.js 加载我的模块,但控制台显示以下错误:

Uncaught TypeError: Cannot read property 'default' of undefined
at Object.<anonymous> (main.ts:8)
at Object.execCb (require.min.js:5)
at b.check (require.min.js:5)
at b.<anonymous> (require.min.js:5)
at require.min.js:5
at require.min.js:5
at each (require.min.js:5)
at b.emit (require.min.js:5)
at b.check (require.min.js:5)
at b.enable (require.min.js:5)

现在,如果我从对idb.default.open(...) 的调用中删除default,编译器会告诉我“.../idb”类型上不存在“open”。 该库将idb 导出为默认值。

我错过了某种初始化,但我无法真正看到什么或在哪里。

谁能帮忙?

解决方法

这就是我最终完成这项工作的方式。

import * as idxdb from "./idb";
import "./js/idb.js";

let dbPromise: Promise<idxdb.DB> = idb.open('test-db2', 1, (upgradeDb: idxdb.UpgradeDB) => {
    console.log('making a new object store');
    if (!upgradeDb.objectStoreNames.contains('firstOS')) {
        upgradeDb.createObjectStore('firstOS');
    }
});

第一个 import 语句引入了类型,因此它可以编译并提供提示。第二个语句将 idb 对象混在一起。

非常感谢@Josh 为我指明了正确的方向。

【问题讨论】:

    标签: typescript indexeddb


    【解决方案1】:

    嗯,不是打字高手,但是学习了一些模块语法后,看起来像是模块问题。查看https://github.com/jakearchibald/idb/blob/master/lib/idb.js 的代码,您会看到在浏览器上下文中,变量idb 以self.idb = exp; 结尾。

    因此,您尝试使用 ES6 模块语法导入模块,但您要导入的文件不是模块,因为它没有导出,也没有默认导出。

    (1) 您可以下载 idb.js 文件并在最后插入导出默认值,然后继续导入默认导出值。

    (2) 您可以学习如何在脚本文件不导出任何内容时将其作为模块导入。

    在2之下,因为self在浏览器中是window,你可能可以直接访问变量idb,因为通过包含文件,它就在全局范围内定义了。

    所以,首先您要导入文件,忽略它导出的内容,使用import "./idb.js"。这种导入语法风格会忽略导出的任何内容。因为我们知道 idb.js 不会导出任何东西,所以这很好,因为它是导入没有导出的文件所需的最少工作量。并且导入的结果是它被评估,因此这意味着导入的将在窗口的全局范围内声明 idb 作为模块的隐含副作用(在模块中通常不赞成定义全局变量,但这没关系,因为这是一个非模块)。

    所以...如果您在浏览器上下文中工作,请尝试以下操作:

    import "./idb.js";
    
    // This should print out information about the idb object declared in 
    // global scope of the browser (e.g. under window.idb)
    console.log(idb); 
    
    // Because the variable idb is basically just a global, just access 
    // here as it comes from the global
    const dbPromise: Promise<idb.DB> = idb.open(...);
    

    【讨论】:

    • 感谢您的 cmets,我终于弄明白了!编辑帖子以防有人发现自己处于同样的情况。感谢您对此进行调查!
    【解决方案2】:
    import idb from 'idb';
    

    这对我有用。

    【讨论】:

      【解决方案3】:

      导入默认导出时,语法为:

      import idb from "./idb";
      

      这仅适用于默认导出。

      你应该可以使用:

      idb.open(/* ... */)
      

      【讨论】:

      • 感谢您调查本芬顿。恐怕我尝试了这一切。您的第一次导入会导致整个类型提示变为所有红色曲线(事件删除 idb 作为其前缀)。而且,页面仍然崩溃“无法读取属性默认值”。这可能是缺少requirejs配置吗?
      【解决方案4】:

      我认为这可能是因为 idb javascript 不支持 AMD 加载程序(例如我正在使用的 require.js)。

      在 index-min.js 的末尾添加以下行对我有用:

      )({});
      /** added this: */
      if ( typeof define === "function" && define.amd ) {
          define( "idb", [], function() {
              return { openDB:idb.openDB, deleteDB:idb.deleteDB, wrap:idb.wrap, unwrap:idb.unwrap}
          });
      }
      

      【讨论】:

        猜你喜欢
        • 2011-03-14
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-15
        • 2015-05-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多