#javascript #node.js #es6-modules #vite #filestack
Вопрос:
Я использую filestack-js
в проекте Rails, который поставляется в комплекте с Vite. Все работает так, как ожидалось, пока я не включу модуль ESM для filestack-js
библиотеки, в данном случае в контроллер 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 непосредственно в браузере. Он обрабатывает компиляцию машинописного текста. Удаление import * as filestack
бита устраняет ошибку (но, очевидно, нарушает функциональность класса).
Мои поиски в Google, похоже, предполагают, что это может быть проблемой циклической зависимости. Трассировка стека браузера указывает на файл в 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, чтобы точно понять, что значит использовать библиотеку NodeJS, как Stream
в модуле браузера, — filestack-js
в ней есть как браузерные модули, так и модули CommonJS/NodeJS, поэтому я не уверен, как/связаны ли они или взаимодействуют.
Вот как Stream
выглядит объект при входе в консоль браузера. Очевидно, что что-то было импортировано, но Writable
не является свойством того, что было импортировано:
FWIW это происходит в Chrome и Firefox, последних версиях каждого из них.
Я также попытался использовать dpdm
для анализа проекта filestack-js на наличие циклических зависимостей. Он нашел некоторые, но не похоже, что они вызывают ошибки, и, похоже, явно исключаются библиотеки узлов и другие библиотеки зависимостей.
Комментарии:
1. Хорошо, я вижу, что это может быть связано с тем фактом, что Vite использует накопительный пакет под капотом, и этот накопительный пакет может не справляться с определенными циклическими зависимостями, существующими в библиотеках NodeJS? это репозиторий существует, и кажется, что он может быть разработан для решения такого рода проблем, но, похоже, он не работает для меня.
2. Действительно ли этот стимул и ваш собственный класс необходимы для того, чтобы вызвать проблему, или это уже происходит, если все, что вы делаете, — это импортируете
filestack-js
библиотеку?3. @Bergi Я могу подтвердить, что это не имеет отношения к делу. Просто так получилось, что я пользуюсь библиотекой именно там. Извини, что я не ясно выразился.
4. В этом случае я бы определенно сообщил об этом как об ошибке в их системе отслеживания проблем. Тем более, что документация утверждает, что работает с накопительным пакетом из коробки. Однако вам следует поделиться своей конфигурацией свертки
5. Ого, я пропустил эту ссылку на свертку. До сих пор я не решался опубликовать проблему, потому что у меня нет простого решения, но, думаю, я мог бы придумать более простое. Спасибо.
Ответ №1:
Хорошо, я думаю, что решил свою проблему, но я не эксперт, поэтому я попытаюсь объяснить, в чем была проблема. Не стесняйтесь вступать в разговор с разъяснениями, если вам лучше известно.
Это было вызвано filestack-js
интенсивным использованием библиотек nodejs. Исторически сложилось так, что Webpack v4 заполнил множество распространенных библиотек NodeJS для использования в браузере, полностью прозрачных для большинства разработчиков. Это прекрасно работало, но было полным волшебством.
Накопительный пакет и, кстати, Webpack v5 не выполняют этого заполнения, поэтому любые библиотеки NodeJS, используемые библиотеками «ESM» из NPM, которые напрямую не совместимы с современными браузерами, просто сломаются. Чтобы заполнить это вручную, мне пришлось поручить Vite amp; Rollup присвоить псевдоним имени модуля nodejs stream
чему-то, что напрямую совместимо с браузерами, и установить его. Чтобы сделать это, я:
yarn add --dev stream-browserify
И добавил следующее к моему vite.config.js
:
// ...
resolve: {
alias: {
stream: "stream-browserify",
},
},
// ...
Должен быть очень похожий (но другой) способ сообщить свертке, чтобы сделать это, потому что здесь я делаю это через конфигурацию Vite.
Для дополнительного контекста вот проблема GitHub, которую я открыл в filestack-js
репо: https://github.com/filestack/filestack-js/issues/458
Ответ №2:
Импортировал его напрямую, как рекомендовано в ссылке, рекомендованной Тейлором.
import * as filestack from 'filestack-js/build/browser/filestack.esm';
https://github.com/filestack/filestack-js/issues/458#issuecomment-927373100