代码之家  ›  专栏  ›  技术社区  ›  JdelaRubia

用于使用indexedDB的Typescript和IDB库。需要指导

  •  1
  • JdelaRubia  · 技术社区  · 7 年前

    来自新手的问题。 我正试着跟着走 Working with IndexedDB 使用的教程 Jake Archibald's IDB library 但是使用Typescript而不是普通的Javascript。到目前为止,我还没有取得什么成功。

    我的代码看起来像这样。

    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');
        }
    });
    

    定义文件加载良好,因为编译器不会抛出任何错误,并且intellisense在VS代码中工作良好。

    我使用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)
    

    现在,如果我删除 default 从呼叫到 idb.default.open(...) ,编译器告诉我类型“”上不存在“open”/idb’。 库导出 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 为我指明了正确的方向。

    4 回复  |  直到 7 年前
        1
  •  3
  •   Josh    7 年前

    嗯,不是typescript专家,但在学习了一些模块语法后,它看起来像是一个模块问题。查看代码 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(...);
    
        2
  •  1
  •   Michal Drewniak    6 年前
    import idb from 'idb';
    

    这对我很有效。

        3
  •  0
  •   Fenton    7 年前

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

    import idb from "./idb";
    

    这仅适用于默认导出。

    然后,您应该能够使用:

    idb.open(/* ... */)
    
        4
  •  0
  •   Urooj    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}
        });
    }