Thursday, May 25, 2023

Naučite kako započeti sa TypeScript-om, iskoristite potencijal JavaScript-a uz nadogradnju

Ako pitate nekog od mnogobrojnih programera šta je to TypeScript, definitivno ćete dobiti mnogo konfuznih odgovora. Ako posetite zvaničnu prezentaciju TypeScript-a, pogledajte ovde; možete pročitati da je TypeScript programski jezik sa snažnim tipiziranjem koji se nadograđuje na JavaScript  programski jezik, pružajući vam bolje alate za rad u bilo kojoj razmeni. Znači TypeScript jeste programski jezik, koji za razliku od JavaScript-a koristi statički tipizirane promenjive ali je takođe i alat koji kompajlira i nadograđuje JavaScript sa mnogim stvarima koje JavaScript-u nedostaju. Možete li bar pokušati zamisliti kako to izgleda u praksi? Za početak, interesantno. Definitivno, nije nešto što ste do sada radili. Postoji jedna šala, kad vas neko pita koji programski jezik da uči; onda mu kažete  TypeScript jer je sve ostalo zastarelo. Činjenica je da TypeScript postoji još od 2012 godine, ali tek zadnjih godina je stekao sve veću popularnost. Da, iza njega stoji Microsoft korporacija; što programerima daje neku sigurnost, još bolja stvar je što je TypeScript besplatan programski jezik otvorenog kôda. Ako tu dodate jedno čuveno ime danskog softver inženjera Anders Hejlsberg-a, arhitektu C# programskog jezika, koji je takođe imao svoj ogroman doprinos kao tvorac Turbo Pascal-a. Onda za TypeScript možete biti sigurni da je to nešto genijalno i ozbiljna stvar koju jednostavno morate znati. Ali prvo da pogledamo šta je to sa JavaScript-om što je nateralo pametne ljude da stvore  TypeScript. Poznata je ogromna moć i sveprisutnost JavaScript programskog jezika na Internetu; ali sve više i na drugim uređajima; upravo zbog svoje jednostavnosti i što je zaista lak za učenje. Međutim, izazovi su nastali kad radite na velikim i složenim projektima.


( TypeScript nije samo programski jezik, već i alat i nadogradnja JavaScript-a )

Kad spojite interpreter i greške u sintaksi, pa čak i sa PHP programskim jezikom koji radi na strani servera, dobijete noćnu moru. Morate pokrenuti celu aplikaciju da bi ste otkrili grešku u sintaksi.  JavaScript koristi objekte i prati principe OOP - objektnog orjentisanog programiranja, ali to postiže korišćenjem čistih funkcija, što je svojstvo PF - paradigme funkcionalnog programiranja. On jednostavno prati i OOP i FP principe, ali zapravo je proceduralni jezik. TypeScript jednostavno generiše JavaScript. On jednostavno kompajlira TypeScript programski jezik u čisti JavaScript. Da, može zvučati kome treba taj dodatni posao, ali sa time se dobijaju neverovatne stvari. TypeScript na ovaj način ne treba novo radno okruženje već radi na svakom JavaScript okruženju. Ovo otvara mogućnost da se postojeći JavaScript projekti migriraju postepeno na TypeScript bez potrebe za pisanjem novog kôda. Dok JavaScript koristi određen ECMAScript standard, TypeScript kompajler ima parametar koji omogućava da prebacujete kôd između različitih ECMAScript standarda. Ipak, glavna karakteristika TypeScript-a je statičko tipiziranje, što znači da programerima omogućava da deklarišu vrste podataka. To pomaže otkrivanju grešaka i pruža bolju podršku za refaktorisanje kôda, automatsko završavanje kôda; kao i pravljenje poboljšane dokumentacije. TypeScript podržava napredne koncepte programiranja poput interfejsa, klasa, modula i generika. Jednostavno, TypeScript pomaže  programerima da pišu čistiji, pouzdaniji i lakše održavaju velike JavaScript projekte bez pisanja novog JavaScript kôda zahvaljujući naprednim programsko jezičkim konstrukcijama i funkcionalnosti koje nemate u JavaScript programskom jeziku. Nadam se da vam je sada jasnije zašto treba da učite i koristite TypeScript. Imajte samo na umu, sve ovo što ste pročitali u  praksi je mnogo jednostavnije.

Šta mi treba da počnem sa TypeScript programskim jezikom?


TypeScript projekte možete kreirati na različitim operativnim sistemima i možete koristiti različita IDE – integrisana razvojna okruženja. Moja preporuka je definitivno Visual Studio Code i Windows operativni sistem. Pogledajte u video-u kako se instalira Visual Studio Code.


( Windows - 1. How to install Visual Studio Code & .Net Core ? )

Ukoliko ipak; hoćete da koristite Linux operativni sistem, pogledajte video kako se instalira Visual Studio Code na Linux operativnom sistemu; Ubuntu distribuciji.


( Linux - 2. How to install Visual Studio Code and .NET Core ? )

Ukoliko ste vi C# programer ili jednostavno preferirate Microsoft Visual Studio integrisano razvojno okruženje; pogledajte video kako se instalira besplatna edicija Microsoft Visual Studio Community. Imajte samo u vidu da se projekti u Microsoft Visual Studio drugačije kreiraju; znači prvo kreirate ASP .NET prazan projekat, pa tek onda dodajete TypeScript fajlove. Inače, Microsoft Visual Studio radi sa TypeScript kao i sa C# programskim jezikom, omogućavajući vam efikasno ispravljanje grešaka.


( Windows - 4. How to install Microsoft Visual Studio Community? )

Pored IDE – integrisanog razvojnog okruženja, neophodno je da instalirate i platformu Node.js. Pogledajte u video-u kako se ova platforma instalira na Windows operativnom sistemu.


( Windows - 13. How to install Node.js ? )

Ukoliko koristite Linux operativni sistem, pogledajte kako se instalira Node.js na Linux operativnom sistemu, Ubuntu distribuciji.


( Linux - 14. How to install Node.js ? )

Pokrenite vaše IDE - integrisano razvojno okruženje, u našem tutorijalu to je definitivno Visual Studio Code. Otvorite i kreirajte novi projekat i nazovite ga ts_tutorial. Zatim kreirajte index.html fajl i ukucajte sledeći HTML kôd.

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>TypeScript Tutorial</title>

    <script src="lesson01.js"></script>

</head>

<body>

    <h1>Welcome to TypeScript Tutorial ... </h1>

</body>

</html>

Zatim kreirajte novi fajl i nazovite ga lesson01.ts i otkucajte sledeći sadržaj.

let greetings = 'Hi…'

console.log(greetings)

Otvorite terminal i otkucajte sledeću komandu da instalirate TypeScript i pritisnite Enter.

npm -i typescript -g

Komanda npm ili NPM – Node Package Manager; predstavlja paket menadžer sa kojim možete da upravljate sa mnogobrojnim paketima i zavisnostima u Node.js projektima. Malo slovo  -i predstavlja skraćenicu od install, typescript u ovom slučaju predstavlja naziv paketa za instalaciju dok malo -g predstavlja skraćenicu od global. Posle poprilično brze instalacije otkucajte sledeću komandu.

tsc lesson01.ts

Komanda tsc ili TSC – TypeScript Compiler; predstavlja kompajler. Navedena komanda kompajlira lesson01.ts fajl u čisti JavaScript fajl. Pogledajte lesson01.js fajl i sadržaj koji je kompajler kreirao.

var greetings = 'Hi…';

console.log(greetings);

Kao što ste primetili i pored toga što koristimo ključnu reč letTypeScript kompajler je generisao ključnu reč var koja omogućava da vaš JavaScript kôd radi i na starijim pretraživačima. Promenom ECMAScript standarda, možete promeniti i ovo ponašanje. To ćete videti kasnije; za sada obratite pažnju da vam Visual Studio Code prijavljuje grešku. Razlog je jednostavan, imate otvoren i lesson01.ts i lesson01.js otvoren, tako da promenjiva greetings dolazi u konflikt sama sa sobom. Isključite jedan tab ili panel bilo kojeg fajla i vaša greška će nestati. Kliknite desnim tasterom miša na index.html fajl, zatim u meniju kliknite na prvu stavku Open with Live Server. Ukoliko koristite Google Chrome pretraživač, kliknite na meniju stavku More Tools, zatim Developer Tools i pogledajte šta se otkucalo na Console. Pogledajte sliku.



( Pokretanje prvog TypeScript generisanog JavaScript koda na Google Chrome pretraživaču )

Ako sad promenite kôd u lesson01.ts.

let greetings = 'Hello World!';

console.log(greetings);

Da bi ste videli ovu promenu, morate ponovo da izvršite kompajliranje i Reload pretraživača. Šta će se desiti ako ukucate sledeću komandu?

tsc lesson01.ts -w

Pogledajte u terminal:

[12:11:14 AM] Starting compilation in watch mode...

[12:11:17 AM] Found 0 errors. Watching for file changes.

Ukoliko sad promenite kôd u lesson01.ts

let greetings = 'Hello World from Manuel!';

console.log(greetings);

Dobićete novi ispis u terminalu.

[12:13:51 AM] File change detected. Starting incremental compilation...

[12:13:51 AM] Found 0 errors. Watching for file changes.

Ali u pretraživaču u Console, rezultat će biti automatski promenjen i bez pritiskanja dugmeta Reload u pretraživaču.

Šta da radimo ako imamo veliki projekat i više TypeScript fajlova?

Kao što pretpostavljate kad kreirate velike projekte, sve što radite mora biti organizovano. Zato u Explorer Panel-u, kreirajte direktorijum src i u njega pomerite lesson01.ts. Zatim kreirajte novi folder build i u njega pomerite fajl index.html. Fajl koji vam je ostao lesson01.js samo obrišite. Zatim, u terminalu otkucajte sledeću komandu.

$ tsc –init

Pritisnite Enter.

Created a new tsconfig.json with:                                                                                                                                                                                                        TS

  target: es2016

  module: commonjs

  strict: true

  esModuleInterop: true

  skipLibCheck: true

  forceConsistentCasingInFileNames: true

 

You can learn more at https://aka.ms/tsconfig

Pogledajte u Explorer Panel i videćete da je formiran novi fajl tsconfig.json. Pogledajte sadržaj fajla.

{

  "compilerOptions": {

    /* Visit https://aka.ms/tsconfig to read more about this file */

 

    /* Projects */

    // "incremental": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */

    // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */

    // "tsBuildInfoFile": "./.tsbuildinfo",              /* Specify the path to .tsbuildinfo incremental compilation file. */

    // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */

    // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */

    // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */

 

    /* Language and Environment */

    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */

    // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */

    // "jsx": "preserve",                                /* Specify what JSX code is generated. */

    // "experimentalDecorators": true,                   /* Enable experimental support for legacy experimental decorators. */

    // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */

    // "jsxFactory": "",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */

    // "jsxFragmentFactory": "",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */

    // "jsxImportSource": "",                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */

    // "reactNamespace": "",                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */

    // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */

    // "useDefineForClassFields": true,                  /* Emit ECMAScript-standard-compliant class fields. */

    // "moduleDetection": "auto",                        /* Control what method is used to detect module-format JS files. */

 

    /* Modules */

    "module": "commonjs",                                /* Specify what module code is generated. */

    // "rootDir": "./",                                  /* Specify the root folder within your source files. */

    // "moduleResolution": "node10",                     /* Specify how TypeScript looks up a file from a given module specifier. */

    // "baseUrl": "./",                                  /* Specify the base directory to resolve non-relative module names. */

    // "paths": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */

    // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */

    // "typeRoots": [],                                  /* Specify multiple folders that act like './node_modules/@types'. */

    // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */

    // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */

    // "moduleSuffixes": [],                             /* List of file name suffixes to search when resolving a module. */

    // "allowImportingTsExtensions": true,               /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */

    // "resolvePackageJsonExports": true,                /* Use the package.json 'exports' field when resolving package imports. */

    // "resolvePackageJsonImports": true,                /* Use the package.json 'imports' field when resolving imports. */

    // "customConditions": [],                           /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */

    // "resolveJsonModule": true,                        /* Enable importing .json files. */

    // "allowArbitraryExtensions": true,                 /* Enable importing files with any extension, provided a declaration file is present. */

    // "noResolve": true,                                /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

 

    /* JavaScript Support */

    // "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */

    // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */

    // "maxNodeModuleJsDepth": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */

 

    /* Emit */

    // "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */

    // "declarationMap": true,                           /* Create sourcemaps for d.ts files. */

    // "emitDeclarationOnly": true,                      /* Only output d.ts files and not JavaScript files. */

    // "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */

    // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */

    // "outFile": "./",                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */

    // "outDir": "./",                                   /* Specify an output folder for all emitted files. */

    // "removeComments": true,                           /* Disable emitting comments. */

    // "noEmit": true,                                   /* Disable emitting files from a compilation. */

    // "importHelpers": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */

    // "importsNotUsedAsValues": "remove",               /* Specify emit/checking behavior for imports that are only used for types. */

    // "downlevelIteration": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */

    // "sourceRoot": "",                                 /* Specify the root path for debuggers to find the reference source code. */

    // "mapRoot": "",                                    /* Specify the location where debugger should locate map files instead of generated locations. */

    // "inlineSources": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */

    // "emitBOM": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */

    // "newLine": "crlf",                                /* Set the newline character for emitting files. */

    // "stripInternal": true,                            /* Disable emitting declarations that have '@internal' in their JSDoc comments. */

    // "noEmitHelpers": true,                            /* Disable generating custom helper functions like '__extends' in compiled output. */

    // "noEmitOnError": true,                            /* Disable emitting files if any type checking errors are reported. */

    // "preserveConstEnums": true,                       /* Disable erasing 'const enum' declarations in generated code. */

    // "declarationDir": "./",                           /* Specify the output directory for generated declaration files. */

    // "preserveValueImports": true,                     /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

 

    /* Interop Constraints */

    // "isolatedModules": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */

    // "verbatimModuleSyntax": true,                     /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */

    // "allowSyntheticDefaultImports": true,             /* Allow 'import x from y' when a module doesn't have a default export. */

    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */

    // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */

    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

 

    /* Type Checking */

    "strict": true,                                      /* Enable all strict type-checking options. */

    // "noImplicitAny": true,                            /* Enable error reporting for expressions and declarations with an implied 'any' type. */

    // "strictNullChecks": true,                         /* When type checking, take into account 'null' and 'undefined'. */

    // "strictFunctionTypes": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */

    // "strictBindCallApply": true,                      /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */

    // "strictPropertyInitialization": true,             /* Check for class properties that are declared but not set in the constructor. */

    // "noImplicitThis": true,                           /* Enable error reporting when 'this' is given the type 'any'. */

    // "useUnknownInCatchVariables": true,               /* Default catch clause variables as 'unknown' instead of 'any'. */

    // "alwaysStrict": true,                             /* Ensure 'use strict' is always emitted. */

    // "noUnusedLocals": true,                           /* Enable error reporting when local variables aren't read. */

    // "noUnusedParameters": true,                       /* Raise an error when a function parameter isn't read. */

    // "exactOptionalPropertyTypes": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */

    // "noImplicitReturns": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */

    // "noFallthroughCasesInSwitch": true,               /* Enable error reporting for fallthrough cases in switch statements. */

    // "noUncheckedIndexedAccess": true,                 /* Add 'undefined' to a type when accessed using an index. */

    // "noImplicitOverride": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */

    // "noPropertyAccessFromIndexSignature": true,       /* Enforces using indexed accessors for keys declared using an indexed type. */

    // "allowUnusedLabels": true,                        /* Disable error reporting for unused labels. */

    // "allowUnreachableCode": true,                     /* Disable error reporting for unreachable code. */

 

    /* Completeness */

    // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */

    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */

  }

}


Zahvaljujući ovom *.json fajlu, vi možete da konfigurišete i uključite u svoj projekat sve navedene mnogobrojne opcije. Za sada ćemo uključiti samo neke opcije kako bi smo naveli kompajler da zna u kom folderu da smešta generisane JavaScript fajlove. Pronađite i omogućite sledeće opcije u navedenom fajlu.

"rootDir": "./src",

i

"outDir": "./build/js",

U terminalu ukucajte sledeću komandu.

tsc -w

Pogledajte u Explorer Panel direktorijum build i videćete da je kreiran novi folder js gde će biti smešteni generisani JavaScript fajlovi. Sad kreirajte novi fajl test.ts u src direktorijumu. Ukucajte sledeći kôd.

let greetings = 'Hello World from Manuel!';

console.log(greetings);

I pogledajte u js direktorijumu fajl test.js.

"use strict";

var greetings = 'Hello World from Manuel!';

console.log(greetings);

Obrišite test.ts fajl. I primetićete da za razliku od kreiranja generisanog *.js fajla, prilikom brisanja *.ts fajla, fajl *.js se ne briše. Njega uvek morate obrisati kada brišete i *.ts fajl. Ukoliko želite da koristite umesto ključne reči let, ključnu reč var, za starije pretraživače; jednostavno promenite  ECMAScript standard u tsconfig.json fajlu. Na primer ES5.

"target": "es5",

Sad promenite kôd u lesson01.ts

var greetings = 'Hello World from Manuel!';

console.log(greetings);

I to će imati smisla. Inače vratite ES2016, i otkucajte pravilno kôd u lesson01.ts.

let greetings = 'Hello World!';

console.log(greetings);

U index.html promenite putanju:

<script src="/build/js/lesson01.js"></script>

Pokrenite vaš pretraživač i u njemu ćete dobiti u Console:

Hello World! 

Nadam se da ste sada naučili kako se počinje sa TypeScript-om. Kako ovo sve izgleda možete pogledati i u sledećem video-u.


( TypeScript - 1. How to start with TypeScript ? )















 

 

No comments:

Post a Comment