I'm using filestack-js
in a Rails project which is bundled with Vite. Everything works as expected until I include the ESM module for the filestack-js
library, in this case in a StimulusJS controller:
import { Controller } from "stimulus";
import * as filestack from "filestack-js";
export default class extends Controller {
// some irrelevant implementation code that calls filestack.init(...)
}
Loading the above controller file in the browser causes an error:
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
This is an error produced by the browser while working in a development environment, using Vite to build and serve ES modules to the browser directly. It handles Typescript compilation. Removing the import * as filestack
bit makes the error go away (but obviously breaks the class' functionality).
My google searches seem to suggest that this might be a circular dependency problem. The browser stack trace points towards a file in the filestack-js
library:
// 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
}
Where Stream.Writable
is actually undefined due to a circular dependency problem. I have no idea how that would happen or seem to only affect me.
This is not an issue that has been reported on the filestack-js issue tracker.
Debugging in the browser and cloning/linking the repository locally have confirmed that Stream.Writable
is returning undefined
, but I don't know enough about JS to understand why. Supposedly this typically happens due to a circular dependency, but I'm not sure how the nodejs Stream
module would have circular dependencies on a random library like filestack-js
. I am also inexperienced enough in the JS world to understand exactly what it means to be using a nodeJS library like Stream
in a browser module - filestack-js
has both browser modules and commonJS/nodeJS modules so I'm not sure how/if they relate or interact.
Here's what the Stream
object looks like when logged to a browser console. Clearly something has been imported but Writable
is not a property of what was imported:
FWIW this happens on Chrome and Firefox, latest versions of each.
I also tried using dpdm
to analyze the filestack-js project for circular dependencies. It did find some but it doesn't appear as if they are causing errors, and it does seem to explicitly be excluding node libraries and other dependency libraries.