React:有条件地需要 CSS 文件始终包含在构建中
React: Conditionally required CSS file always included in build
出于测试目的,我包含了一个 CSS 文件,该文件禁用某些 CSS class 的动画,这样 differencify 测试就不会产生虚假差异。此 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 对象,因此不包括构建中不相关的任何内容。
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/ ,有了它你可以比仅仅开发和生产有更好的控制,例如。您可能需要启用日志记录等的生产构建。
出于测试目的,我包含了一个 CSS 文件,该文件禁用某些 CSS class 的动画,这样 differencify 测试就不会产生虚假差异。此 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 对象,因此不包括构建中不相关的任何内容。
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/ ,有了它你可以比仅仅开发和生产有更好的控制,例如。您可能需要启用日志记录等的生产构建。