Vyhledávání na webu

typescript - import mathjax vyvolá chybu @types/mathjax/index.d.ts není modul


Snažím se importovat MathJax do souboru TypeScript.

Můžete reprodukovat podle následujících kroků:

tsc --init
npm init -y
npm i mathjax @types/mathjax
echo "import { MathJax } from 'mathjax';" > index.ts

Zkoušel jsem všechny následující důležité syntaxe:

import { MathJax } from 'mathjax';
import mathjax from "mathjax";
import * as mathjax from "mathjax"
import { * as MathJax } from "mathjax";

Ale všechny vracejí následující chybu:

'../node_modules/@types/mathjax/index.d.ts' is not a module.

Také jsem zkusil přidat mathjax do types v mém tsconfig.app.json takto (ale ani to nepomohlo)

"types": [
   "mathjax"
]

Související problémy

  • StackOverflow

    • MathJax není definován v Angular 4
    • Použití MathJax uvnitř komponenty Typescript/Angular2
    • Typy TypeScriptu mi dávají ‚index.d.ts není modul‘
  • Problémy na Githubu

    • Jednoduchý příklad s Typescriptem #2310
    • Jak používat MathJax v projektu TypeScript? #2385

Odpověď č. 1

Tato odpověď je napsána s ohledem na použití MathJax v webovém projektu. Pokud to pro vás není tento případ, mnoho z toho se přesto vztahuje, protože se to týká Typescriptu, který zjevně používáte.

1. MathJax je určen k stažení v prohlížeči

Bez ohledu na dnešní situaci je MathJax historicky stahován v prohlížeči a neměl by být importován do projektu zaměřeného na web jako ostatní npm balíčky. Pod Installation and use na https://www.npmjs.com/package/mathjax můžete vidět, že MathJax byste měli používat v projektu tímto způsobem pouze tehdy, pokud vytváříte backendovou Node aplikaci, jinak by měl být MathJax importován do frontendu pomocí skriptu. Můžete hostovat vlastní kopii MathJax jako statický soubor na svém webovém serveru a načítat ji odtud pomocí script tagu z frontendu (podobně jako z jakéhokoli CDN), ale neměli byste ji zabudovávat do frontendu jako běžné npm balíčky tím, že ji importujete do zdrojových souborů. Proč je to důležité? Protože to ovlivňuje, jak je MathJax organizován, historicky i dnes, což následně ovlivňuje, jak je nakládáno v projektu Typescript.

2. Balíčky MathJax

MathJax má dvě verze, MathJax 2 a 3. Verze 2 se interně a syntakticky velmi liší od verze 3, ale stále se používá, i když je doporučována verze 3. Balíček mathjax z npmjs.org je balíček MathJax 3. Pokud půjdete na GitHub repozitář MathJax, můžete stáhnout starší balíčky, ale nemyslím si, že jsou dostupné jako npm balíčky. Na oficiální stránce MathJax pod Server integration se můžete dočíst, jak stáhnout MathJax pro backend. Také zde uvidíte, že existují dva npm balíčky: mathjax a mathjax-full, z nichž druhý obsahuje „úplný zdrojový kód“. MathJax je napsán s podporou Typescript, takže můžeme očekávat, že existují typy. Pokud navštívíte záznamy těchto balíčků na npmjs.org (https://www.npmjs.com/package/mathjax a https://www.npmjs.com/package/mathjax-full), uvidíte, že mathjax-full obsahuje typy, které mathjax neobsahuje. To je také patrné při prohlížení stažených balíčků v node_modules.

Tak co je to balíček @types/mathjax? No, při bližším prozkoumání vidíme, že je spojen s verzí 2 MathJax, protože jeho deklarace typů zahrnují použití MathJax.Hub, které se používá pouze ve verzi 2. Také jeho index.d.ts, vstupní bod pro typy, když není uvedeno nic konkrétnějšího než

import mathjax from "mathjax"

nebo

import * as mathjax from "mathjax"

deklaruje jmenný prostor s exporty uvnitř

declare namespace MathJax {
    export ...
    export ...
}

Namespaces se v JavaScriptu používají k organizaci kódu do různých oddělených komponent, jakási dřívější alternativa modulů, které dělají totéž bez namespaces. V dokumentaci TypeScriptu (https://www.typescriptlang.org/docs/handbook/modules.html) se doslova uvádí, že V TypeScriptu, stejně jako v ECMAScript 2015, je jakýkoli soubor obsahující import nebo export na nejvyšší úrovni považován za modul. Balíček @types/mathjax toto nemá, což vede k tomu, že není modulem, což také hlásí váš překladač.

Kromě toho, že @types/mathjax není propojen s npm balíčkem mathjax (což je špatná organizace, vím) kvůli různým verzím, také nepodporuje moderní syntax modulů. Řekl bych, že je starý, ale měl poměrně nedávno vydání, takže upřímně nevím, o co jde, možná to má něco společného s tím, jak se MathJax obvykle importuje, nebo to má fungovat v nějaké jiné, velmi specifické situaci. Všechno, co vím, je, že podle dokumentace Typescriptu tento balíček typů není považován za modul (jak naznačuje váš kompilátor) a jeho typy nejsou v souladu s MathJax verzí 3, například rozhodně si nemyslím, že by existovalo oficiální propojení mezi tímto balíčkem a balíčkem, který má podporovat.

Takže pokud máme mathjax-full, máme typy, že? Ano, to je pravda, ale organizace souborů v mathjax-full není přizpůsobena vašemu použití. Za prvé, chybí index, takže neexistuje žádný rozumný vstupní bod pro použití takových import příkazů, jak bylo dříve popsáno (jak bylo řečeno, když není cílen žádný konkrétní zdroj, přirozeným vstupním bodem je indexový soubor). package.json zahrnutý neobsahuje ani informace o balíčku, ani informace o typech (můžete si to sami ověřit v node_modules). I když se pokusím použít to bez Typescriptu, nefunguje to kvůli chybám o tom, že require není definován. Celkově tento balíček není určen k používání jako běžný balíček npm; měl by být používán těmi, kteří chtějí pracovat se zdrojovým kódem MathJaxu, a rozhodně ne pro případ „průměrného uživatele tvořícího webovou aplikaci“. Pro tyto účely by měl být MathJax používán jako samostatný projekt jako černá skříňka, ke kterému se přistupuje přes import skriptu (opět z historických důvodů... takto to bylo přibližně před 15 lety).

3. Jak to funguje ve vašem konkrétním případě použití

Aby to fungovalo ve vašem případě použití, a tím myslím, aby váš kompilátor přijal váš import (nic jiného), existuje několik věcí, které můžete udělat. Říkám to, protože cítím zájem o to, jak Typescript funguje zde také.

V případě balíčku @types/mathjax můžete vstoupit do jeho souboru index.d.ts v node_modules a na jeho spodní část (nejvyšší úroveň) přidat export default MathJax. Nyní má soubor globální export a proto importní příkazy jako

import * as mathjax from "mathjax"
import mathjax from "mathjax"

nebude mít za následek stížnosti, které jste viděli dříve. I tak by to však nefungovalo kvůli chybám require, které jsem krátce popsal dříve.

V případě mathjax-full, pokud se podíváte na kód v node_modules, můžete vidět, že skutečně existují soubory Typescript spolu se zdrojovým kódem v podadresáři js. Ale protože index není přítomen (což je také jasná narážka, že balíček by neměl být používán ve webových projektech pomocí importů), výchozí importy nebudou fungovat (kompilátor bude hlásit chyby typů). Pokud se však zaměříte na konkrétní součást, například

import { mathjax } from "mathjax-full/js/mathjax"

Najde odpovídající typy a nedostanete chybu. Ve skutečnosti pak dostanete jakýsi objekt MathJax, ale nevím, jestli by to fungovalo zcela (zkuste to, pokud chcete). Kromě toho mám podezření, že byste ve svém balíčku dostali spoustu nepotřebných souborů navíc (nebo byste museli strávit hodně času přizpůsobováním tree-shakingu), protože MathJax je používán k určení, které soubory potřebuje při použití, a může být pro balíčkovač těžké to určit v době sestavení.

4. Tak jak byste to MĚLI OPRAVDU spravit?

Nejlepší způsob je použít balíček React pro MathJax. Zde doporučím svůj vlastní balíček better-react-mathjax (https://www.npmjs.com/package/better-react-mathjax), ale existují i jiné. Takové balíčky se snaží překlenout propast mezi MathJax a Reactem, jako tu, kterou právě zažíváte.

Pokud to chcete udělat složitější cestou, použijete zdrojový kód v balíčcích MathJax a zahrnete je jako součást svých statických souborů, a pak vložíte script tag v Reactu, který načte soubor se startovacím skriptem MathJax z vašeho statického backendu. Můžete to udělat také tímto způsobem a načíst stejný soubor z CDN, pokud nechcete hostovat vlastní kopii.

Pokud opravdu potřebujete používat MathJax na backendu, doporučil bych prozkoumat balíček mathjax-full a pokusit se převést pokyny o jeho používání v Node z oficiální dokumentace MathJax, na kterou bylo dříve odkázáno, na váš případ použití, pracující s explicitními importy místo výchozích, abyste získali podporu typů.

Doporučení

Vnímám jistý zájem o organizaci kódu a moduly (možná mylně) z vaší strany, což je složité téma. Zkuste napsat svůj vlastní balíček a distribuovat ho přes npm, abyste získali pochopení rolí, které hrají npm, Node, Typescript, moduly ecmascript, moduly commonjs a tak dále. Pochopení různých formátů modulů a toho, jak je dovoleno, aby spolu interagovaly v projektech Typescript za použití funkcí jako esModuleInterop a allowSyntheticDefaultImports, jsou také důležitá témata a distribucí vlastního balíčku skutečně získáte představu o rozdílech mezi zdrojovým kódem v projektu a zdrojovým kódem v balíčcích.

Odpověď č. 2

Jednoduše importujte knihovnu typings:

import "mathjax";

použijte volbu kompilátoru "types": ["mathjax"].

odkaz: referenční odkaz

Doufám, že to pro tebe bude fungovat!!

Související články