TypeScript — это язык с открытым исходным кодом, разработанный и поддерживаемый Microsoft. Впервые выпущенный в октябре 2012 года, его разработкой руководил Андерс Херлсберг, который также сыграл большую роль в создании языка C#. TypeScript — это типизированный надмножество JavaScript, который компилируется в обычный JavaScript.

Вам может быть интересно… почему TypeScript? Что ж, JavaScript — это динамический язык без системы типов и не поддерживает некоторые объектно-ориентированные функции таких языков, как C# и Java, которые упрощают создание сложных приложений большими группами, работающими над одним и тем же кодом. Система типов повышает качество кода, удобочитаемость и упрощает поддержку и рефакторинг кодовой базы. Что еще более важно, ошибки могут быть обнаружены во время компиляции, а не во время выполнения.

Итак… что такое webpack? По своей сути webpack — это сборщик статических модулей для современных приложений JavaScript. Когда webpack обрабатывает ваше приложение, он строит граф зависимостей, который сопоставляет все модули, необходимые вашему проекту, и генерирует один или несколько пакетов. Говоря простым языком, это инструмент, который решит все проблемы ECMAScript 2015+. модульных зависимостей, транспилировать исходный код с помощью Babel, объединить все файлы JavaScript в один, а также сделать код совместимым с браузером или Node.js.

В этой хорошо продуманной статье я покажу вам, как настроить проект TypeScript с нуля с помощью webpack. На сегодняшний день TypeScript 4.0 является последней версией, которую мы будем использовать. В конце этой статьи у вас должна быть следующая структура проекта

Настройка проекта

Перейдите в любое место, где вам удобно создавать проекты на своем компьютере, и создайте папку проекта с помощью команды mkdir. Например, mkdir typescript-webpack. В только что созданной папке проекта запустите npm init -y, чтобы добавить файл package.json со значениями по умолчанию. Если вы хотите инициализировать git, чтобы сохранить репозиторий на GitHub или аналогичном ресурсе, запустите git init в той же папке проекта.

Добавьте webpack, webpack-cli, typescript и ts-loader в качестве зависимостей dev с помощью команды npm i webpack webpack-cli typescript ts-loader -D

Далее мы продолжим и настроим typescript для проекта, используя файл tsconfig.json. Файл tsconfig.json — это простой файл в формате JSON, в котором мы можем указать различные параметры, чтобы сообщить компилятору, как компилировать текущий. Идите вперед и создайте новый файл в корневом каталоге, назовите его tsconfig.json и добавьте следующую конфигурацию.

{
   "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "sourceMap": true,
    "module": "ESNext",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "target": "es5",
    "typeRoots": [
    "node_modules/@types",
    "typings"
   ]
 },
    "include": [
    "src/**/*.ts"
  ]
}

Вебпак

Давайте продолжим и добавим базовую конфигурацию веб-пакета. Добавьте файл webpack.config.js в корневой каталог и добавьте следующую конфигурацию.

const path = require('path');

module.exports = {
  mode: "production",
  entry: path.resolve(__dirname, './src/index.ts'),
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

Несколько замечаний:

  • По умолчанию режим веб-пакета — производственный, в котором ваш код будет минимизирован.
  • Точка входа указывает, какой модуль webpack должен использовать, чтобы начать построение своего внутреннего графа зависимостей. webpack выяснит, от каких других модулей и библиотек зависит эта точка входа (напрямую или косвенно).
  • Свойство output сообщает веб-пакету, куда создавать связки, которые он создает, и как называть эти файлы. По умолчанию это ./dist/main.js для основного выходного файла и папка ./dist для любого другого сгенерированного файла.
  • По умолчанию webpack понимает только файлы JavaScript и JSON. Загрузчики позволяют веб-пакету обрабатывать другие типы файлов и преобразовывать их в действительные модули, которые могут использоваться вашим приложением и добавляться в граф зависимостей.

Измените скрипт в файле package.json, чтобы мы могли запускать webpack.

"scripts": {
    "build": "webpack"
  },

Добавьте код в файл index.ts внутри папки src.

window.addEventListener("load", () => {
  const header = document.createElement("h1");
  header.innerText = "Webpack❤️TS"

  const body = document.querySelector("body");
  body.appendChild(header);
})

Соберите проект с npm run build и УВЫ! Мы сделали это, эй🚀

Пока не совсем…

Здорово, что у нас есть файл bundle.js в нашей папке dist, верно?! Потому что теперь мы можем легко ссылаться на него в нашем HTML-файле, но большая новость заключается в том, что у webpack есть лучший способ сделать это :)

HTML-шаблоны

Прежде всего, нам нужно добавить некоторые зависимости разработки. Перейдите к своему терминалу и запустите npm i -D html-webpack-plugin clean-webpack-plugin Продолжайте, а также создайте папку шаблона в папке src, куда мы добавим шаблон HTML.

src/templates/index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Webpack❤️TS</title>
</head>
<body>

</body>
</html>

Плагины

Внутри файла webpack.config.js мы будем использовать два плагина, которые мы добавили в качестве зависимостей dev, т.е.

  • html-webpack-plugin — этот плагин упрощает создание HTML-файлов для обслуживания пакетов webpack. Это особенно полезно для пакетов веб-пакетов, которые включают хеш в имени файла, который изменяется при каждой компиляции.
  • clean-webpack-plugin — в целом рекомендуется очищать папку /dist перед каждой сборкой, чтобы генерировались только используемые файлы. Этот плагин позаботится об этом.

В файле webpack.config.js добавьте следующие изменения.

const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
...
module.exports = {
  ...
  output: {
    filename: 'bundle.[hash].js', // <- ensures unique bundle name
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname,"./src/templates/index.html")
    })
  ]
};

Обратите внимание, что имя выходного файла теперь включает [hash]. Это обеспечит уникальное имя при каждой компиляции.

Повторная сборка путем запуска npm run build в терминале создаст новый пакет с хэшем, а также файл HTML в папке dist.

/dist/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>TypeScript❤️Webpack</title>
</head>
<body>
  <script src="bundle.fef64ef9b6c46a5020b1.js"></script>
</body>
</html>

То, чего мы достигли на данный момент, действительно круто, но мы можем сделать еще лучше. А не ___ ли нам?

Сервер разработки Webpack

webpack-dev-server можно использовать для быстрой разработки приложения. Он имеет много полезных функций, таких как перезагрузка в реальном времени или горячая замена модуля, когда вы что-то меняете в своем коде, и может использоваться для обслуживания статических ресурсов, таких как изображения :)

В этом разделе мы рассмотрим некоторые из лучших практик и утилит для создания рабочего сайта или приложения. Цели сборок для разработки и рабочих сильно различаются, поэтому рекомендуется создавать отдельные конфигурации веб-пакетов для каждой среды.

Хотя мы разделим специфические части производства и разработки, обратите внимание, что мы по-прежнему будем поддерживать «общую» конфигурацию, чтобы все было СУХИМ. Чтобы объединить эти конфигурации вместе, мы будем использовать утилиту под названием webpack-merge.

npm install -D webpack-merge webpack-dev-server

создайте 3 файла webpack в корневом каталоге, как показано на рисунке ниже, т.е. webpack.common.js, webpack.dev.js, and webpack.prod.js

/webpack.common.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const distPath = path.resolve(__dirname, "dist");
module.exports = {
    entry: path.resolve(__dirname, "./src/index.ts"),
    module: {
    rules: [
     {
        test: /\.tsx?$/,
        use: "ts-loader",
        exclude: /node_modules/
     }
    ]
   },
   resolve: {
   extensions: [".tsx", ".ts", ".js"]
   },
   output: {
     filename: "bundle.[hash].js",
     path: distPath
    },
   plugins: [
     new CleanWebpackPlugin(),
     new HtmlWebpackPlugin({
     template: path.resolve(__dirname, "./src/templates/index.html")
    })
   ]
  };

/webpack.dev.js

создайте папку ресурсов в корневой папке, куда мы добавим статические ресурсы, такие как изображения.

const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const path = require("path");
module.exports = merge(common, {
   devtool: "inline-source-map",
   mode: "development",
   devServer: {
     contentBase: path.join(__dirname, "assets"),
     publicPath: "/",
     compress: true,
     port: 9000
   }
});

В производственной конфигурации нам потребуются дополнительные плагины, чтобы сделать некоторые изящные вещи под капотом, а именно:

  • webpack-bundle-analyzer: помогает нам визуализировать размер выходных файлов webpack с помощью интерактивной масштабируемой древовидной карты.
  • terser-webpack-plugin: этот плагин использует terser для минимизации вашего JavaScript.

npm i -D terser-webpack-plugin webpack-bundle-analyzer

/webpack.prod.js

const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const TerserPlugin = require("terser-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = merge(common, {
optimization: {
   minimize: true,
   minimizer: [
       new TerserPlugin({
         terserOptions: {
           ecma: undefined,
           warnings: false,
           parse: {},
           compress: {},
           mangle: true,
           module: false,
           output: null,
           toplevel: false,
           nameCache: null,
           ie8: false,
           keep_classnames: undefined,
           keep_fnames: false,
           safari10: false
        }
      })
    ]
   },
   plugins: [new BundleAnalyzerPlugin()],
   devtool: "none",
   mode: "production"
  });

Мы также должны обновить скрипт npm, чтобы убедиться, что используется правильный файл конфигурации.

"scripts": {
    "start": "webpack-dev-server --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },

Запуск npm start сделает проект доступным на http://localhost:9000.

Добавление стилей с помощью веб-пакета

Нам понадобится всего два плагина webpack, чтобы удобно добавлять стили в наш проект.

npm i css-loader mini-css-extract-plugin -D

Добавим их к webpack.common.js:

// webpack.common.js
...
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  ...
  module: {
    rules: [
      ...
      {
        test: /\.css$/i,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader'
        ],
      },
    ],
  },
  plugins: [
    ...
    new MiniCssExtractPlugin({filename: "styles.[hash].css"})
  ]
};

Создайте файл styles.css в папке src и добавьте несколько основных стилей.

/src/styles.css

body {
    margin: 0;
    border: 1px solid red;
  }

импортируйте его в файл index.ts

/src/index.ts

import "./styles.css";
...

Стили будут добавлены в html-файл. Запустите npm start для сборки для разработки и npm run build для рабочей сборки.

Код можно найти в моем репозитории github.