【问题标题】:Can't find variable: Buffer找不到变量:缓冲区
【发布时间】:2018-07-04 02:11:20
【问题描述】:

我正在尝试在我的 react-native 应用程序中使用节点模块,我在这里采用ReactNativify 方法。

我现在一切就绪,我可以正常加载加密包。但是,当我添加 eth-lightwallet 时,事情变得越来越奇怪。

自从我添加了那个包之后,npm 就没有安装任何依赖项。这意味着我必须手动添加它们。每次我安装与 eth-lightwallet 相关的依赖项时,都会卸载该模块。虽然乏味且烦人,但我希望它可以阐明我当前的问题。

现在我遇到了Can't find variable: Buffer,它被扔到标准库的 util 文件夹中。我查看了代码,它正在从全局命名空间访问 Buffer。事情是,我正在将 Buffer 导入全局命名空间。下面看看我的 global.js

// Inject node globals into React Native global scope.
global.Buffer = require('buffer').Buffer;
global.process = require('process');
global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';

// Needed so that 'stream-http' chooses the right default protocol.
global.location = {
    protocol: 'file:',
};

// Don't do this in production. You're going to want to patch in
// https://github.com/mvayngrib/react-native-randombytes or similar.
global.crypto = {
    getRandomValues(byteArray) {
        for (let i = 0; i < byteArray.length; i++) {
            byteArray[i] = Math.floor(256 * Math.random());
        }
    },
};

我的猜测是在加载这个全局变量之前正在评估标准库,因此会引发错误。

【问题讨论】:

  • 我也有同样的问题,你试过用 rn-nodeify 包代替 react nativify 吗?

标签: node.js react-native npm global-variables


【解决方案1】:

在 TypeScript 中,我必须明确导入 Buffer

import { Buffer } from "buffer"

我原以为编译器会在导入之前抱怨Buffer 丢失和/或"source.organizeImports": true 在保存文件时会删除该行,但两者都不是真的。

@ehacinom 的解决方案也有效。

【讨论】:

    【解决方案2】:

    我使用 rn-nodeify 在我的 react-native 项目中使用节点包。添加安装后脚本后

        "postinstall": "./node_modules/.bin/rn-nodeify --install buffer,events,process,stream,util,inherits,fs,path,assert --hack;"
    

    我仍然遇到 Can't find variable: Buffer 。我最终通过将 shim.js 文件导入到我的 App.js 中解决了这个问题:

    import './shim';
    

    希望对您有所帮助!愉快的黑客攻击。

    【讨论】:

    • import './shim' 也为我解决了这个问题。我将它导入到我的 index.js 中,起初它什么也没做,然后我将 import 语句移到“import App from ./App”行上方,它起作用了。
    【解决方案3】:

    先安装以下

    yarn add buffer process babel-plugin-react-native-nodeify-hack
    

    然后添加到你的 babel 设置中.babelrc

    {
      "presets": ["react-native"],
      "plugins": ["babel-plugin-react-native-nodeify-hack"]
    }
    

    手动导入缓冲区和进程模块。在您的 index.ios.jsindex.android.js 中,将其添加到第一行:

    import process from 'process';
    import buffer from 'buffer';
    global.Buffer = buffer.Buffer
    

    尝试停止正在运行的 React Native Packager,然后运行:

    rm -rf $TMPDIR/react-*
    

    然后重新开始

    你可以走了!

    【讨论】:

      【解决方案4】:

      我运行 npm install buffer 并将其放在需要 Buffer 的文件的顶部:

      global.Buffer = global.Buffer || require('buffer').Buffer
      

      【讨论】:

      • 我得到了同样的错误,你能解释一下哪些文件会缓冲。有App.js、index.js等文件
      • 谢谢,这解决了我的问题。但是导入缓冲区还不够吗?
      【解决方案5】:

      回到这里留下一个解决方案,以防有人被困在这个问题上。解决方案基本上是尝试在不同的时间在不同的包中填充以更改加载顺序。

      当 TYPED_ARRAY_SUPPORT 受到不同处理并且 Buffer 更依赖它时,我们尝试返回不同的版本。在旧版本上,我们尝试了很多不同的东西,最终放弃并通过将缓冲区更新到最新版本来回溯,最后一切正常。

      我的意思是我们不确定我们是如何修复它的,但它是通过随机更改加载顺序直到我们幸运的。我知道这不是一个好的答案,但我可以为这个问题提供最好的答案。

      这是我们的 global.js 最后的样子

      // Inject node globals into React Native global scope.
      // Required for crypto functionality for bitcoinjs-lib, web3, etc.
      
      global.Buffer = require('buffer').Buffer;
      //global.Buffer.TYPED_ARRAY_SUPPORT = false;
      
      global.process = require('process');
      global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';
      
      var getRandomValues = function(byteArray) {
        var bytes = crypto.rng.randomBytes(byteArray.length);
        for (let i = 0; i < byteArray.length; i++) {
          byteArray[i] = bytes[i];
        }
      };
      // "But Zach, aren't you just doing the same thing twice?"
      // Yes. Initializing the crypto-browserify module eventually requires
      // crypto.getRandomValues to exist, so we must add it here once.
      // However, crypto-browserify does not support getRandomValues, so we
      // must re-add it after loading the module.
      global.crypto = { getRandomValues };
      global.crypto.rng = require('react-native-randombytes');
      global.crypto = require('crypto');
      global.crypto.getRandomValues = getRandomValues;
      global.crypto.rng = require('react-native-randombytes');
      crypto.rng.seedSJCL();
      
      // Needed so that 'stream-http' chooses the right default protocol.
      global.location = {
        protocol: 'file:'
      };
      

      【讨论】:

      • 我找不到 global.js 文件
      • global.js 是您创建并放在根级别的东西。我最终完成了这个项目,所以如果你想看看我是如何做到的 - github.com/arshbot/hail
      猜你喜欢
      • 2020-07-02
      • 1970-01-01
      • 2015-02-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      相关资源
      最近更新 更多