CRA - 使用动态 CSS 导入的 React 生产构建

CRA - React production build with dynamic CSS imports

问题:

使用 create-react-app 附带的开箱即用的 react-scripts 包来构建 React 的生产版本,动态导入的 CSS 文件将被忽略,取而代之的是所有 CSS 似乎被编译到生产版本中。

正在发生的事情的例子:

/* styles/desktop.css */
.some-class {
  background-color: white;
  margin: 0;
}
/* styles/mobile.css */
.some-class {
  border: 1px solid black;
  margin: 1em;
}
.another-class {
  background-color: black;
  padding: 3px;
}

请注意,我们将 require() 与模板字符串一起使用,因为 import 语句只接受字符串文字,而 cssEnv 可以是任何数量的东西,这会使条件语句无法成立。

/* config.js */
const cssEnv = 'desktop';
require(`./styles/${cssEnv}.css`);

我们构建生产版本。

$ npm run build

在构建文件夹中,我们找到编译好的CSS。请注意我们所有的 CSS 文件是如何编译成一个文件的(甚至包括我们从未导入的 CSS)。

/* compiledCSS.chunk.css */
.some-class {
  background-color: white;
  border: 1px solid black;
  margin: 0;
}
.another-class {
  background-color: black;
  padding: 3px;
}

我在谷歌搜索中找到的类似 SO 问题的解决方案:

我立即回答我自己的问题,因为我已经解决了它,但也因为我有一点 Homer Simpson "d'oh!" 的时刻,我在搜索后终于找到了解决方案 Google 和广泛的文档。这就是为什么我发布了这个问题,希望能节省其他人寻找一个不是很明显的解决方案的时间(而且似乎没有在我找到的任何地方得到解决)。

所以我没有意识到 import 语句通过 import() 具有动态导入功能。所以解决方案就是用 import() 替换 require()。

/* config.js */
const cssEnv = 'desktop';
import(`./styles/${cssEnv}.css`);

现在,当我们构建生产版本时,我们会得到正确的编译结果 CSS

/* compiledCSS.chunk.css */
.some-class {
  background-color: white;
  margin: 0;
}

所以我对正在发生的事情的最佳猜测是 react-scripts 对待 require() 的方式与 import() 不同,其中为 require() 提供带有变量的模板字符串会导致变量像通配符 (*) .所以当我们早些时候构建生产版本时,

require(`./styles/${cssEnv}.css`);

得到了

的待遇
require(`./styles/*.css`);

因此样式文件夹中的所有 css 个文件被一起编译。

我不完全确定这里发生的事情的内部运作,所以我不介意从 Dan Abramov 和其他可能更了解到底发生了什么的人那里获得意见来澄清这一点。