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

xggvc2p6  于 2022-12-21  发布在  Java
关注(0)|答案(6)|浏览(176)

我尝试在React中使用同构呈现,以便可以输出静态HTML作为应用程序的文档。
问题是我有一个只在客户端运行的特定组件,因为它引用window。不要在服务器上渲染它。是的,我不能在服务器上渲染它,但我仍然需要它包含在我的webpack包中,这样我就可以在客户端上渲染它。问题是,阻止我的组件在服务器上渲染的代码是:

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

但是isServer()webpack捆绑时也是true,我希望它在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,这没有道理。

zpqajqem

zpqajqem1#

把这个放在你的webpack配置中的plugins下面:

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无法知道它可以跳过哪些要求。
(The NODE_ENV-变量在生产模式下应始终设置为production,因为包括React在内的许多库都使用它进行优化。)

agxfikkp

agxfikkp2#

你也可以这么做-

typeof __webpack_require__ === 'function'

我猜这可能随时会改变,所以要谨慎使用。:/

kokeuurv

kokeuurv3#

在Node.js中global.global是循环引用,Webpack未创建此循环:

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

jucafojl4#

下面是@Ambroos回答的改进版。

// webpack.config.js
const DefinePlugin = require('webpack').DefinePlugin;

const config = {
    ...
    plugins: [
        new DefinePlugin({
            'DEBUG': false,
        }),
    ],
};

module.exports = (env, argv) => {
    switch (argv.mode) {
        case 'development': {
            config.plugins[0].definitions.DEBUG = true;
            break;
        }

        case 'production': {
            break;
        }

        default: {
            throw new Error('No matching configuration was found!');
        }
    }

    return config;
};
mv1qrgav

mv1qrgav5#

更改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;
}
6ljaweal

6ljaweal6#

这对我很有效。

if(typeof process.env.NODE_ENV === "undefined") {
    // Not webpack
} else {
    // Its webpack
}

相关问题