CRA-具有动态CSS导入的React生产构建

时间:2020-02-26 17:53:40

标签: css reactjs create-react-app react-scripts

问题:

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

在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问题以寻求解决方案:

react-scripts build ignores conditional css imports

1 个答案:

答案 0 :(得分:1)

我立即回答了自己的问题,因为我已经解决了它,而且还因为我有点荷马·辛普森的“ 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`);

因此,styles文件夹中的所有css文件都一起编译了。

我不太确定这里发生的事情的内在原理,所以我不介意从Dan Abramov等人那里获得输入,他们可能会更好地了解正在发生的事情以澄清这一点。