我的需求:根据 path 匹配,动态引入 ts 文件(其实是自己定义的静态数据)
现实问题:import().then 用变量时会报错
let { name } = useParams()
const [bookData, setBookData] = useState<string[]>()
useEffect(() => {
if (name !== undefined) {
import(`@/store/${name}`)
.then(module => {
// @ts-ignore
const data: string[] = module[data]
setBookData(data)
})
}
}, [])
上面这样写会报错 Uncaught (in promise) TypeError: Failed to resolve module specifier '@/store/teach'
但是把import(
@/store/${name})
换成 import('@/store/teach')
就正常了。但这样并不能满足根据变量导入的需求呀,求大神指出正确方式。
1
mxT52CRuqR6o5 2022-10-26 11:16:20 +08:00
|
2
nanqic OP @mxT52CRuqR6o5 感谢回复,我想可能不应该放在 react 板块里,我用的是 vite ,看一下官方文档,谢谢你的思路
|
3
mxT52CRuqR6o5 2022-10-26 11:34:23 +08:00
|
4
akatquas 2022-10-26 11:36:16 +08:00
|
5
nanqic OP @mxT52CRuqR6o5
我试了加上.ts 不可以,把文件修改成 js 后加.js 后缀也不行,打算放弃这种方式了,反正是静态文本,用 json 也一样吧,文件大点也无所谓。 @akatquas 感谢帮助,已经换 json 文件引入了 |
6
joesonw 2022-10-26 12:21:15 +08:00 via iPhone 1
你这个动态解析要运行时,运行时’@/xxx’这样是解析不到的。这是编译时 bundler 替换掉的,你动态的编译器也管不了:
|
7
wenerme 2022-10-26 13:25:16 +08:00
如果真的需要,可以考虑打包为单独 js ,然后 dynamic import 如果浏览器支持,不支持或者稳健点可以考虑 systemjs ,例如 https://github.com/wenerme/wode/tree/main/packages/system , 目前项目用到的这样的动态逻辑
|
8
oatw 2022-10-26 14:53:58 +08:00
6 楼正解
|
9
xiaoming1992 2022-10-26 14:56:13 +08:00
如果是服务端渲染,且每个 name 对应一个页面的话,把整个 store 下的文件分别 import 进来,在函数中按需取用,服务端渲染页面的时候应该会把这个页面没用到的 data 移除,可以省掉一点数据量(猜测,不确定)(但是一个 json 数据能有多大呢,除非是几万几十万行,否则没必要这么麻烦,直接全量引进来好了)
|
10
zhuweiyou 2022-10-26 15:31:59 +08:00
https://cn.vitejs.dev/guide/features.html#dynamic-import 上面写了 如果是一层路径 可以用变量.
你可以考虑用 import.meta.glob 或 import.meta.globEager ,批量导入, 然后 obj[key]() 来用 |
11
RabbitDR 2022-10-26 16:08:30 +08:00
不知道你具体是什么情况,我试了一下,是可以的,https://stackblitz.com/edit/vitejs-vite-pps848?file=src/App.jsx
|
12
learningman 2022-10-26 16:12:58 +08:00
@/store/${name}
如果这么搞的话,必须手写配置确保 bundler 打包了所有所需的对应的文件,不然 treeshaking 可能给整没了 |