Задать вопрос

Как импортировать файлы в manifest для расширения firefox?

Здравствуйте, изучаю TypeScript и решил использовать его в одном из своих проектов - расширение для Firefox

Я хочу сделать модульную систему, чтобы проект легко можно было масштабировать в будущем, поэтому пытаюсь разделить функционал по файлам (файл core.ts пытается импортировать файлы modules/log.ts и т.д, а они наследуются от modules/module.ts)

Файловая структура:
  • system
    • core.ts
    • modules
      • module.ts
      • log.ts
        ...





Код manifest.json
{
    "version": "1.0",
    "manifest_version": 2,
    "name": "надрез мозжечка",
    "description": "Манипулятор ВКонтакте с функцией самоподрыва от Альянса Злодеев",
    "applications": {
        "gecko": {
            "id": "vk@mirzaev.sexy",
            "strict_min_version": "95.0.2"
        }
    },
    "content_scripts": [
        {
            "matches": [
                "*://*.vk.com/*"
            ],
            "js": [
                "/system/modules/module.js",
                "/system/modules/log.js",
                "/system/modules/visor.js",
                "/system/modules/killer.js",
                "/system/core.js"
            ]
        }
    ]
}


И вот что я получаю в итоге:
624f776d2ac79122766054.png

Код module/module.ts (буквально нихера там нет)
/**
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
export default class module {
}


Код module/log.ts (загружается после module/module.ts и импортирует его - вероятно проблема здесь)
import module from "./module";

export default class log extends module {
    constructor(public debug: boolean = false) {
        super();
    }

    /**
     * Запись в журнал
     *
     * @param text Текст для записи
     */
    write(...text: string[]) {
        if (this.debug) {
            // Активен режим отладки

            console.log('[надрез мозжечка]', ...text);
        }
    }
}


После компиляции код modules/log.js выглядит вот так:
"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
exports.__esModule = true;
var module_1 = require("./module");
var log = /** @class */ (function (_super) {
    __extends(log, _super);
    function log(debug) {
        if (debug === void 0) { debug = false; }
        var _this = _super.call(this) || this;
        _this.debug = debug;
        return _this;
    }
    /**
     * Запись в журнал
     *
     * @param text Текст для записи
     */
    log.prototype.write = function () {
        var text = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            text[_i] = arguments[_i];
        }
        if (this.debug) {
            // Активен режим отладки
            console.log.apply(console, __spreadArray(['[надрез мозжечка]'], text, false));
        }
    };
    return log;
}(module_1["default"]));
exports["default"] = log;


Почему загрузился только modules/module.js???
Проверю любые предположения
  • Вопрос задан
  • 100 просмотров
Подписаться 1 Средний 2 комментария
Решения вопроса 1
Mirzaev
@Mirzaev Автор вопроса
Я решил оставить пока TS, разрабатываю на сыром JS. Переписал всё это под него и получил ту же проблему

Я, кажется, понял: все файлы уже подгружены, так как указаны в manifest.json
к сожалению как сделать динамическую подгрузку я не знаю, а оно мне и не надо в расширении, в принципе

Удалил все выражения импорта и всё работает
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Psychosynthesis
@Psychosynthesis
Fullstack developer and radio engineer
Я столкнулся по сути с той же проблемой, хотя я пишу без всяких сборщиков, так что код попроще для понимания, так что возможно кому-то ещё может пригодится мой подход.

Короче, в моём случае, я тоже хотел вынести общие функции в отдельный файл и импортить его где необходимо.
У меня изначально всего один background-скрипт и ещё пара для меню. Вот мой изначальный манифест (очевидно не целиком, а лишь значимые части):
{
	...
	"background": {
		"scripts": ["queryParamsRemover.js"]
	},
	"browser_action": {
		"browser_style": true,
		"default_icon": "icons/panelicon.png",
		"default_title": "Eraser",
		"default_popup": "panel/panelMenu.html"
	},
	...
}


Соответственно, код с логикой panelMenu у меня подключался просто через тег в теле panel/panelMenu.html:
<script src="panelMenu.js"></script>

Естессна, никакие импорты внутри panelMenu.js не работали, вылетала ошибка Uncaught SyntaxError: import declarations may only appear at top level of a module. Очевидно, при попытке импортить что-либо в queryParamsRemover.js ошибка была аналогичная.

Как выяснилось, решения у данной проблемы два:
1. В файл panelMenu.html скрипт встраивается с атрибутом type="module":
<script src="panelMenu.js" type="module"></script>
После этого внутри panelMenu.js уже работают привычные импорты (кому-то хватит и этого, полагаю).
Далее, чтобы импорты заработали и в основном background-скрипте (у меня это queryParamsRemover), придётся немного изменить подход. Решение (как по мне) выглядит несколько коряво, но именно так предлагает делать официальная документация: https://developer.mozilla.org/ru/docs/Mozilla/Add-...

Итак, нужно изменить манифест:
"background": {
	"page": "background.html"
}

А уже в этом самом background.html вставлять основной скрипт всё с тем же атрибутом module:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script type="module" src="queryParamsRemover.js"></script>
  </head>
</html>

Собсна, вуаля. Теперь всё работает везде, хотя (как по мне), лишняя веб-страница выглядит каким-то костылём. Почему нельзя было какой-нить атрибут в манифест добавить, что скрипт как модуль выполнялся - непонятно сршна.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы