Представьте проблемы
предыдущий раздел3-9 Генерация HTML для одностраничных приложенийВ приложении генерируется только один файл HTML, но в практических приложениях полная система не будет реализовывать все функции на одной веб-странице, потому что это приведет к снижению производительности веб-страницы. Реальная практика состоит в том, чтобы разделить его на несколько одностраничных приложений в соответствии с функциональными модулями, и каждое одностраничное приложение создает файл HTML. И по мере развития бизнеса в проект могут постепенно добавляться больше одностраничных приложений.
Хотя одна вещь была решена автоматизация, генерирует болевые точки HTML, но удалось вручную генерировать несколько одностраничных приложений, также является неприятным. Чтобы продолжать преобразовать пример в предыдущем разделе, следующее:
- В настоящее время проект состоит из 2-х одностраничных приложений, одно из которых является домашней страницей.
index.html
, одна из них — страница входа пользователяlogin.html
; - Между несколькими одностраничными приложениями будут общие части кода. Эти общие части необходимо извлечь и поместить в отдельные файлы, чтобы предотвратить повторную загрузку. Например, несколько страниц используют набор стилей CSS и используют фреймворк React, и эти общие части необходимо извлечь в отдельные файлы;
- По мере развития бизнеса новые одностраничные приложения могут добавляться постоянно, но каждый раз, когда добавляется новое одностраничное приложение, код, связанный со строительством, не может быть изменен.
Прежде чем мы начнем, давайте взглянем на код окончательной версии приложения в Интернете.
login.html
содержание документа:
<html>
<head>
<meta charset="UTF-8">
<!--从多个页面中抽离出的公共 CSS 代码-->
<link rel="stylesheet" href="common_7cc98ad0.css">
<!--只有这个页面需要的 CSS 代码-->
<link rel="stylesheet" href="login_e31e214b.css">
<!--注入 google_analytics 中的 JS 代码-->
<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');</script>
<!--异步加载 Disqus 评论-->
<script async="" src="https://dive-into-webpack.disqus.com/embed.js"></script>
</head>
<body>
<div id="app"></div>
<!--从多个页面中抽离出的公共 JavaScript 代码-->
<script src="common_a1d9142f.js"></script>
<!--只有这个页面需要的 JavaScript 代码-->
<script src="login_f926c4e6.js"></script>
<!--Disqus 评论容器-->
<div id="disqus_thread"></div>
</body>
</html>
Создайте структуру каталогов следующим образом:
dist
├── common_029086ff.js
├── common_7cc98ad0.css
├── index.html
├── index_04c08fbf.css
├── index_b3d3761c.js
├── login.html
├── login_0a3feca9.js
└── login_e31e214b.css
Если вы следуете идеям, изложенным в предыдущем разделе, вам может потребоваться настроить фрагмент кода следующим образом для каждого одностраничного приложения:
new WebPlugin({
template: './template.html', // HTML 模版文件所在的文件路径
filename: 'login.html' // 输出的 HTML 的文件名称
})
И добавьте запись, соответствующую странице, вenrty
В пункте конфигурации, вот так:
entry: {
index: './pages/index/index.js',// 页面 index.html 的入口文件
login: './pages/login/index.js',// 页面 login.html 的入口文件
}
Когда добавляется новая страница, необходимо изменить файл конфигурации Webpack и вставить более одного фрагмента кода, что затрудняет поддержку кода сборки и подвержено ошибкам.
решение
в предыдущем разделеweb-webpack-pluginПлагин также построил решение этой проблемы, единственное, что использует егоWebPlugin
,
Этот раздел будет использовать егоAutoWebPlugin
Чтобы решить вышеуказанные проблемы, метод использования очень прост, следующее научит вас, как его использовать.
Структура каталогов исходного кода проекта выглядит следующим образом:
├── pages
│ ├── index
│ │ ├── index.css // 该页面单独需要的 CSS 样式
│ │ └── index.js // 该页面的入口文件
│ └── login
│ ├── index.css
│ └── index.js
├── common.css // 所有页面都需要的公共 CSS 样式
├── google_analytics.js
├── template.html
└── webpack.config.js
Из структуры каталогов можно увидеть следующие требования:
- Весь код одностраничного приложения нужно поместить в каталог, например, в каталог pages;
- Однострановое приложение имеет отдельную папку, такую как последнее сгенерированное
index.html
Связанный код Inindex
Под содержанием,login.html
тоже самое; - Каждый одностраничный каталог приложения имеет
index.js
Файл используется как запись для выполнения файла.
несмотря на то что
AutoWebPlugin
Структура каталогов проектной части обязательна, но, как показывает практика, это элегантная спецификация каталогов, разумно разделяющая код и позволяющая новичкам быстро понять структуру проекта, что также удобно для дальнейшего сопровождения.
Файл конфигурации Webpack изменяется следующим образом:
const { AutoWebPlugin } = require('web-webpack-plugin');
// 使用本文的主角 AutoWebPlugin,自动寻找 pages 目录下的所有目录,把每一个目录看成一个单页应用
const autoWebPlugin = new AutoWebPlugin('pages', {
template: './template.html', // HTML 模版文件所在的文件路径
postEntrys: ['./common.css'],// 所有页面都依赖这份通用的 CSS 样式文件
// 提取出所有页面公共的代码
commonsChunk: {
name: 'common',// 提取出公共代码 Chunk 的名称
},
});
module.exports = {
// AutoWebPlugin 会为寻找到的所有单页应用,生成对应的入口配置,
// autoWebPlugin.entry 方法可以获取到所有由 autoWebPlugin 生成的入口配置
entry: autoWebPlugin.entry({
// 这里可以加入你额外需要的 Chunk 入口
}),
plugins: [
autoWebPlugin,
],
};
Чтобы сосредоточить внимание на части этой статьи, посвященной модификации, в приведенном выше файле конфигурации пропущен некоторый код, который согласуется с предыдущим разделом.Для получения полного кода обратитесь к предыдущему разделу или загрузите полный код этого проект.
AutoWebPlugin
узнаетpages
2 папки в каталогеindex
а такжеlogin
, думайте об этих двух папках как о двух одностраничных приложениях.
И сгенерируйте конфигурацию Chunk иWebPlugin
конфигурация.
Имя фрагмента каждого одностраничного приложения равно имени папки, то естьautoWebPlugin.entry()
Метод возвращает содержимое:
{
"index":["./pages/index/index.js","./common.css"],
"login":["./pages/login/index.js","./common.css"]
}
но эти вещиAutoWebPlugin
Это будет сделано автоматически за вас, вам не нужно об этом беспокоиться, просто поймите общий принцип.
template.html
Файл шаблона выглядит следующим образом:
<html>
<head>
<meta charset="UTF-8">
<!--在这注入该页面所依赖但没有手动导入的 CSS-->
<!--STYLE-->
<!--注入 google_analytics 中的 JS 代码-->
<script src="./google_analytics.js?_inline"></script>
<!--异步加载 Disqus 评论-->
<script src="https://dive-into-webpack.disqus.com/embed.js" async></script>
</head>
<body>
<div id="app"></div>
<!--在这注入该页面所依赖但没有手动导入的 JavaScript-->
<!--SCRIPT-->
<!--Disqus 评论容器-->
<div id="disqus_thread"></div>
</body>
</html>
Обратите внимание, что в файле шаблона появились 2 важных новых ключевых слова.<!--STYLE-->
а также<!--SCRIPT-->
, что они имеют в виду?
Поскольку этот файл шаблона используется в качестве шаблона для всех одностраничных приложений в проекте, больше невозможно напрямую написать имя чанка для импорта ресурсов, как в предыдущем разделе, потому что имя чанка, который необходимо быть введенным в текущую страницу, неясно, и каждое отдельное приложение каждой страницы будет иметь свое собственное имя.<!--STYLE-->
а также<!--SCRIPT-->
Функция заключается в том, чтобы гарантировать, что ресурсы, от которых зависит страница, будут внедрены в сгенерированный HTML-шаблон.
web-webpack-plugin может анализировать, от каких ресурсов зависит каждая страница, например, дляlogin.html
Например, плагин может определить, что страница зависит от следующих ресурсов:
- Общий код CSS, от которого зависят все страницы
common.css
; - Общий код JavaScript, на котором зависит все страницы
common.js
; - Только код CSS, от которого зависит эта страница
login.css
; - Только код JavaScript, от которого зависит эта страница
login.css
.
Из-за файла шаблонаtemplate.html
Нет инструкции HTML для введения этих зависимых ресурсов, плагин автоматически вставит ресурсы, которые не импортированы вручную, но зависят от страницы в соответствии с различными типами.<!--STYLE-->
а также<!--SCRIPT-->
Это расположено.
- CSS внедряется в типы файлов
<!--STYLE-->
расположение, если<!--STYLE-->
Отсутствующие вводятся в окончательные теги HTML HEAD; - JavaScript вводится в типы файлов
<!--SCRIPT-->
расположение, если<!--SCRIPT-->
Если он не существует, он будет вставлен в конце HTML-тега BODY.
Если в будущем появятся новые страницы, вам нужно толькоpages
Создайте новый каталог в каталоге, имя каталога — это имя выходного HTML-файла, а код, относящийся к этой странице, можно поместить в каталог без изменения кода сборки.
из-заAutoWebPlugin
косвенно через тот, который упоминался в предыдущем разделеWebPlugin
осуществленный,WebPlugin
Поддерживаемые функцииAutoWebPlugin
поддерживаются.
AutoWebPlugin
Плагин также поддерживает некоторые другие более сложные способы использования, подробности можно найти здесь.Домашняя страница проектаПрочтите документацию.
этот примерПредоставьте полный код проекта