Webpack实战-管理多个单页应用
引入问题上一节3-9为单页应用生成HTML中只生成了一个 HTML 文件,但在实际应用中一个完整的系统不会把所有的功能都做到一个网页中,因为这会导致这个网页性能不佳。 虽然上一节已经解决了自动化生成 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 的文件名称 }) 并且把页面对应的入口加入到 entry: { index: './pages/index/index.js',// 页面 index.html 的入口文件 login: './pages/login/index.js',// 页面 login.html 的入口文件 } 当有新页面加入时就需要修改 Webpack 配置文件,新插入一段以上代码,这会导致构建代码难以维护而且易错。 解决方案上一节中的 web-webpack-plugin 插件也内置了解决这个问题的方法,上一节中只使用了它的 项目源码目录结构如下: ├── pages │ ├── index │ │ ├── index.css // 该页面单独需要的 CSS 样式 │ │ └── index.js // 该页面的入口文件 │ └── login │ ├── index.css │ └── index.js ├── common.css // 所有页面都需要的公共 CSS 样式 ├── google_analytics.js ├── template.html └── webpack.config.js 从目录结构中可以看成出下几点要求:
虽然
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,],}; 以上配置文件为了重点展示出本文侧重修改的部分,省略了部分和上一节一致的代码,完整代码可以参照上一节或者下载本项目完整代码。
{ "index":["./pages/index/index.js","./common.css"],"login":["./pages/login/index.js","./common.css"] } 但这些事情
<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个重要的新关键字 由于这个模版文件被当作项目中所有单页应用的模版,就不能再像上一节中直接写 Chunk 的名称去引入资源,因为需要被注入到当前页面的 Chunk 名称是不定的,每个单页应用都会有自己的名称。 web-webpack-plugin 能分析出每个页面依赖哪些资源,例如对于
由于模版文件
如果后续有新的页面需要开发,只需要在 由于
本实例 提供项目完整代码
《深入浅出Webpack》全书在线阅读链接 阅读原文 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |