如何使用带有可变查询字符串的webpack动态导入? [英] How to use a webpack dynamic import with a variable query string?

查看:126
本文介绍了如何使用带有可变查询字符串的webpack动态导入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆