Модульная система Typescript.
Фронтенд разработка на языке JavaScript. -> Модульная система Typescript.
Typescript. Начало работы.
Инициализация npm проекта.
npm init
Установка транспилятора
sudo npm install -g typescript
Установка и обновление nodejs и npm.
npm install npm@latest -g
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
Проверка версии.
node -v
Создание конфигурационного файла.
Первая программа app.ts.
function greeter(person) {
return "Hello, " + person;
}
greeter('Dima')
Компиляция.
tsc app.ts
Либо указывая полный путь.
./node_modules/.bin/tsc
Стартовая страница
<!DOCTYPE html>
<html>
<head><title>TypeScript Greeter</title></head>
<body>
<script src="app.js"></script>
</body>
</html>
Добавление веб сервера.
npm install lite-server --save
Иногда возникает ошибка permission denied, mkdir ‘/home/user/.npm для устранения удалите папку .npm
Запуск веб сервера.
./node_modules/.bin/lite-server
Создание конфигурационного файла tsconfig.json
В этом файле определяются:
-
входная (корневая) директория проекта;
-
выходная директория;
-
опции компилятора;
-
определяются какие файлы включать и выключать из компиляции.
{ “compilerOptions”: { “emitDecoratorMetadata”: true, “experimentalDecorators”: true, “module”: “commonjs”, “target”: “es2015”, “outDir”: “built”, “rootDir”: “src” } }
если вы указываете файл для компиляции явно то конфигурационный файл игнорируется!
Список всех настроек typescript
Перенесем app.ts файл в папку src.
Запуск транспилятора в режиме отслеживания изменений (watch).
tsc -w
Исключение и включение каталогов из процесса слежения (tsconfig.json).
{
"compilerOptions": {
....
},
"include": [
"**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]}
При этом приняты следующие условные обозначения.
-
- любое кол-во символов, исключая разделитель каталогов
? - один любой символ, исключая разделитель каталогов
**/ - все подкаталоги
Полная версия
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"noImplicitAny": false,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": [
"node_modules/*"
]
}
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
]
}
Определение типа передаваемого значения.
function greeter(person: string) {
Попытка передать неверный тип.
let user = [0, 1, 2];
document.body.innerHTML = greeter(user);
src/app.ts:7:35 - error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.
Определение типа возвращаемого значения.
function greeter(person: string): number {
return "Hello, " + person;
}
src/app.ts:8:1 - error TS2322: Type 'number' is not assignable to type 'string'.
Модульность
Определим библиотечную функцию src/lib/function.ts.
export function sayHello( name ) {
return `Hello {$name}`;
};
Импортируем ее в главном модуле app.js.
import { sayHello } from './lib/function';
console.log(sayHello());
Получаем ошибку в консоле.
app.js:2 Uncaught ReferenceError: exports is not defined
Это значит что js не знает конструкцию exports и для этого необходимо использовать загрузчик модулей, например SystemJS.
Установка.
npm install systemjs@0.19.22 --save
Шаблон
<!DOCTYPE html>
<html>
<head><title>TypeScript Greeter</title>
<script src="node_modules/systemjs/dist/system.js"></script>
</head>
<body>
<script>
SystemJS.config({
defaultJSExtensions: true
});
SystemJS.import('built/index.js');
</script>
</body>
</html>
При компиляции на лету (внутри браузера без запуска tsc).
<!DOCTYPE html>
<html>
<head><title>TypeScript Greeter</title>
<script src="node_modules/systemjs/dist/system.js"></script>
<script src="node_modules/typescript/lib/typescript.js"></script>
</head>
<body>
<script>
SystemJS.config({
transpiler: 'typescript',
packages: {
src: {
defaultExtension: 'ts'
}
}
});
SystemJS.import('src/index.ts');
</script>
</body>
</html>
Фронтенд разработка на языке JavaScript. -> Пракрикум. Нахождение общего делителя.
Нахождение общего делителя.
Создаем поток
import { range } from 'rxjs';
const CONST1 = 20;
const stream1 = range(1,CONST1);
Преобразуем в массив и сортируем.
...
import { toArray, map } from 'rxjs/operators';
stream1
.pipe(toArray(),map(arr=>arr.sort((a,b) => b-a)))
.subscribe((el) => {
console.log(el);
})
Переключаемся на второй поток из масива и выбираем из него все что делится без остатка.
stream1
.pipe(
toArray(),
map(arr=>arr.sort((a,b) => b-a)),
switchMap( (rez) => from(rez)
.pipe(filter((el: any) => CONST1%el === 0))
)
)
.subscribe((el) => {
console.log(el);
})
Оформляем 2 потока.
const CONST1 = 20;
const CONST2 = 50;
const stream1 = range(1,CONST1)
.pipe(
toArray(),
map(arr=>arr.sort((a,b) => b-a)),
switchMap( (rez) => from(rez)
.pipe(filter((el: any) => CONST1%el === 0))
)
);
const stream2 = range(1,CONST2)
.pipe(
toArray(),
map(arr=>arr.sort((a,b) => b-a)),
switchMap( (rez) => from(rez)
.pipe(filter((el: any) => CONST2%el === 0))
)
);
stream1.subscribe((el) => {
console.log(`stream1 = ${el}`);
})
stream2.subscribe((el) => {
console.log(`stream2 = ${el}`);
})
Создаем 3 поток где выбираем совпадающие элементы, переключаясь на второй поток, переводим их в массив и получаем наибольшее.
const stream3 = stream1.pipe(
switchMap((el1) => stream2.pipe(filter((el2) => el2 === el1))),
toArray()
).subscribe((el) => {
console.log(Math.max(...el));
})
Полный код примера.
import { from } from 'rxjs';
import { range } from 'rxjs';
import { toArray, map, switchMap, filter } from 'rxjs/operators';
const CONST1 = 20;
const CONST2 = 50;
const stream1 = range(1,CONST1)
.pipe(
toArray(),
map(arr=>arr.sort((a,b) => b-a)),
switchMap( (rez) => from(rez)
.pipe(filter((el: any) => CONST1%el === 0))
)
);
const stream2 = range(1,CONST2)
.pipe(
toArray(),
map(arr=>arr.sort((a,b) => b-a)),
switchMap( (rez) => from(rez)
.pipe(filter((el: any) => CONST2%el === 0))
)
);
const stream3 = stream1.pipe(
switchMap((el1) => stream2.pipe(filter((el2) => el2 === el1))),
toArray()
).subscribe((el) => {
console.log(Math.max(...el));
})