我在一个与Vite捆绑在一起的Rails项目中使用filestack-js
。在我为filestack-js
库包含ESM模块之前,一切都按预期运行,在本例中是在StimulusJS控制器中:
import { Controller } from "stimulus";
import * as filestack from "filestack-js";
export default class extends Controller {
// some irrelevant implementation code that calls filestack.init(...)
}
在浏览器中加载上述控制器文件会导致错误:
tslib.es6.js:25 Uncaught TypeError: Object prototype may only be an Object or null: undefined
at setPrototypeOf (<anonymous>)
at __extends (tslib.es6.js:25)
at http.ts:43
at node_modules/filestack-js/build/module/lib/request/adapters/http.js (http.ts:64)
at __init (chunk-IHTDASF6.js?v=1616a449:14)
at request_adapter.node.ts:17
这是浏览器在开发环境中工作时产生的错误,使用Vite直接构建ES模块并将其提供给浏览器。它处理Typescript编译。删除import * as filestack
位可以消除错误(但显然会破坏类的功能)。
我在谷歌上的搜索似乎表明这可能是一个循环依赖问题。浏览器堆栈跟踪指向filestack-js
库中的一个文件:
// src/lib/request/adapters/http.ts
import * as url from 'url';
import * as zlib from 'zlib';
import Debug from 'debug';
import { AdapterInterface } from './interface';
import { getVersion } from '../../utils';
import * as Stream from 'stream'; // <---------- Stream imported here
import { FsRequestOptions, FsResponse } from '../types';
import * as utils from '../utils';
import { prepareData, parseResponse, combineURL, set as setHeader, normalizeHeaders } from './../helpers';
import { FsRequestErrorCode, FsRequestError } from '../error';
import { FsHttpMethod } from './../types';
const HTTPS_REGEXP = /https:?/;
const HTTP_CHUNK_SIZE = 16 * 1024;
const MAX_REDIRECTS = 10;
const CANCEL_CLEAR = `FsCleanMemory`;
const debug = Debug('fs:request:http');
class HttpWritableStream extends Stream.Writable {
// omitted class definition
}
其中由于循环依赖问题,Stream.Writable
实际上是未定义的。我不知道这将如何发生,或者似乎只对我有影响。
这不是filestack-js问题跟踪器上报告的问题。
在浏览器中调试和在本地克隆/链接存储库已经确认Stream.Writable
返回undefined
,但我对JS的了解还不够多,无法理解其中的原因。假设这通常是由于循环依赖而发生的,但我不确定nodejs Stream
模块如何在filestack-js
这样的随机库上具有循环依赖。我在JS领域也没有足够的经验,无法确切地理解在浏览器模块中使用像Stream
这样的nodeJS库意味着什么- filestack-js
既有浏览器模块,也有通用的JS/nodeJS模块,所以我不确定它们之间是如何联系或相互作用的。
下面是登录到浏览器控制台时Stream
对象的外观。显然,已经导入了某些内容,但Writable
不是所导入内容的属性:
FWIW这发生在Chrome和Firefox上,它们都是最新版本。
我还尝试使用dpdm
来分析filestack-js项目中的循环依赖关系。它确实发现了一些错误,但看起来并不像是它们导致了错误,而且它似乎确实显式地排除了节点库和其他依赖库。
发布于 2021-08-27 05:22:57
好吧,我想我已经解决了我的问题,但我不是专家,所以我会试着解释问题是什么。如果你知道得更清楚,请随时加入澄清。
这是由于filestack-js
大量使用nodejs库造成的。历史上,Webpack v4已经填充了很多通用的NodeJS库在浏览器中使用,对大多数开发人员来说是完全透明的。这很好用,但却是完全神奇的。
Rollup,顺便说一句,Webpack v5,不做这种多层填充,所以来自NPM的"ESM“库使用的任何nodeJS库都不能直接与现代浏览器兼容。为了手动填充它,我必须指示Vite & Rollup将nodejs stream
模块的别名命名为与浏览器直接兼容的名称,并安装该模块。要做到这一点,我:
yarn add --dev stream-browserify
并将以下内容添加到我的vite.config.js
中
// ...
resolve: {
alias: {
stream: "stream-browserify",
},
},
// ...
应该有一种非常类似(但不同)的方式来告诉Rollup去做这件事,因为在这里我是通过Vite配置来做的。
对于额外的上下文,这里是我在filestack-js
存储库上打开的GitHub问题:https://github.com/filestack/filestack-js/issues/458
发布于 2021-11-04 07:21:38
按照Taylor推荐的链接中的建议直接导入。
import * as filestack from 'filestack-js/build/browser/filestack.esm';
https://github.com/filestack/filestack-js/issues/458#issuecomment-927373100
https://stackoverflow.com/questions/68944568
复制相似问题