·Publikoval Frank Hliva·3 min čítania

Problémy s importami v JS

Problémy s importami v JS

Pamätám si časy keď JSko oficiálne nepodporovalo moduly. Programátori si miesto nich ohýbali objekty. Viditeľnosť sa riešila cez uzávery. Jediné čo JS nemal vyriešené bolo načítavanie jednotlivých súborov. Mnohí to mali poriešené cez dynamické pridávanie JSiek do headeru.

Ja som mal už vtedy preprocesor, ktorý všetky JS súbory spojil do jedného… Tým sa minimalizoval aj počet requestov.

Pozn.: Dnes už nemusíme riešiť optimalizáciu requestov, ale v časoch keď internetu kraľoval protokol HTTP 1.0, každý jeden prenášaný súbor znamenal samostatný request (HTTP 2.0 si tieto veci optimalizuje).

Dnes (vďaka Webpacku aj podpore v prehliadačoch) už JavaScript moduly oficiálne podporuje. A stali sa aj súčasťou HTML5. No tieto moduly majú viac nevýhod ako výhod.

Problémy modulov v TypeScripte:

  1. Problém - Neviem si modul rozdeliť do viacerých súborov.
  2. Problém - Neviem si vytvoriť vnorený modul v inom súbore ako bol nadmodul.
  3. Problém - Neviem si naimportovať obsah celého modulu bez prefixu, bez toho aby som explicitne vymenoval všetky jeho identifikátory (v iných jazykoch samozrejmosť). V JS musím vymenovať všetky identifikátory ktoré chcem naimportovať:
import { Trieda, funkcia1, funkcia3, ..., funkcia1000 } from "/module";

alebo použijem operátor *:

import * as zastupnyNazov from "/module";

lenže v tom prípade si musím import pomenovať a volať cez takúto konvenciu:

zastupnyNazov.funkcia1;

Kedysi sa to dalo obísť napríklad takto:

for (let k in objektNaimportovanehoModulu) {
    eval(`var ${k} = helpers.${k}`)
}

Dnes to už kvôli strict režimu nejde. Dnes by sa to dalo vyriešiť elegantnejšie na úrovni Webpacku, ale evidentne sa do toho nikomu nechce.

Pozn.: Nepoužívajte eval! Eval je evil: či už kvôli bezpečnosti, alebo kvôli nízkemu výkonu (kód uložený v stringu sa ťažko optimalizuje).

  1. Problém - v JS máme 2 typy exportov: defaultný a export pomenovaného modulu. Ten defaultný umožňuje importovať aj jednotlivé časti modulu. Ten pomenovaný sa zase ľahšie importuje (poriadny editor vám ho naimportuje automaticky!). Bohužiaľ v TS nie je možnosť jeden modul vyexportovať oboma spôsobmi.

Ale že ste to vy, jeden dirty hack vám predsa len ukážem:

Súbor ./PomenovanyModule/AnonymnyModul.ts:

export const alertX = function() {
    alert("X")
}

export const alertY = function() {
    alert("Y")
}

export const alertZ = function() {
    alert("Z")
}

Súbor ./PomenovanyModule/index.ts:

import * as PomenovanyModul from './AnonymnyModul';
export { PomenovanyModul };

a potom to už len pekne naimportujete, môžete si vybrať či takto:

import { alertX, alertY } from '@lib/PomenovanyModul/PomenovanyModul';

alebo takto:

import { PomenovanyModule } from '@lib/PomenovanyModul';

samozrejme to nerieši problémy 1 - 3.

Toto sú problémy modulov TS v kombinácii s Webpackom. V samotnom JS je tých obmedzení o niečo menej, nie som si teraz istý či sa bod č. 4 týka aj JS, už 2 roky používam TypeScript. Väčšinu problémov s modulmi vytvorili samotní autori dnešnej implementácie. Tá totiž nebola úplne domyslená, vďaka čomu sa FE developeri stretávajú s problémami, ktoré mali iné vývojárske platformy vyriešené už v polovici 90-tych rokov.

Share:
Späť na blog

Súvisiace čítanie

Ďalšie články z blogu

Zobraziť všetky články
F# - async a kompatibilita s jazykom C#

F# - async a kompatibilita s jazykom C#

Jazyk F# je priekopníkom v zavádzaní nových paradigiem a postupov a tak to bolo aj v prípade práce s asynchrónnym kódom. Zatiaľ čo C# zaviedol async / await až vo verzii 5.0 (jún 2013), F# mal syntaktický cukor pre prácu s asynchrónnym kódom už dávno predtým.

Čítať článok