禁用 Chrome React 开发工具以进行生产环境

23

我正在尝试使用gulp和envify为生产环境browserify我的React应用程序。这样,我就可以消除React警告、控制台中的错误报告,甚至通过编码禁用一些功能,例如对react-addons-perf的需求。

它工作得很好。当我在我的app.js中搜索"production"时,看看是否有这些典型的条件:

if("development" !== "production") {
    ...
}

没有什么比我之前说的更好,所以它似乎运行良好。

但是,我仍然可以在Chrome的React DevTools选项卡中看到所有的React组件,就像我在开发网站上一样。 如何在Chrome的DevTools中禁用此选项卡?

这是我的Gulp任务:

var production  = process.env.NODE_ENV === 'production' ? true : false;
var environment = process.env.NODE_ENV ? process.env.NODE_ENV : 'dev';

...

var bundler = browserify({
    debug: !production,

    // These options are just for Watchify
    cache: {}, packageCache: {}, fullPaths: true
})
.require(require.resolve('./dev/client/main.js'), { entry: true })
.transform(envify({global: true, _: 'purge', NODE_ENV: environment}), {global: true})
.transform(babelify)
.transform(reactify);

var start = Date.now();
bundler.bundle()
    .on('error', function (err) {
        console.log(err.toString());
        this.emit("end");
    })
    .pipe(source('main.js'))
    .pipe(gulpif(options.uglify, streamify(uglify())))
    .pipe(gulpif(!options.debug, streamify(stripDebug())))
    .pipe(gulp.dest(options.dest))
    .pipe(notify(function () {
        console.log('Built in ' + (Date.now() - start) + 'ms');
    }));
};

3
Chrome浏览器中的实际插件?你为什么想要这样做?你的js代码不应包含任何敏感信息。为什么Chrome会允许网站通过javascript来更改Chrome中的内容?想一想 - 这将是一个巨大的安全漏洞,因为可以通过javascript在用户浏览器中启用/禁用某些功能。 - Dominic
1
是的,Chrome 插件。别担心,如果用户没有经过身份验证,他什么也做不了:每个请求都会在服务器端使用强秘钥(1024 个字符)检查令牌。我的问题是,这是否可能以及如何实现?据我所知,这是可能的,因此我在这里询问为什么我的 gulp 任务无法正常工作。 - Poirette
啊,我明白了,如果没有全局的Reactrequire,它就不起作用,但是我不确定特定的设置。 - Dominic
我最近发布了一个禁用React Developer Tools插件的包:https://www.npmjs.com/package/@fvilers/disable-react-devtools - Fabian Vilers
4
如果有人对绕过此处的“保护”感兴趣,可以使用Chrome中的本地覆盖功能,在美化后删除有问题的行。例如:https://www.trysmudford.com/blog/chrome-local-overrides/ - nelsonjchen
11个回答

36
根据Github上的问题,你可以在React加载之前运行单个JavaScript命令来防止它。来源于react-devtools的#191问题
<script>
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function () {}
</script>

那么,您可以考虑将此与您的环境条件一起包装,这样您就可以在服务器端渲染中执行以下操作。假设使用Pug(以前称为Jade):

#{process.env.NODE_ENV == 'production' ? "window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function(){}" : ""}

然而,将业务逻辑和敏感数据放回服务器仍是一个好的实践。


我遇到了以下错误:无法为未定义的属性“inject”设置属性。 - Love Trivedi
2
请前往 chrome://extensions/ 查看是否已启用 "React Developer Tools"。 - peteroid
2
@LoveTrivedi 你是通过服务器渲染吗?请记住 Node 没有 window 对象。将代码片段包裹在 if (window){ ... } 中。 - Sua Morales
3
如果您没有安装React开发工具,那么很可能会发生这种情况。因此,您的代码应该首先检查__REACT_DEVTOOLS_GLOBAL_HOOK__是否已定义。 - Wayne Bloss

15

如果您正在使用redux-devtools-extension,则可以这样做。

const devTools =
  process.env.NODE_ENV === "production"
    ? applyMiddleware(...middlewares)
    : composeWithDevTools(applyMiddleware(...middlewares));

const store = createStore(rootReducer, initialState, devTools);

这将确保您的开发工具扩展仅在开发环境中运行,而不在生产环境中运行


16
这个答案指的是 Redux DevTools 而不是 React DevTools。 - Clay Stewart

6

仅对@peteriod的答案进行改进,以确保是否已安装开发工具

if (typeof window.__REACT_DEVTOOLS_GLOBAL_HOOK__ === 'object') {
   __REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function() {};
}

你可以将它添加到public文件夹中的index.html文件中。 - Cong Nguyen
1
我们如何在脚本标签内分配/访问环境变量?以便仅在生产模式下启用。 - Siluveru Kiran Kumar
1
@siluverukirankumar 添加这个条件 "%NODE_ENV%" !== "development" - khcpietro

2

您也可以在构建后通过在package.json文件中添加以下命令来删除所有源映射。

"scripts":{
     ...,
    "build": "react-scripts build",
    "postbuild": "rimraf build/**/*.map"
}

这会使得在组件中导航有些困难,并且在开发者工具中它们被隐藏了 - 来源


1

您可以使用@fvilers/disable-react-devtools包来禁用React开发者工具

首先,安装上述提到的包

npm i @fvilers/disable-react-devtools

或者

yarn add @fvilers/disable-react-devtools

在你的主文件中,在React加载之前调用disableReactDevTools()方法。

import React from 'react';
import ReactDOM from 'react-dom';
import { disableReactDevTools } from '@fvilers/disable-react-devtools';
import App from './App';

if (process.env.NODE_ENV === 'production') {
  disableReactDevTools();
}

ReactDOM.render(<App />, document.getElementById('root'));

1
你可以检查模式:
在位于public文件夹中的index.html文件的</body>标签之前添加以下代码。
  <input type="hidden" value="%NODE_ENV%" id="node_env_mode" />
<script>
  var mode = document.querySelector("#node_env_mode").value;
  if (
    mode === "production" &&
    typeof window.__REACT_DEVTOOLS_GLOBAL_HOOK__ === "object"
  ) {
    window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function () {};
  }
</script>

这不是一个万无一失的想法 - 有人可以创建一个本地代理服务器,从本地主机上提供您的网站,欺骗这个机制。 - Wojciech Maj
@WojciechMaj 你是对的。我编辑了我的答案,提供了更好的解决方案。 - Reza Hashemi

0

这个解决方案对我非常有效,将以下函数定义在您的根文件中,然后调用disbaleReactDevTools()函数:


const disableReactDevTools = (): void => {
  const noop = (): void => undefined;
  const DEV_TOOLS = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__;

  if (typeof DEV_TOOLS === "object") {
    // eslint-disable-next-line no-restricted-syntax
    for (const [key, value] of Object.entries(DEV_TOOLS)) {
      DEV_TOOLS[key] = typeof value === "function" ? noop : null;
    }
  }
};

你可以在这里找到更多细节:https://github.com/facebook/react-devtools/issues/191#issuecomment-443607190


0

我经常使用'fvilers/disable-react-devtools'包,它对我总是有效的。

你只需要使用以下命令安装这个页面:

npm i @fvilers/disable-react-devtools

然后告诉你的应用程序你处于生产环境。通过导入该软件包到你的应用程序中

import { disableReactDevTools } from '@fvilers/disable-reactdevtools';

然后在您的应用程序组件顶部使用以下代码片段。

if (process.env.NODE_ENV === 'production') {
  disableReactDevTools();
}
    import { disableReactDevTools } from '@fvilers/disable-react-devtools';

if (process.env.NODE_ENV === 'production') {
  disableReactDevTools();
}

0
为了移除开发工具,您需要从文件index.js中删除以下行:
mainWindow.webContents.openDevTools();

这是 index.js 文件的一行,即第23行。


男人重新阅读文章 - BugsCreator

0

针对我的解决方案,可以使用 npm run build 命令来运行。

  1. 在项目根目录下(与 package.json 文件相同的位置)添加文件 .env.production
  2. 在文件 .env.production 中添加属性 INLINE_RUNTIME_CHUNK=true(建议同时添加 GENERATE_SOURCEMAP=false 以确保构建后不会生成 *.map 文件)
  3. 最后尝试运行 npm run build,享受 ^^

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接