Могу ли я определить, обрабатывается ли мой 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;
}