Frank Hliva - PlutonKrea s.r.o

Front-end Developer & majiteľ

rokov skúsenosti

rokov prax

roky React

Úvod / Blog / Problémy s importami v JS

Problémy s importami v JS

Publikoval Frank Hliva 2019-10-09 17:00:00 print comments
dev js typescript

Pamatá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ť). 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ť napíklad takto:

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

Dnes to už kô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žíbajte eval! Eval je evil: či už kôli bezpečnosti, alebo kô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 lahšie importuje (poriadny editor vám ho naimportuje automaticky!). Bohužiaľ v TS neni 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ôžte si vybrať či takto:

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

alebo takto:

import { PomenovanyModule } '@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ž rok 2 roky používam Typescript. Vačšinu problémov s modulmi vytvorili samotní autori dnešnej implementácie. Tá totiž nebola úplne domyslená, vďaka čomu sa FE developeri stratávajú s problémami, ktoré mali iné vývojárske platformy vyriešené už v polovici 90tych rokov.