使用vite/rollup.js来扩展Node.js的os模块
<p>我正在处理一个使用<code>opensea-js</code>包的Vite项目。这个包依赖于<code>xhr2-cookies</code>,它导入了<code>os</code>、<code>http</code>、<code>https</code>和其他一些内部的node模块。</p>
<p>当我尝试调用任何opensea方法时,出现了以下错误:</p>
<pre class="brush:php;toolbar:false;">Uncaught (in promise) TypeError: os.type不是一个函数
XMLHttpRequest2 xml-http-request.ts:102
prepareRequest httpprovider.js:61
sendAsync httpprovider.js:116
node_modules opensea-js.js:24209</pre>
<p>追踪这个错误,发现它来自构建用户代理字符串。</p>
<p>我尝试安装<code>rollup-plugin-polyfill-node</code>并将其添加到<code>vite.config.js</code>中,但仍然出现相同的错误:</p>
<pre class="brush:php;toolbar:false;">import path from 'path'
import vue from '@vitejs/plugin-vue'
import nodePolyfills from 'rollup-plugin-polyfill-node'
import { defineConfig } from 'vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
server: {
port: 8080,
},
define: {
'process.env': {},
},
build: {
rollupOptions: {
plugins: [
nodePolyfills(),
],
},
},
})</pre>
<p>我还尝试使用<code>patch-package</code>手动修复文件,这样可以解决<code>os</code>错误,但在尝试发送请求时失败(因为它使用需要进行polyfill的<code>http</code>/<code>https</code>模块)。</p>
我使用了
rollup-plugin-polyfill-node来解决这个问题。import nodePolyfills from 'rollup-plugin-polyfill-node'; rollup({ entry: 'main.js', plugins: [ nodePolyfills( /* options */ ) ] })这是基于Fabiano的答案的更完整的解决方案:
// yarn add --dev @esbuild-plugins/node-globals-polyfill import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill' // yarn add --dev @esbuild-plugins/node-modules-polyfill import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill' import nodePolyfills from 'rollup-plugin-polyfill-node'; export default { optimizeDeps: { esbuildOptions: { // Node.js global to browser globalThis define: { global: 'globalThis' }, // Enable esbuild polyfill plugins plugins: [ NodeGlobalsPolyfillPlugin({ process: true, buffer: true }), NodeModulesPolyfillPlugin() ] } }, build: { rollupOptions: { plugins: [ // Enable rollup polyfills plugin // used during production bundling nodePolyfills() ] } } }在我的项目中,我使用了以下配置来解决问题。我在一篇简短的文章中描述了解决方案。
// yarn add --dev @esbuild-plugins/node-globals-polyfill import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill' // yarn add --dev @esbuild-plugins/node-modules-polyfill import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill' // You don't need to add this to deps, it's included by @esbuild-plugins/node-modules-polyfill import rollupNodePolyFill from 'rollup-plugin-node-polyfills' export default { resolve: { alias: { // This Rollup aliases are extracted from @esbuild-plugins/node-modules-polyfill, // see https://github.com/remorses/esbuild-plugins/blob/master/node-modules-polyfill/src/polyfills.ts // process and buffer are excluded because already managed // by node-globals-polyfill util: 'rollup-plugin-node-polyfills/polyfills/util', sys: 'util', events: 'rollup-plugin-node-polyfills/polyfills/events', stream: 'rollup-plugin-node-polyfills/polyfills/stream', path: 'rollup-plugin-node-polyfills/polyfills/path', querystring: 'rollup-plugin-node-polyfills/polyfills/qs', punycode: 'rollup-plugin-node-polyfills/polyfills/punycode', url: 'rollup-plugin-node-polyfills/polyfills/url', string_decoder: 'rollup-plugin-node-polyfills/polyfills/string-decoder', http: 'rollup-plugin-node-polyfills/polyfills/http', https: 'rollup-plugin-node-polyfills/polyfills/http', os: 'rollup-plugin-node-polyfills/polyfills/os', assert: 'rollup-plugin-node-polyfills/polyfills/assert', constants: 'rollup-plugin-node-polyfills/polyfills/constants', _stream_duplex: 'rollup-plugin-node-polyfills/polyfills/readable-stream/duplex', _stream_passthrough: 'rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough', _stream_readable: 'rollup-plugin-node-polyfills/polyfills/readable-stream/readable', _stream_writable: 'rollup-plugin-node-polyfills/polyfills/readable-stream/writable', _stream_transform: 'rollup-plugin-node-polyfills/polyfills/readable-stream/transform', timers: 'rollup-plugin-node-polyfills/polyfills/timers', console: 'rollup-plugin-node-polyfills/polyfills/console', vm: 'rollup-plugin-node-polyfills/polyfills/vm', zlib: 'rollup-plugin-node-polyfills/polyfills/zlib', tty: 'rollup-plugin-node-polyfills/polyfills/tty', domain: 'rollup-plugin-node-polyfills/polyfills/domain' } }, optimizeDeps: { esbuildOptions: { // Node.js global to browser globalThis define: { global: 'globalThis' }, // Enable esbuild polyfill plugins plugins: [ NodeGlobalsPolyfillPlugin({ process: true, buffer: true }), NodeModulesPolyfillPlugin() ] } }, build: { rollupOptions: { plugins: [ // Enable rollup polyfills plugin // used during production bundling rollupNodePolyFill() ] } } }