我可以检测 Webpack 是否正在处理我的脚本吗?

IT技术 javascript node.js reactjs webpack
2021-05-04 13:43:45

我正在尝试在 React 中使用同构渲染,以便我可以输出静态 HTML 作为我的应用程序的文档。

问题是我有一个仅在客户端上运行的特定组件,因为它引用window. 解决方案很明显:不要在服务器上呈现它。是的,我不能在服务器上渲染它,但是,我仍然需要将它包含在我的webpack包中,以便我可以在客户端上渲染它。问题是,阻止我的组件在服务器上呈现的代码是:

function isServer() {
    return ! (typeof window != 'undefined' && window.document);
}

但是,isServer()truewebpack被捆绑了,我希望它正常工作,同时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在客户端上打印这没有意义。

4个回答

把它放在你的 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 在内的许多库都使用它进行优化。)

你也可以这样做——

typeof __webpack_require__ === 'function'

我猜这可能会随时更改,因此请谨慎使用。:/

在 Node.js 中global.global是循环引用,Webpack 没有创建这个循环:

function is_node() {
    return typeof global !== 'undefined' && global.global === global;
}

更改render()原因react的输出以失败重新水化组件,因此将放弃服务器端渲染。

相反,请考虑使用ComponentDidMount,它只在浏览器中运行:

//file level const (cache the result)
let LiveSchemaEditor = () => null;

//...

componentDidMount() {
    LiveSchemaEditor  = LiveSchemaEditor || require('../../src/components/LiveSchemaEditor.js');
    this.setState({ editor: <LiveSchemaEditor/> });
}

render() {
    if(!this.state.editor){
        return <div>loading...</div>;
    }

    return this.state.editor;
}