繁体   English   中英

React:有条件地要求的 CSS 文件始终包含在构建中

[英]React: Conditionally required CSS file always included in build

出于测试目的,我包含了一个禁用某些 CSS 类动画的 CSS 文件,使用它是为了使差异化测试不会产生虚假差异。 仅当设置了某些环境变量时,才会包含此 CSS 文件:

if (process.env.REACT_APP_BACKEND_URL === 'localhost') {
  // Use a fixed clock against local backend
  moment.now = () => 1558396800000;

  // Disable animations when running localcd to avoid diff on visual tests
  if (process.env.REACT_APP_DISABLE_ANIMATIONS === 'true') {
    require('./disable-animations.css');
  }
}

ReactDOM.render(<App />, document.getElementById('root'));

这在本地运行时效果很好,当后端为localhost时禁用动画,并在针对其他后端运行时启用。 但是由于某种原因,在使用react-scripts build的部署代码中也禁用了动画。 moment.now()在构建的代码中没有被覆盖,所以似乎react-scripts build将包括传递给require()所有资源,而不管它们的条件如何? 有没有办法避免这种情况? 有没有更好的方法来实现这一目标?

所有require()都会在最终构建中添加静态文件,无论它们是在 true 还是 false 条件下。 我会说解决方法可能是您使用StyleSheet.create()并在其中使 CSS 动态化。 您应该能够在逻辑上控制任何 CSS 属性,甚至最终输出一个空的 StyleSheet 对象,从而在构建中不包含任何不相关的内容。

来自https://facebook.github.io

const styles = StyleSheet.create({
  container: {
    borderRadius: 4,
    borderWidth: 0.5,
    borderColor: '#d6d7da',
  },
  title: {
    fontSize: 19,
    fontWeight: 'bold',
  },
  activeTitle: {
    color: 'red',
  },
});

在您的情况下,它可能如下所示:

const isIncluded = true;
const styles = isIncluded ? StyleSheet.create({
  container: {
    borderRadius: 4,
    borderWidth: 0.5,
    borderColor: '#d6d7da',
  },
  title: {
    fontSize: 19,
    fontWeight: 'bold',
  },
  activeTitle: {
    color: 'red',
  },
}) : null;

编辑:虽然在大多数情况下这将是正确的,正如@Keith 指出的那样,“......这不是严格正确的,例如......如果你做了 if (false) { require("something"); }会知道这是死代码并会排除它......”。 换句话说,在编译器将确保永远不会到达此代码的情况下, require()将不会包含在构建中

if (process.env.REACT_APP_DISABLE_ANIMATIONS === 'true') {
  require('./disable-animations.css');
}

在上面的 if 条件中,评估是动态的,编译器不知道这是一个编译时指令,它只会知道在运行时评估。

如果使用 webpack,有一种方法可以告诉编译器这是一个构建时间常量,一个例子是process.env.NODE_ENV ,这样编译器将在构建时而不是运行时评估这个值。 它通过用它的值替换 NODE_ENV 中的内容来做到这一点,例如。

if (process.env.NODE_ENV !== 'production') {
  require('./disable-animations.css');
}

在生产过程中,上述内容实际上会被转换为 ->

if ('production' !== 'production') {
  require('./disable-animations.css');
}

因此require('./disable-animations.css'); 将被排除在构建之外。

如果您想使用更复杂的构建时间常量,还有https://webpack.js.org/plugins/define-plugin/ ,通过它,您可以拥有比开发和生产更好的控制,例如。 您可能需要启用日志记录等的生产版本。

暂无
暂无

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

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