简体   繁体   English

CRA - 使用动态 CSS 导入反应生产构建

[英]CRA - React production build with dynamic CSS imports

The issue:问题:

Using the out-of-the-box react-scripts package included with create-react-app to build a production build of React, dynamically imported CSS files get ignored and instead all CSS seems to get compiled into the production build.使用 create-react-app 附带的开箱即用的 react-scripts 包来构建 React 的生产版本,动态导入的 CSS 文件将被忽略,取而代之的是所有 CSS 似乎都被编译到生产版本中。

Example of what is happening:正在发生的事情的例子:

/* 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;
}

Note we are using require() with template strings as the import statement only accepts string literals and cssEnv could be any number of things which would make a conditional statement untenable.请注意,我们将 require() 与模板字符串一起使用,因为 import 语句只接受字符串文字,而 cssEnv 可能是许多会使条件语句站不住脚的东西。

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

We build our production build.我们构建我们的生产版本。

$ npm run build

In the build folder, we find our compiled CSS.在 build 文件夹中,我们找到了我们编译的 CSS。 Note how all our CSS files have been compiled into one (including even CSS we never imported).注意我们所有的 CSS 文件是如何被编译成一个文件的(甚至包括我们从未导入的 CSS)。

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

A similar SO question I found in Googling for a solution:我在谷歌搜索中找到了一个类似的 SO 问题以寻求解决方案:

react-scripts build ignores conditional css imports react-scripts 构建忽略条件 css 导入

I'm immediately answering my own question because I've already solved it, but also because I had a bit of a Homer Simpson "d'oh!"我立即回答我自己的问题,因为我已经解决了它,但也因为我有一点荷马辛普森的“d'oh!” moment when I finally found the solution after scouring Google and documentation far and wide.在我广泛搜索谷歌和文档后终于找到解决方案的那一刻。 This is why I posted the question, in hopes of saving other people that time searching for a solution that wasn't super obvious (and doesn't seem to be addressed anywhere that I have found).这就是我发布这个问题的原因,希望能节省其他人寻找不太明显的解决方案的时间(并且似乎在我找到的任何地方都没有解决)。

So I didn't realize that the import statement had a dynamic importing functionality via import().所以我没有意识到 import 语句通过 import() 具有动态导入功能。 So the solution was simply to replace require() with import().所以解决方案只是用 import() 替换 require()。

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

Now when we build our production build, we get the correct compiled CSS现在当我们构建我们的生产版本时,我们得到了正确的编译 CSS

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

So my best guess as to what is happening is that react-scripts treats require() differently than import(), where providing a template string with variables to require() causes the variables to act like wildcards (*).所以我对正在发生的事情的最佳猜测是 react-scripts 处理 require() 与 import() 不同,其中向 require() 提供带有变量的模板字符串会导致变量表现得像通配符 (*)。 So when we were building the production build earlier,所以当我们之前构建生产版本时,

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

got treated like被对待

require(`./styles/*.css`);

Hence all css files in the styles folder were compiled together.因此,样式文件夹中的所有 css 文件都被编译在一起。

I'm not entirely sure of the intimate inner workings of what is happening here, so I wouldn't mind getting input from folks like Dan Abramov and others who might better understand what exactly is happening to clarify this.我不完全确定这里发生的事情的内部运作,所以我不介意从像 Dan Abramov 和其他人这样的人那里得到意见,他们可能会更好地理解到底发生了什么来澄清这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM