Могу ли я определить, обрабатывается ли мой script с помощью Webpack?
Я пытаюсь использовать изоморфный рендеринг в React, поэтому я могу выводить статические HTML как документацию для своего приложения.
Проблема в том, что у меня есть конкретный компонент, который работает только на клиенте, потому что он ссылается на window
. Решение очевидно: не отображать его на сервере. Да, я не могу сделать это на сервере, но все же мне нужно, чтобы он был включен в мой пакет webpack
, поэтому я могу отобразить его на клиенте. Проблема в том, что код, который предотвращает рендеринг моего компонента на сервере, следующий:
function isServer() {
return ! (typeof window != 'undefined' && window.document);
}
Но isServer()
также true
, когда webpack
связывается, и я хочу, чтобы он работал нормально, когда выполняется webpack
.
Итак, как я обнаруживаю, что работает webpack
?
Я ищу что-то вроде этого:
function isWebpack() {
// what do I put here?
}
Теперь я могу сделать свой клиентский компонент обычно, если isServer()
и !isWebpack()
.
Спасибо!
ИЗМЕНИТЬ
Это компонент, который я пытаюсь построить:
function isServer() {
return ! (typeof window != 'undefined' && window.document);
}
import React from 'react';
const LED = React.createClass({
render: function () {
if(!isServer()) {
var LiveSchemaEditor = require('../../src/components/LiveSchemaEditor.js');
return <LiveSchemaEditor />;
}
return <div>I AM IN THE SERVER</div>;
}
});
export default LED;
Что меня беспокоит, что пакет webpack
содержит содержимое LiveSchemaEditor.js
, но он все еще печатает I AM IN THE SERVER
на клиенте. Это не имеет смысла.
Ответы
Ответ 1
Поместите это в свою конфигурацию webpack под плагинами:
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
APP_ENV: JSON.stringify('browser')
}
}),
С этим вы можете проверить, работаете ли вы в браузере или нет:
if (process.env.APP_ENV === 'browser') {
const doSomething = require('./browser-only-js');
doSomething();
} else {
const somethingServer = require('./server-only-js');
somethingServer();
}
if (process.env.APP_ENV !== 'browser') {
const somethingServer = require('./server-only-js');
somethingServer();
}
Поскольку эти переменные среды заменяются во время сборки, Webpack не будет включать в себя ресурсы, которые являются серверными. Вы всегда должны делать такие вещи легко, с простым, прямым сравнением. Uglify удалит все мертвые коды.
Поскольку вы использовали функцию раньше, и функция не была оценена во время сборки, Webpack не смог узнать, что требуется, чтобы он мог пропустить.
(NODE_ENV
-variable всегда должен быть установлен в production
в рабочем режиме, так как многие библиотеки, включая React, используют его для оптимизации.)
Ответ 2
Вы также можете сделать это -
typeof __webpack_require__ === 'function'
Я предполагаю, что это может измениться в любое время, поэтому используйте с осторожностью.:/
Ответ 3
ComponentDidMount запускается исключительно в браузере, поэтому вы можете использовать его следующим образом:
//file level const (cache the result)
const LiveSchemaEditor;
//...
componentDidMount() {
LiveSchemaEditor = require('../../src/components/LiveSchemaEditor.js');
this.setState({ editor: <LiveSchemaEditor/> });
}
render() {
if(!this.state.editor){
return <div>loading...</div>;
}
return this.state.editor;
}