我可以检测我的脚本是否正在被 Webpack 处理吗?
Can I detect if my script is being processed by Webpack?
我正在尝试在 React 中使用同构渲染,这样我就可以输出静态 HTML 作为我的应用程序的文档。
问题是我有一个只在客户端上运行的特定组件,因为它引用了 window
。解决方案很明显:不在服务器上呈现它。是的,我不能在服务器上渲染它,但我仍然需要将它包含在我的 webpack
包中,这样我才能在客户端上渲染它。问题是,阻止我的组件在服务器上呈现的代码是:
function isServer() {
return ! (typeof window != 'undefined' && window.document);
}
但是isServer()
在webpack
捆绑的时候也是true
,我希望webpack
在运行.[=25的时候正常工作=]
那么,我如何检测 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
。这没有意义。
把这个放在插件下的 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
变量应始终设置为 production
,因为包括 React 在内的许多库都使用它进行优化。)
你也可以这样做 -
typeof __webpack_require__ === 'function'
我猜这可能会随时更改,因此请谨慎使用。 :/
更改 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;
}
这对我有用。
if(typeof process.env.NODE_ENV === "undefined") {
// Not webpack
} else {
// Its webpack
}
in Node.js global.global
是循环引用,Webpack 没有创建这个循环:
function is_node() {
return typeof global !== 'undefined' && global.global === global;
}
我正在尝试在 React 中使用同构渲染,这样我就可以输出静态 HTML 作为我的应用程序的文档。
问题是我有一个只在客户端上运行的特定组件,因为它引用了 window
。解决方案很明显:不在服务器上呈现它。是的,我不能在服务器上渲染它,但我仍然需要将它包含在我的 webpack
包中,这样我才能在客户端上渲染它。问题是,阻止我的组件在服务器上呈现的代码是:
function isServer() {
return ! (typeof window != 'undefined' && window.document);
}
但是isServer()
在webpack
捆绑的时候也是true
,我希望webpack
在运行.[=25的时候正常工作=]
那么,我如何检测 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
。这没有意义。
把这个放在插件下的 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
变量应始终设置为 production
,因为包括 React 在内的许多库都使用它进行优化。)
你也可以这样做 -
typeof __webpack_require__ === 'function'
我猜这可能会随时更改,因此请谨慎使用。 :/
更改 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;
}
这对我有用。
if(typeof process.env.NODE_ENV === "undefined") {
// Not webpack
} else {
// Its webpack
}
in Node.js global.global
是循环引用,Webpack 没有创建这个循环:
function is_node() {
return typeof global !== 'undefined' && global.global === global;
}