I tried to import ccxt into my svelte kit app and got ReferenceError: Buffer is not defined even though I'd only imported it

huangapple go评论67阅读模式
英文:

I tried to import ccxt into my svelte kit app and got ReferenceError: Buffer is not defined even though I'd only imported it

问题

我这里有一个关于这个问题的最小可重现示例。问题是,import ccxt from "ccxt" 引发了这个错误:

ReferenceError: Buffer is not defined
    at node_modules/ccxt/js/static_dependencies/node-rsa/schemes/pkcs1.js (pkcs1.js:10:10)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)
    at node_modules/ccxt/js/static_dependencies/node-rsa/schemes/schemes.js (schemes.js:2:12)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)
    at node_modules/ccxt/js/static_dependencies/node-rsa/libs/rsa.js (rsa.js:12:15)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)
    at node_modules/ccxt/js/static_dependencies/node-rsa/NodeRSA.js (NodeRSA.js:8:11)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)
    at node_modules/ccxt/js/base/functions/crypto.js (crypto.js:8:17)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)

重现步骤:

  1. 使用创建项目步骤
  2. npm install ccxt
  3. /src/routes/+page.svelte中使用import ccxt from "ccxt"

我期望的行为是包成功导入,然后我可以像文档中所示那样操作:

var ccxt = require ('ccxt')

console.log (ccxt.exchanges) // 打印所有可用的交易所

我看到这篇帖子基本上说:“为了使require工作,请尝试将其添加为开发依赖”,所以我这样做了:

npm install --save-dev ccxt

require仍然失败。无论如何,我不想使用require,我想使用import

编辑:

我设法使用Uncaught ReferenceError: Buffer is not defined来使我的vite.config.js做如下设置:

import path from 'path'
import inject from '@rollup/plugin-inject'

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
	plugins: [sveltekit()],
	resolve: {
		alias: {
			'@': path.resolve(__dirname, 'src'),
		}
	},
	build: {
		rollupOptions: {
			plugins: [inject({ Buffer: ['buffer', 'Buffer'] })],
		},
	},
})

现在我可以在服务器端使用console.log(ccxt.exchanges),但在客户端端仍然出错。但是,有进展。

编辑2:我还尝试了ReferenceError: Buffer is not defined in vite/sveltekit with Torus中被勾选的答案,该答案如下:

resolve: {
                alias: {
                    '@toruslabs/openlogin': path.resolve(
                        './node_modules/@toruslabs/openlogin/dist/openlogin.umd.min.js'
                    )
                }
            }

但这也失败了。

我还尝试了“Goutham J.M”所提供的答案,该答案长而复杂,并卡在了错误[ERR_MODULE_NOT_FOUND]: Cannot find package '@esbuild-plugins/node-globals-polyfill',但我不知道如何解决这个问题,而且这个问题有点复杂。

英文:

I have a minimal reproducible example here about this issue. The issue is that import ccxt from "ccxt" gives this error

ReferenceError: Buffer is not defined
    at node_modules/ccxt/js/static_dependencies/node-rsa/schemes/pkcs1.js (pkcs1.js:10:10)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)
    at node_modules/ccxt/js/static_dependencies/node-rsa/schemes/schemes.js (schemes.js:2:12)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)
    at node_modules/ccxt/js/static_dependencies/node-rsa/libs/rsa.js (rsa.js:12:15)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)
    at node_modules/ccxt/js/static_dependencies/node-rsa/NodeRSA.js (NodeRSA.js:8:11)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)
    at node_modules/ccxt/js/base/functions/crypto.js (crypto.js:8:17)
    at __require (chunk-RSJERJUL.js?v=d0062138:3:50)

steps to reproduce:

  1. use the create a project steps
  2. npm install ccxt
  3. in the /src/routes/+page.svelte use import ccxt from "ccxt"

My expected behavior is that the package imports and I can do like what the docs say to do

var ccxt = require ('ccxt')

console.log (ccxt.exchanges) // print all available exchanges

i saw this post say basically "to get require to work, try adding it as a dev dependency" so i did that:

npm install --save-dev ccxt

require still fails. and anyway I don't want to use require, I want to use "import".

edit:

I managed to use Uncaught ReferenceError: Buffer is not defined to make my vite.config.js do this

import path from 'path'
import inject from '@rollup/plugin-inject'

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
	plugins: [sveltekit()],
	resolve: {
		alias: {
			'@': path.resolve(__dirname, 'src'),
		}
	},
	build: {
		rollupOptions: {
			plugins: [inject({ Buffer: ['buffer', 'Buffer'] })],
		},
	},
})

and now i can console.log(ccxt.exchanges) server side, but client side it still errors. but, progress.

edit2: I also tried the ticked answer to ReferenceError: Buffer is not defined in vite/sveltekit with Torus which says

resolve: {
                alias: {
                    '@toruslabs/openlogin': path.resolve(
                        './node_modules/@toruslabs/openlogin/dist/openlogin.umd.min.js'
                    )
                }
            }

but this fails as well.

I tried the answer by "Goutham J.M" with many upvotes that was long and complex, and got stuck with error [ERR_MODULE_NOT_FOUND]: Cannot find package '@esbuild-plugins/node-globals-polyfill' but I don't know how to solve that and it's too much of a rabbit hole.

答案1

得分: 1

不幸的是,像ccxt这样的Node.js库(与浏览器或客户端库相对)在客户端SvelteKit中没有官方支持;它们只在服务器端SvelteKit中受支持。通常,最好的解决方案是将Node.js库的使用限制在服务器端SvelteKit。 这在99%的情况下应该足够:

  • +page.server.js调用Node.js库,并从load函数返回值。这些值可以通过data属性从+page.svelte访问。
  • 或者从+server.js中的API端点调用Node.js库。然后从+page.svelte(或几乎任何其他地方)fetch()相应的内部API端点URL。

在1%的情况下,这是不够的,你将不得不要么polyfill Node.js的内置依赖项(Buffer),要么从相关库(ccxt)中删除Node.js依赖项。


有时,polyfilling可以让一些Node.js库在客户端正常工作(Buffer是一个Node.js内置模块):

  1. 修复本地开发错误
  2. 修复构建时错误

然而,看起来你已经尝试过polyfilling。

英文:

Unfortunately, nodejs libraries (as opposed to browser or client-side libraries) like ccxt are not officially supported in client-side SvelteKit; they are only supported in server-side SvelteKit.

Generally, the best solution is to limit usage of nodejs libraries to server-side SvelteKit. This should be sufficient 99% of the time:

  • Call the nodejs library from +page.server.js and return values from the load function. The values can be accessed from +page.svelte via the data prop.
  • OR call the nodejs library from an API endpoint in +server.js. Then fetch() the appropriate internal API endpoint URL from +page.svelte (or almost anywhere else).

For the 1% of the time this is not sufficient, you will have to either polyfill nodejs built-in dependencies (Buffer) and/or remove nodejs dependencies from the library (ccxt) in question.


Sometimes polyfilling will get some nodejs libraries to work client-side. (Buffer is a nodejs built-in module):

  1. To fix local dev errors.
  2. To fix build-time errors.

However, it seems you have already tried polyfilling.

huangapple
  • 本文由 发表于 2023年2月24日 01:29:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75548299.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定