用于Gatsby JS网站的组件中的动态模块导入

时间:2019-09-19 12:34:59

标签: reactjs gatsby

我正在建立一个gatsby网站,每个页面都是从模板生成的,但是每个页面都需要导入不同的模块。

具体来说,每个页面都包含一个observablehq notebook,并且这些页面是从可观察到的模块导出的。参见here

页面是根据json文件动态生成的,例如:

[
    {   "path": "page1",
        "modulename": "gatsby-test"
    },
    {   
        "path": "page2",
        "modulename": "gatsby-test-2"
    }
]

这是通过createPages中的gatsby-node.js完成的。

我已经yarn add为每个笔记本项目,例如yarn add https://api.observablehq.com/@robinl/gatsby-test.tgz

我正在尝试编写一个将模块名称作为属性的组件,然后从this.props的内容中加载正确的模块。

我的组件的轮廓如下:

class ImportedNotebook extends Component {

    componentDidMount() {
        var promise = import(this.props.modulename).then(function(themodule) {
            // do stuff here
        })   
    }

    render() {
        return (<div>blah</div>);
    }
}

这不起作用-使用gatsby开发程序访问本地主机上的页面时,出现Unhandled Rejection (Error): Cannot find module 'gatsby-test-2'错误。

但是,如果我将this.props.modulename替换为"gatsby-test-2",则效果很好。

是否有一种从变量动态加载模块的方法?或者也许是另一种更适合解决此问题的方法?

2 个答案:

答案 0 :(得分:1)

我越来越相信使用这种方法不可能做到这一点。本质上这是因为webpack需要显式导入。如果您试图使这些“动态”成为可能,则无法知道要捆绑的代码。

我想出的解决方案是: -开发一个组件,将从可观察模块导入的notebook作为输入 -每个导入笔记本的笔记本都有一个最小的页面,然后将其传递给我的组件

对于每个页面,代码如下:

import React from "react"
import notebook from "gatsby-test-2"
import ObservablePage from "../components/obs_page"

export default ({ data }) => (
    ObservablePage(notebook)
)

答案 1 :(得分:1)

如果我正确理解了您的页面构建过程,那么在调用 {{1} 中的 modulename 时,您应该能够将可观察的 context 传递到动态生成的页面的 createPage }

exports.createPages:

然后在您的页面模板 (exports.createPages = function({ actions }) { // ... actions.createPage({ path: pagePath, component: require.resolve("./src/templates/pageTemplate.js"), // your page template file context: { modulename: modulename, // pass in your modulename URL here }, }) ) 中,您可以像这样访问 "./src/templates/pageTemplate.js" 变量:

modulename

最后,您可以使用该变量来动态导入您的每个组件。