Влияние HtmlWebpackPlugin на сервер разработки webpack

Я использую webpack в проекте реагирования, и кажется, что HtmlWebpackPlugin влияет на сервер разработки webpack странным образом, которого я не понимаю. Кажется, это позволяет мне перейти к index.html независимо от того, где этот файл находится в базе кода, что невозможно, используя только сервер разработки.

Допустим, у меня есть следующая структура каталогов:

myproj/
  |- package.json
  |- webpack.config.js
  |- src/
    |- index.html
    |- index.jsx

и файл webpack.config.js, который выглядит так:

const path = require('path');

module.exports = {
    entry: './src/index.jsx',

    devServer: {
        contentBase: __dirname
    }
};

Затем я запускаю webpack-dev-server --mode=development. Поскольку devServer.contentBase установлен в текущий каталог (myproj), а файл index.html находится внутри myproj/src, я должен перейти к http://localhost:8080/src/index.html, чтобы увидеть свое веб-приложение. Если я попытаюсь просмотреть http://localhost:8080/index.html, то получу 404. Мне это понятно.

Затем я добавляю HtmlWebpackPlugin, больше ничего не меняя внутри webpack.config.js:

const HtmlWebpackPlugin = require('html-webpack-plugin');
....
plugins: [
    new HtmlWebpackPlugin({
        template: './src/index.html'
    })
]

Теперь я могу без проблем перейти на http://localhost:8080/index.html. На самом деле я могу попасть либо в http://localhost:8080/index.html, либо в http://localhost:8080/src/index.html.

Что случилось с этим? Что сделал HtmlWebpackPlugin, чтобы это стало возможным?


person d512    schedule 23.04.2018    source источник
comment
он создает для вас html-файл по адресу root. Вероятно, у вас есть еще один index.html внутри src, который загружается во втором случае.   -  person Prajwal    schedule 23.04.2018
comment
@Prajwal спасибо за информацию. Итак, я думаю, как и файл bundle.js, этот файл index.html существует только в памяти? Я нигде не вижу записи на диск.   -  person d512    schedule 24.04.2018


Ответы (3)


Ладно, думаю, я понял это.

TL;DR

Как только вы добавите HtmlWebpackPlugin, вы должны удалить эту строку из index.html:

<script type="text/javascript" src="main.bundle.js"></script>

и перейдите только к http://localhost:8080/index.html.

Утомительные подробности:

Как только вы добавите HtmlWebpackPlugin, он берет ваш файл index.html и объединяется с тегом <script>, который указывает на ваш пакет webpack. Он обслуживает этот объединенный HTML-файл из http://localhost:8080. Это происходит, даже если index.html уже содержит ссылку на пакет.

Плагин на самом деле не перезаписывает index.html объединенной версией. Таким образом, просмотр http://localhost:8080/src/index.html просто показывает вам этот файл в том виде, в котором он находится на диске.

Итак, если ваш файл src/index.html выглядит так до добавления HtmlWebpackPlugin:

<body>
    <div id="app">it worked</div>
    <script type="text/javascript" src="main.bundle.js"></script>
</body>

затем после добавления HtmlWebpackPlugin при переходе к http://localhost:8080 вы получите эту объединенную версию:

<body>
    <div id="app">it worked</div>
    <script type="text/javascript" src="main.bundle.js"></script>
    <script type="text/javascript" src="main.bundle.js"></script>
</body>

Итак, теперь у вас будет две ссылки на пакет: тот, который вы добавили в файл, и тот, который был добавлен HtmlWebpackPlugin.

Просмотр до http://localhost:8080/src дает вам то, что находится на диске в src/index.html:

<body>
    <div id="app">it worked</div>
    <script type="text/javascript" src="main.bundle.js"></script>
</body>

Однако, поскольку весь смысл использования HtmlWebpackPlugin заключается в том, чтобы позволить ему вставить ссылку на пакет для вас, это означает, что вы должны удалить этот тег <script> из src/index.html. Это, в свою очередь, означает, что просмотр src/index.html больше не будет работать, потому что у вас больше нет ссылки на ваш пакет!

Теперь вы зависите от того, позволите ли HtmlWepbackPlugin вставить тег <script> за вас, а это значит, что теперь вы должны перейти к http://localhost:8080/index.html, чтобы получить сгенерированную версию.

Вебпак. Быть. Псих.

person d512    schedule 25.04.2018

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

Из документов Webpack-dev-server,

Этот модифицированный пакет обслуживается из памяти по относительному пути, указанному в publicPath (см. API). Он не будет записан в настроенный вами выходной каталог. Если пакет уже существует по тому же пути URL, пакет в памяти имеет приоритет (по умолчанию).

person Prajwal    schedule 24.04.2018

у вас есть доступ как к http://localhost:8080/index.html, так и к http://localhost:8080/src/index.html. Но подают по-разному.

Для http://localhost:8080/src/index.html он обслуживается веб-пакетом -dev-server точно так же, как когда HtmlWebpackPlugin не включен. Если вы проверите содержимое ответа этого URL-адреса, вы обнаружите, что оно идентично содержимому src/index.html на вашем диске.

Для http://localhost:8080/index.html он обслуживается HtmlWebpackPlugin из памяти. Если вы проверите содержимое ответа этого URL-адреса, вы обнаружите, что все файлы вашего пакета добавлены в HTML (вот почему мы его используем). Что касается имени файла, вы можете настроить его на что угодно с помощью поля «имя файла» (вы также можете указать подкаталог). проверьте https://github.com/jantimon/html-webpack-plugin#options подробнее.

person loveky    schedule 24.04.2018