英文:
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)
重现步骤:
- 使用创建项目步骤。
npm install ccxt
。- 在
/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:
- use the create a project steps
npm install ccxt
- in the
/src/routes/+page.svelte
useimport 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内置模块):
然而,看起来你已经尝试过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):
However, it seems you have already tried polyfilling.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论