如何使用带有可变查询字符串的webpack动态导入? [英] How to use a webpack dynamic import with a variable query string?
问题描述
使用webpack 3做出反应,我可以导入一个文件,如下所示:
Using webpack 3 and react, I can import a file like this:
import(`src/Main.sass`).then(...do something)
我有一个用于导入文件的加载程序,该加载程序可以根据查询字符串更改模块内容,并且可以成功地导入一个文件,如下所示:
I have a loader for the imported files that changes the module content based on a query string, and I can successfully import a file like this:
import(`src/Main.sass?theme=themename`).then(...do something)
但是当查询字符串是变量时:
But when the query string is a variable:
const themeQuery = '?theme=themename';
import(`src/Main.sass${themeQuery}`).then(...do something);
或
const theme = 'themename';
import(`src/Main.sass?theme=${theme}`).then(...do something);
我得到了错误:
Error: Cannot find module '.src/Main.sass?theme=themename'.
我希望这会根据此处的信息起作用:
I would expect this to work based on the information here:
完全动态的语句(例如import(foo))将失败,因为webpack至少需要一些文件位置信息.这是因为foo可能是系统或项目中任何文件的任何路径. import()必须至少包含有关模块位置的某些信息,因此捆绑可以限制为特定目录或文件集.
Fully dynamic statements, such as import(foo), will fail because webpack requires at least some file location information. This is because foo could potentially be any path to any file in your system or project. The import() must contain at least some information about where the module is located, so bundling can be limited to a specific directory or set of files.
和
包括了可能会在import()调用中请求的每个模块.例如,import(
./locale/${language}.json
)将导致./locale目录中的每个.json文件捆绑到新的块中.在运行时,计算完可变语言后,将可以使用english.json或german.json之类的任何文件.
Every module that could potentially be requested on an import() call is included. For example, import(
./locale/${language}.json
) will cause every .json file in the ./locale directory to be bundled into the new chunk. At run time, when the variable language has been computed, any file like english.json or german.json will be available for consumption.
这不是一个完全动态的语句,它具有完整的文件路径(位置信息),可以在没有查询字符串的情况下毫无问题地导入.
This is not a fully dynamic statement and it has the full file path (location information) that can be imported with no problem sans query string.
我创建了一个测试存储库,可以在其中复制该文件. src/Main.js
导入Main.component.sass
以及由道具themeName
定义的查询字符串.当将此组件用作src/App.js
中的<Main/>
时,您可以看到Cannot find module './Main.module.sass?theme=themename' error.
.但是,当使用完整字符串(包括查询)进行导入时,文件导入没有问题.通过将src/Main-no-var.js
用作<Main>
组件,可以看到这一点.
I've created a test repo where this can be reproduced. src/Main.js
imports Main.component.sass
with a query string defined by a prop, themeName
. When using this component as <Main/>
in src/App.js
, you can see the Cannot find module './Main.module.sass?theme=themename' error.
However, when importing using the full string, including the query, the file is imported with no issue. This can be seen by using src/Main-no-var.js
as the <Main>
component.
这是 webpack配置用于此示例.
推荐答案
如果您查看文档的这一部分
If you look at this part of documentation
例如,import(./locale/$ {language} .json)将导致每个.json ./locale目录中的文件,以将其捆绑到新块中.在 运行时,计算完可变语言后,任何类似的文件 english.json或german.json将可供使用.
For example, import(./locale/${language}.json) will cause every .json file in the ./locale directory to be bundled into the new chunk. At run time, when the variable language has been computed, any file like english.json or german.json will be available for consumption.
这意味着静态分析将搜索./locale/
文件夹中的每个.json
文件并将其捆绑,这意味着它将知道每个可能的目标.有了query string
,您将基本上拥有无限数量的可能目标,因为query string
可以是任何东西,因此将不知道捆绑什么.
This means that static analysis will search for every .json
file within ./locale/
folder and bundle it, meaning it'll know every possible target. With query string
you'll have basically infinite number of possible targets because query string
could be anything and therefore won't be able to know what to bundle.
我想这与dynamic path
分辨率完全不同,目前的import()
语句显然不支持该功能.
I guess this is just entirely different functionality from dynamic path
resolution which obviously is not supported in the current import()
statement.
您最好的选择是将文件夹结构更改为每个主题具有多个.css
文件,然后按照文档(语言示例)中的建议使用dynamic path
加载它,或者您可以执行类似的操作
Your best bet is to change folder structure to have multiple .css
files for each theme and then load it using dynamic path
as suggested in documentation (language example) or you could do something like this
const themes = {
"themename": () => import(
`./Main.module.css?theme=themename`
),
// other themes
}
这样,您将获得更清晰的代码,以显示可以传递给prop
的所有可能的主题(静态分析将确切地知道query string
是什么,因此它将起作用),然后按如下方式使用它
This way you'd have cleaner code showing all possible themes that can be passed to prop
(static analysis would know exactly what the query string
is, so it will work) and then you'd use it like so
componentDidMount = () => {
const { themeName } = this.props
themes[themeName]().then((result) => {
this.setState({ theme: result })
})
}
我宁愿按照您所建议的那样执行查询字符串,但就目前而言,据我调查,这是不可能的.
I'd rather have the query string implementation as you've suggested but for now, as far as I've investigated, it's not possible.
这篇关于如何使用带有可变查询字符串的webpack动态导入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!