提出问题
在前面的3-9节中,只生成了一个HTML文件,用于为单页应用程序生成HTML。 但在实际应用中,一个完整的系统不会将所有的功能都放到一个网页中,因为这会导致网页的性能较差。 好的。
实际做法是根据功能模块定义多个单页应用,并为每个单页应用生成一个HTML文件。 而且随着业务的发展,项目中可能会逐渐加入更多的单页应用。
其实上一节已经解决了手动生成HTML的痛点,而自动管理多个单页面应用的生成也是一件麻烦的事情。
我们继续修改上一节的例子,需求如下:
在开始之前,我们先看一下在线发布的应用程序的最终代码。
Login.html 文件内容:
(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');
创建的目录结构为:
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 的文件名称 })
而是将页面对应的entry添加到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
从目录结构可以看出以下需求:
虽然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目录下找到index和login这两个文件夹,并将这两个文件夹视为两个单页面应用程序。
但是,会为每个单页应用程序生成一个 Chunk 配置和 WebPlugin 配置。
每个单页应用程序的Chunk名称等于文件夹的名称。 也就是说autoWebPlugin.entry()方法返回的内容为:
{ "index":["./pages/index/index.js","./common.css"], "login":["./pages/login/index.js","./common.css"] }
但 AutoWebPlugin 会手动为您完成此操作,因此您不必担心,只需了解一般原理即可。
template.html模板文件如下:
注意到模板文件中出现了两个重要的新关键字 和 。 他们的意思是什么?
因为这个模板文件是作为项目中所有单页应用的模板,所以不能再像上一节那样直接写Chunk名称来引入资源,因为需要注入当前页面的Chunk名称是不确定的webpack单页,并且每个单页应用程序都会有自己的名称。
和的作用是保证页面所依赖的资源会被注入到生成的HTML模板中。
web-webpack-plugin可以分析每个页面依赖哪些资源。 例如,对于login.html,插件可以确定该页面依赖于以下资源:
由于模板文件template.html并不强调引入依赖资源的HTML语句webpack单页,因此插件会根据不同的类型和位置,手动注入不自动导出但页面依赖的资源。
如果以后有新的页面需要开发,只需要在pages目录下新建一个目录即可。 目录名称是输出 HTML 文件的名称。 与此页面相关的代码可以放在该目录中,无需更改创建代码。
由于AutoWebPlugin是通过上一节提到的WebPlugin间接实现的,因此AutoWebPlugin支持WebPlugin支持的所有功能。
AutoWebPlugin插件还支持其他一些更中间的用法。 具体可以访问项目主页阅读文档。
本示例提供了项目的完整代码
” >
《Webpack in a Simple Language》全书在线阅读链接