Первоначальная цель, и она остается наиболее распространенным вариантом использования Webpack, - это сборка интерфейсного javascript. Это включает в себя объединение фрагмента кода javascript и всех его зависимостей в один файл javascript, который может служить статическим javascript и ссылаться на него со страницы HTML.

Если вы не знакомы с объединением интерфейсов javascript, следующий раздел служит введением в ускоренный курс, в противном случае сразу переходите к следующему разделу «Объединение интерфейсов и серверных компонентов Javascript Webpack».

Эта статья посвящена использованию Webpack не только для связывания вашего интерфейсного javascript, но и для внутреннего javascript, в случае, если вы используете серверную часть на основе javascript, такую ​​как nodejs.

Одна из веских причин для использования Webpack для серверной части nodejs заключается в том, что вы уже используете Webpack для своего интерфейса и хотите оптимизировать свои инструменты сборки.

Мотив написания этой статьи двоякий:

  • Объясните различия в использовании Webpack для бэк-энда и для бандлинга javascript во внешнем интерфейсе.
  • Предоставьте пошаговую инструкцию по связыванию javascript как для серверной, так и для интерфейсной части.

Ускоренный курс по сборке Javascript-интерфейса Webpack

Это введение основано на примере с официального сайта Webpack.

  1. Вы пишете функцию и т. Д. Внутри модуля, упакованного в файл (bar.js)
// bar.js
export default function bar() {
  // Code for bar function
  ...
}

2. Вы импортируете модуль и используете его с другими библиотеками, например, React (интерфейсный фреймворк) в своем внешнем javascript-коде (front.js).

// front.js
import bar from '/.bar';
import React from 'react';
export default class MyButton extends React.Component {
  // Code that use bar function and React library
  ...
}

3. Вы используете webpack для создания пакета, то есть одного javascript («bundle-front.js»), содержащего все зависимости (модуль панели, библиотека React и т. Д.) С «front.js» в качестве отправной точки.

// webpack.config.js
module.exports = {
  entry = './front.js',
  output: {
    filename: 'bundle-front.js'
  }
}

4. Запустите код javascript в файле "bundle-front.js" на своей веб-странице.

// index.html
<!doctype html>
<html>
  <head>
    ...
  </head>
  <body>
    ...
    <script src="bundle-front.js"></script>
  </body>
</html>

Фронтенд и бэкэнд объединение Javascript

Объединение внешнего интерфейса javascript используется в любом проекте независимо от его внутреннего стека, который может быть ruby, python и т. Д. Выходные данные пакета внешнего интерфейса javascript просто подаются из внутреннего стека как статический файл javascript.

Путаница начинается, когда внутренний стек также основан на javascript, например, nodejs. Затем вы пытаетесь связать javascript для внешнего, внутреннего или обоих интерфейсов при использовании Webpack?

У вас есть 2 варианта:

  1. Используйте Webpack для связывания внешнего кода javascript, как описано, и Gulp или Grunt для создания внутреннего кода javascript. Недостаток в том, что при управлении обеими системами сборки требуется много усилий и избыточность настройки.
  2. Используйте Webpack для объединения как внешнего, так и внутреннего кода javascript. Большинство людей не знают, что вам нужно объединить внешний и внутренний javascript-код «отдельно», создав 2 выходных пакета.

Предположим, что вы хотите использовать Webpack в случае №2, и есть 2 способа сделать это:

A. Отдельные файлы конфигурации Webpack для интерфейса и серверной части

Б. Единый файл конфигурации Webpack как для интерфейса, так и для серверной части

А. Отдельные файлы конфигурации для интерфейса и серверной части

Самый простой способ - создать 2 конфигурации Webpack.

  • webpack-back.config.js
  • webpack-front.config.js

Вы запускаете команду Webpack дважды, каждый раз используя другой файл конфигурации для создания двух выходных пакетов, например, bundle-front.js и bundle-back.js.

// Generate bundle-front.js
webpack --config ./webpack-front.config.js
// Generate bundle-back.js
webpack --config ./webpack-back.config.js

Вы запускаете свой внутренний сервер с помощью "bundle-back.js", используя:

node bundle-back.js

И на своей главной html-странице вы запускаете "bundle-front.js" следующим образом:

// index.html
<!doctype html>
<html>
  <head>
    ...
  </head>
  <body>
    ...
    <script src="bundle-front.js"></script>
  </body>
</html>

Отличия в конфигурациях Webpack заключаются в следующих параметрах:

  • цель
  • Вход
  • выход
  • внешние
  • devServer
  • инструмент разработчика

webpack-back.config.js

const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
  target: "node",
  entry: {
    app: ["./back.js"]
  },
  output: {
    path: path.resolve(__dirname, "../build"),
    filename: "bundle-back.js"
  },
  externals: [nodeExternals()],
};

webpack-front.config.js

const path = require('path');
module.exports = {
  target: "web",
  entry: {
    app: ["./front.js"]
  },
  output: {
    path: path.resolve(__dirname, "../build"),
    filename: "bundle-front.js",
  },
  devServer: {
    host: '0.0.0.0', // Required for docker
    publicPath: '/assets/',
    contentBase: path.resolve(__dirname, "./views"),
    watchContentBase: true,
    compress: true,
    port: 9001
  },
  devtool: 'inline-source-map',
}

'цель':

  • Для серверной части это «узел», для интерфейса - «веб».

'Вход':

  • Точки входа (исходные файлы) для внутреннего и внешнего javascript указывают на разные исходные файлы javascript, то есть «back.js» и «front.js» соответственно.

'выход':

  • Сгенерированный файл пакета javascript для внутреннего и внешнего интерфейса - это разные файлы, то есть «bundle-back.js» и «bundle-front.js» соответственно.

«Внешние»:

  • «Webpack-back.config.js» импортирует метод nodeExternals из библиотеки «webpack-node-externals».
  • Этот метод возвращает список библиотек зависимостей в каталоге «./node_modules» и помещает список во «внешние», чтобы исключить их из объединения.
  • Для серверной части все библиотеки зависимостей устанавливаются в ‘./node_modules’ с помощью yarn install или npm install во время сборки, поэтому нет необходимости включать их в пакет серверной части.
  • С другой стороны, интерфейс требует, чтобы все зависимости были объединены, потому что связанный javascript должен быть автономным модулем, поскольку он будет загружаться и запускаться в браузере пользователя.

‘DevServer’

  • Только для фронтальной сборки. Это настраивает webpack-dev-server, что избавляет от необходимости настраивать веб-сервер для обслуживания клиентского пакета в качестве статического файла javascript во время разработки. Более того, он может автоматически повторно связывать интерфейсный пакет, если обнаруживает изменения в исходном коде, для повышения производительности; вам не нужно перезапускать сервер и перезагружать браузер.

‘Devtool’

  • Указывает детали в исходной карте, которая используется браузером для привязки выполнения пакета интерфейсного javascript к исходному исходному коду внешнего интерфейса javascript, что полезно для отладки.
  • Только для внешнего интерфейса, так как на внутреннем javascript есть собственные инструменты отладки.

Б. Унифицированные файлы конфигурации для интерфейсной и серверной частей

Можно объединить webpack-back.config.js и webpack-front.config.js в один файл webpack.config.j. , для чего требуется 3 шага:

  1. Объедините все операторы require и поместите их вверху
  2. Поместите файлы «webpack-front.config.js» и «webpack-back.config.js» в два отдельных файла const.
  3. Объедините «module.exports» и поместите их внизу, чтобы экспортировать consts, содержащие конфигурации веб-пакетов.
// Combined 'require' statements
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const webpack = require('webpack');
const frontConfig = {
  // Stuff the entire webpack-front.config.js
  // without the require and module.exports lines
  ...
}
const backConfig = {
  // Stuff the entire webpack-back.config.js
  // without the require and module.exports lines
  ...
}
// Combined 'module.exports'
module.exports = [ frontConfig, backConfig ];

Это позволяет нам создавать пакеты серверной части и интерфейса пользователя с помощью одной команды Webpack.

// Generate both bundle-front.js and bundle-back.js 
webpack --config webpack.config.js

Однако я столкнулся с проблемами, когда webpack-dev-server не может запускаться должным образом в зависимости от порядка clientConfig и serverConfig.

Подробнее см. Понятие страница Webpack цели. В react-starter-kit также используется один файл webpack.config.js. Однако ни в одном из примеров не настроен devServer.

Сообщения об общих ошибках

Наиболее явным признаком того, что вы неправильно связываете интерфейсный и серверный пакеты, является появление сообщений, похожих на:

Can't resolve 'fs' webpack

Вы пытаетесь использовать модуль на основе узла во внешнем пакете.

Самый простой способ решить эту проблему - указать «цель» в конфигурации Webpack для вашего внешнего интерфейса «webpack-front.config.js», как указано выше.

// webpack-front.config.js
module.exports = {
  target: "web",
  ...
}

Если проблема не исчезнет, ​​добавьте в конфигурацию Webpack следующее:

// webpack-front.config.js
module.exports = {
  node: {
    fs: 'empty'
  },
  ...
}