Реагируйте: Условно обязательный CSS файл всегда включен в сборку - PullRequest
2 голосов
/ 27 января 2020

Для целей тестирования я включаю файл 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() независимо от их условий? Есть ли способ избежать этого? Есть ли лучший способ добиться этого?

Ответы [ 2 ]

1 голос
/ 27 января 2020
if (process.env.REACT_APP_DISABLE_ANIMATIONS === 'true') {
  require('./disable-animations.css');
}

В приведенном выше условии, если оценка является динамической c, компилятор не знает, что это директива времени компиляции, он будет знать, что оценивать только во время выполнения.

При использовании веб-пакета есть способ сообщить компилятору, что это постоянная времени сборки, например, 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/, с этим вы можете иметь даже более точное управление, чем просто разработка и производство, например. вам может потребоваться промышленная сборка с включенным ведением журнала, и т. д. c.

1 голос
/ 27 января 2020

Все require() добавят в окончательную сборку файлы c, независимо от того, находятся ли они в истинных или ложных условиях. Я бы сказал, что обходной путь может быть таким, что вместо этого вы используете StyleSheet.create() и делаете там CSS dynamici c. Вы должны иметь возможность логически управлять любым свойством CSS и даже выводить пустой объект StyleSheet в конце, таким образом, не включая ничего не связанного в сборке.

From 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, ".. .это не совсем верно, например .. если вы сделали, если (false) {require ("что-то");} компилятор будет знать, что это мертвый код, и исключит его ... ". Другими словами, в случаях, когда компилятор будет уверен, что этот код никогда не будет достигнут, require() не будет включен в сборку

...