Spec-Zone.ru › TypeScript 5.1

Gulp

Это краткое руководство научит вас, как создать TypeScript с помощью gulp, а затем добавить Browserify, terser или Watchify в конвейер gulp. Это руководство также демонстрирует, как добавить функциональность Babel с помощью Babelify.

Мы предполагаем, что вы уже используете Node.js с npm.

Минимальный проект

Давайте начнём с новой директории. Мы назовём её proj пока, но вы можете изменить её на что угодно.

mkdir proj
cd proj

Для начала, мы будем структурировать наш проект следующим образом:

proj/
   ├─ src/
   └─ dist/

Файлы TypeScript будут находиться в вашей папке src, обрабатываться компилятором TypeScript и оказываться в папке dist.

Давайте создадим эту структуру:

mkdir src
mkdir dist

Инициализация проекта

Теперь мы превратим эту папку в пакет npm.

npm init

Вам будет предложено несколько вопросов. Вы можете использовать значения по умолчанию, за исключением точки входа. В качестве точки входа используйте ./dist/main.js. Вы всегда можете вернуться и изменить эти значения в файле package.json , который был создан для вас.

Установка зависимостей

Теперь мы можем использовать npm install для установки пакетов. Сначала установите gulp-cli глобально (если вы используете Unix-систему, вам может потребоваться добавить префикс npm install ко всем командам в этом руководстве с помощью sudo).

npm install -g gulp-cli

Затем установите typescript, gulp и gulp-typescript в зависимости разработки вашего проекта. Gulp-typescript — это плагин gulp для TypeScript.

npm install --save-dev typescript gulp@4.0.0 gulp-typescript

Написание простого примера

Давайте напишем программу «Hello, world!». В src, создайте файл main.ts:

function hello(compiler: string) {
  console.log(`Hello from ${compiler}`);
}
hello("TypeScript");

В корне проекта, proj, создайте файл tsconfig.json:

{
  "files": ["src/main.ts"],
  "compilerOptions": {
    "noImplicitAny": true,
    "target": "es5"
  }
}

Создание файла gulpfile.js

В корне проекта создайте файл gulpfile.js:

var gulp = require("gulp");
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");

gulp.task("default", function () {
  return tsProject.src().pipe(tsProject()).js.pipe(gulp.dest("dist"));
});

Тестирование результата приложения

gulp
node dist/main.js

Программа должна вывести «Привет из TypeScript!».

Добавление модулей в код

Прежде чем перейти к Browserify, давайте расширим наш код и добавим модули. Это структура, которую вы скорее всего будете использовать для реального приложения.

Создайте файл с именем src/greet.ts:

export function sayHello(name: string) {
  return `Hello from ${name}`;
}

Теперь измените код в src/main.ts для импорта sayHello из greet.ts:

import { sayHello } from "./greet";

console.log(sayHello("TypeScript"));

Наконец, добавьте src/greet.ts в tsconfig.json:

{
  "files": ["src/main.ts", "src/greet.ts"],
  "compilerOptions": {
    "noImplicitAny": true,
    "target": "es5"
  }
}

Убедитесь, что модули работают, запустив gulp и затем проверив в Node:

gulp
node dist/main.js

Обратите внимание, что даже если мы использовали синтаксис модулей ES2015, TypeScript сгенерировал модули CommonJS, используемые Node.js. В этом руководстве мы будем придерживаться CommonJS, но вы можете установить module в объекте опций, чтобы изменить это.

Browserify

Теперь давайте переведём этот проект из Node.js в браузер. Для этого мы хотим объединить все наши модули в один JavaScript-файл. К счастью, именно это делает Browserify. Более того, он позволяет использовать систему модулей CommonJS, используемую Node.js, которая является стандартной для TypeScript. Это означает, что наша настройка для TypeScript и Node.js практически без изменений перенесётся в браузер.

Сначала установите browserify, tsify и vinyl-source-stream. tsify — это плагин Browserify, который, как и gulp-typescript, предоставляет доступ к компилятору TypeScript. vinyl-source-stream позволяет адаптировать вывод файлов Browserify обратно в формат, который понимает gulp, называемый vinyl.

npm install --save-dev browserify tsify vinyl-source-stream

Создание страницы

Создайте файл в src с именем index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>
  </head>
  <body>
    <p id="greeting">Loading ...</p>
    <script src="bundle.js"></script>
  </body>
</html>

Теперь измените main.ts для обновления страницы:

import { sayHello } from "./greet";

function showHello(divName: string, name: string) {
  const elt = document.getElementById(divName);
  elt.innerText = sayHello(name);
}

showHello("greeting", "TypeScript");

Вызов showHello вызывает sayHello для изменения текста абзаца. Теперь измените ваш gulpfile следующим образом:

var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var tsify = require("tsify");
var paths = {
  pages: ["src/*.html"],
};

gulp.task("copy-html", function () {
  return gulp.src(paths.pages).pipe(gulp.dest("dist"));
});

gulp.task(
  "default",
  gulp.series(gulp.parallel("copy-html"), function () {
    return browserify({
      basedir: ".",
      debug: true,
      entries: ["src/main.ts"],
      cache: {},
      packageCache: {},
    })
      .plugin(tsify)
      .bundle()
      .pipe(source("bundle.js"))
      .pipe(gulp.dest("dist"));
  })
);

Это добавляет задачу copy-html и добавляет её в качестве зависимости default. Это означает, что каждый раз при запуске default, copy-html должна выполняться первой. Мы также изменили default на вызов Browserify с плагином tsify вместо gulp-typescript. Удобно, что оба позволяют передать тот же объект опций в компилятор TypeScript.

После вызова bundle мы используем source (наш псевдоним для vinyl-source-stream) для именования нашего выходного пакета bundle.js.

Проверьте страницу, запустив gulp и затем открыв dist/index.html в браузере. Вы должны увидеть «Hello from TypeScript» на странице.

Обратите внимание, что мы указали debug: true для Browserify. Это заставляет tsify генерировать карты исходных файлов внутри скомпонованного JavaScript-файла. Карты исходных файлов позволяют отлаживать ваш исходный код TypeScript в браузере вместо скомпонованного JavaScript. Вы можете проверить, что карты исходных файлов работают, открыв отладчик браузера и установив точку останова внутри main.ts. При обновлении страницы точка останова должна приостановить страницу и позволит вам отладить greet.ts.

Watchify, Babel и Terser

Теперь, когда мы объединяем наш код с помощью Browserify и tsify, мы можем добавить различные функции в нашу сборку с помощью плагинов browserify.

  • Watchify запускает gulp и поддерживает его работу, поэтапно компилируя каждый раз, когда вы сохраняете файл. Это позволяет вам поддерживать цикл изменения-сохранение-обновление в браузере.

  • Babel — это чрезвычайно гибкий компилятор, преобразующий ES2015 и более поздние версии в ES5 и ES3. Это позволяет вам добавлять обширные и настраиваемые преобразования, которые TypeScript не поддерживает.

  • Terser сжимает ваш код, чтобы сократить время загрузки.

Watchify

Мы начнём с Watchify для обеспечения фоновой компиляции:

npm install --save-dev watchify fancy-log

Теперь измените свой gulpfile следующим образом:

var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var watchify = require("watchify");
var tsify = require("tsify");
var fancy_log = require("fancy-log");
var paths = {
  pages: ["src/*.html"],
};

var watchedBrowserify = watchify(
  browserify({
    basedir: ".",
    debug: true,
    entries: ["src/main.ts"],
    cache: {},
    packageCache: {},
  }).plugin(tsify)
);

gulp.task("copy-html", function () {
  return gulp.src(paths.pages).pipe(gulp.dest("dist"));
});

function bundle() {
  return watchedBrowserify
    .bundle()
    .on("error", fancy_log)
    .pipe(source("bundle.js"))
    .pipe(gulp.dest("dist"));
}

gulp.task("default", gulp.series(gulp.parallel("copy-html"), bundle));
watchedBrowserify.on("update", bundle);
watchedBrowserify.on("log", fancy_log);

Здесь в основном три изменения, но они требуют небольшой переработки кода.

  1. Мы обернули наш экземпляр browserify в вызов watchify, а затем сохранили результат.
  2. Мы вызвали watchedBrowserify.on('update', bundle); так, чтобы Browserify запускал функцию bundle каждый раз, когда вы изменяете один из ваших TypeScript-файлов.
  3. Мы вызвали watchedBrowserify.on('log', fancy_log); для записи в консоль.

Вместе (1) и (2) означают, что нам нужно перенести наш вызов browserify из задачи default. И нам нужно дать имени функции для default имя, так как как Watchify, так и Gulp должны её вызвать. Добавление регистрации с помощью (3) необязательно, но очень полезно для отладки вашей настройки.

Теперь, когда вы запустите Gulp, он должен начать работу и оставаться запущенным. Попробуйте изменить код для showHello в main.ts и сохранить его. Вы должны увидеть вывод, подобный этому:

proj$ gulp
[10:34:20] Using gulpfile ~/src/proj/gulpfile.js
[10:34:20] Starting 'copy-html'...
[10:34:20] Finished 'copy-html' after 26 ms
[10:34:20] Starting 'default'...
[10:34:21] 2824 bytes written (0.13 seconds)
[10:34:21] Finished 'default' after 1.36 s
[10:35:22] 2261 bytes written (0.02 seconds)
[10:35:24] 2808 bytes written (0.05 seconds)

Terser

Сначала установите Terser. Поскольку цель Terser — исказить ваш код, нам также необходимо установить vinyl-buffer и gulp-sourcemaps, чтобы карты исходных файлов продолжали работать.

npm install --save-dev gulp-terser vinyl-buffer gulp-sourcemaps

Теперь измените свой gulpfile следующим образом:

var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var terser = require("gulp-terser");
var tsify = require("tsify");
var sourcemaps = require("gulp-sourcemaps");
var buffer = require("vinyl-buffer");
var paths = {
  pages: ["src/*.html"],
};

gulp.task("copy-html", function () {
  return gulp.src(paths.pages).pipe(gulp.dest("dist"));
});

gulp.task(
  "default",
  gulp.series(gulp.parallel("copy-html"), function () {
    return browserify({
      basedir: ".",
      debug: true,
      entries: ["src/main.ts"],
      cache: {},
      packageCache: {},
    })
      .plugin(tsify)
      .bundle()
      .pipe(source("bundle.js"))
      .pipe(buffer())
      .pipe(sourcemaps.init({ loadMaps: true }))
      .pipe(terser())
      .pipe(sourcemaps.write("./"))
      .pipe(gulp.dest("dist"));
  })
);

Обратите внимание, что terser имеет только один вызов — вызовы buffer и sourcemaps необходимы для того, чтобы карты исходных файлов продолжали работать. Эти вызовы дают нам отдельный файл карты исходных файлов вместо использования встроенных карт исходных файлов, как раньше. Теперь вы можете запустить Gulp и проверить, что bundle.js действительно сжат до нечитаемого набора символов:

gulp
cat dist/bundle.js

Babel

Сначала установите Babelify и набор Babel для ES2015. Подобно Terser, Babelify искажает код, поэтому нам понадобятся vinyl-buffer и gulp-sourcemaps. По умолчанию Babelify будет обрабатывать только файлы с расширениями .js, .es, .es6 и .jsx, поэтому нам нужно добавить расширение .ts в качестве опции для Babelify.

npm install --save-dev babelify@8 babel-core babel-preset-es2015 vinyl-buffer gulp-sourcemaps

Теперь измените свой gulpfile следующим образом:

var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var tsify = require("tsify");
var sourcemaps = require("gulp-sourcemaps");
var buffer = require("vinyl-buffer");
var paths = {
  pages: ["src/*.html"],
};

gulp.task("copy-html", function () {
  return gulp.src(paths.pages).pipe(gulp.dest("dist"));
});

gulp.task(
  "default",
  gulp.series(gulp.parallel("copy-html"), function () {
    return browserify({
      basedir: ".",
      debug: true,
      entries: ["src/main.ts"],
      cache: {},
      packageCache: {},
    })
      .plugin(tsify)
      .transform("babelify", {
        presets: ["es2015"],
        extensions: [".ts"],
      })
      .bundle()
      .pipe(source("bundle.js"))
      .pipe(buffer())
      .pipe(sourcemaps.init({ loadMaps: true }))
      .pipe(sourcemaps.write("./"))
      .pipe(gulp.dest("dist"));
  })
);

Нам также нужно настроить TypeScript на целевую версию ES2015. Babel затем сгенерирует ES5 из кода ES2015, сгенерированного TypeScript. Давайте изменим tsconfig.json:

{
  "files": ["src/main.ts"],
  "compilerOptions": {
    "noImplicitAny": true,
    "target": "es2015"
  }
}

Вывод Babel в ES5 должен быть очень похож на вывод TypeScript для такого простого скрипта.

© 2012-2023 Microsoft
Licensed under the Apache License, Version 2.0.
https://www.typescriptlang.org/docs/handbook/gulp.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API