我正在建立一个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"
,则效果很好。
是否有一种从变量动态加载模块的方法?或者也许是另一种更适合解决此问题的方法?
答案 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
最后,您可以使用该变量来动态导入您的每个组件。