摘要:彻底分离源文件目录和生成文件目录使用生成出来的页面可以很安心地跟打包好的其它资源放到一起,相对于另起一个目录专门存放页面文件来说,整个文件目录结构更加合理如何利用生成页面生成页面主要是通过来实现的,下面来介绍如何实现。
本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。为什么要用webpack来生成HTML页面
原文地址:https://segmentfault.com/a/1190000007126268
如果您对本系列文章感兴趣,欢迎关注订阅这里:https://segmentfault.com/blog/array_huang
按照我们前面的十一篇的内容来看,自己写一个HTML页面,然后在上面加载webpack打包的js或其它类型的资源,感觉不也用得好好的么?
是的没错,不用webpack用requireJs其实也可以啊,甚至于,传统那种人工管理模块依赖的做法也没有什么问题嘛。
但既然你都已经看到这一篇了,想必早已和我一样,追求着以下这几点吧:
更懒,能自动化的事情绝不做第二遍。
更放心,调通的代码比人靠谱,更不容易出错。
代码洁癖,什么东西该放哪,一点都不能含糊,混在一起我就要死了。
那么,废话不多说,下面就来说说使用webpack生成HTML页面有哪些好处吧。
对多个页面共有的部分实现复用在实际项目的开发过程中,我们会发现,虽然一个项目里会有很多个页面,但这些页面总有那么几个部分是相同或相似的,尤其是页头页尾,基本上是完全一致的。那我们要怎么处理这些共有的部分呢?
复制粘贴流不就是复制粘贴的事嘛?写好一份完整的HTML页面,做下个页面的时候,直接copy一份文件,然后直接在copy的文件上进行修改不就好了吗?
谁是这么想这么做的,放学留下来,我保证不打死你!我曾经接受过这么一套系统,顶部栏菜单想加点东西,就要每个页面都改一遍,可维护性烂到爆啊。
Iframe流Iframe流常见于管理后台类项目,可维护性OK,就是缺陷比较多,比如说:
点击某个菜单,页面是加载出来了但是浏览器地址栏上的URL没变,刷新的话又回到首页了。
搜索引擎收录完蛋,前台项目一般不能用Iframe来布局。
没有逼格,Low爆了,这是最重要的一点(大误)。
SPA流最近这几年,随着移动互联网的兴起,SPA也变得非常常见了。不过SPA的局限性也非常大,比如搜索引擎无法收录,但我个人最在意的,是它太复杂了,尤其是一些本来业务逻辑就多的系统,很容易懵圈。
后端模板渲染这倒真是一个办法,只是,需要后端的配合,利用后端代码把页面的各个部分给拼合在一起,所以这方法对前端起家的程序员还是有点门槛的。
利用前端模板引擎生成HTML页面所谓“用webpack生成HTML页面”,其实也并不是webpack起的核心作用,实际上靠的还是前端的模板引擎将页面的各个部分给拼合在一起来达到公共区域的复用。webpack更多的是组织统筹整个生成HTML页面的过程,并提供更大的控制力。最终,webpack生成的到底是完整的页面,还是供后端渲染的模板,就全看你自己把控了,非常灵活,外人甚至察觉不出来这到底是你自己写的还是代码统一生成的。
处理资源的动态路径如果你想用在文件名上加hash的方法作为缓存方案的话,那么用webpack生成HTML页面就成为你唯一的选择了,因为随着文件的变动,它的hash也会变化,那么整个文件名都会改变,你总不能在每次编译后都手动修改加载路径吧?还是放心交给webpack吧。
自动加载webpack生成的css、less如果你使用webpack来生成HTML页面,那么,你可以配置好每个页面加载的chunk(webpack打包后生成的js文件),生成出来的页面会自动用来加载这些chunk,路径什么的你都不用管了哈(当然前提是你配置好了output.publicPath)。另外,用extract-text-webpack-plugin打包好的css文件,webpack也会帮你自动添加到里,相当方便。
彻底分离源文件目录和生成文件目录使用webpack生成出来的HTML页面可以很安心地跟webpack打包好的其它资源放到一起,相对于另起一个目录专门存放HTML页面文件来说,整个文件目录结构更加合理:
build - index - index - entry.js - page.html - login - entry.js - page.html - styles.css如何利用webpack生成HTML页面
webpack生成HTML页面主要是通过html-webpack-plugin来实现的,下面来介绍如何实现。
html-webpack-plugin的配置项每一个html-webpack-plugin的对象实例都只针对/生成一个页面,因此,我们做多页应用的话,就要配置多个html-webpack-plugin的对象实例:
pageArr.forEach((page) => { const htmlPlugin = new HtmlWebpackPlugin({ filename: `${page}/page.html`, template: path.resolve(dirVars.pagesDir, `./${page}/html.js`), chunks: [page, "commons"], hash: true, // 为静态资源生成hash值 minify: true, xhtml: true, }); configPlugins.push(htmlPlugin); });
pageArr实际上是各个chunk的name,由于我在output.filename设置的是"[name]/entry.js",因此也起到构建文件目录结构的效果(具体请看这里),附上pageArr的定义:
module.exports = [ "index/login", "index/index", "alert/index", "user/edit-password", "user/modify-info", ];
html-webpack-plugin的配置项真不少,这里仅列出多页应用常用到的配置:
filename,生成的网页HTML文件的文件名,注意可以利用/来控制文件目录结构的,其最终生成的路径,是基于webpack配置中的output.path的。
template,指定一个基于某种模板引擎语法的模板文件,html-webpack-plugin默认支持ejs格式的模板文件,如果你想使用其它格式的模板文件,那么需要在webpack配置里设置好相应的loader,比如handlebars-loader啊html-loader啊之类的。如果不指定这个参数,html-webpack-plugin会使用一份默认的ejs模板进行渲染。如果你做的是简单的SPA应用,那么这个参数不指定也行,但对于多页应用来说,我们就依赖模板引擎给我们拼装页面了,所以这个参数非常重要。
inject,指示把加载js文件用的插入到哪里,默认是插到的末端,如果设置为"head",则把插入到里。
minify,生成压缩后的HTML代码。
hash,在由html-webpack-plugin负责加载的js/css文件的网址末尾加个URL参数,此URL参数的值是代表本次编译的一个hash值,每次编译后该hash值都会变化,属于缓存解决方案。
chunks,以数组的形式指定由html-webpack-plugin负责加载的chunk文件(打包后生成的js文件),不指定的话就会加载所有的chunk。
生成一个简单的页面下面提供一份供生成简单页面(之所以说简单,是因为不指定页面模板,仅用默认模板)的配置:
var HtmlWebpackPlugin = require("html-webpack-plugin"); var webpackConfig = { entry: "index.js", output: { path: "dist", filename: "index_bundle.js" }, plugins: [new HtmlWebpackPlugin({ title: "简单页面", filename: "index.html", })], };
使用这份配置编译后,会在dist目录下生成一个index.html,内容如下所示:
简单页面
由于没有指定模板文件,因此生成出来的HTML文件仅有最基本的HTML结构,并不带实质内容。可以看出,这更适合React这种把HTML藏js里的方案。
利用模板引擎获取更大的控制力接下来,我们演示如何通过制定模板文件来生成HTML的内容,由于html-webpack-plugin原生支持ejs模板,因此这里也以ejs作为演示对象:
<%= htmlWebpackPlugin.options.title %> 这是一个用html-webpack-plugin生成的HTML页面
大家仔细瞧好了
"html-webpack-plugin"的配置里也要指定template参数:
var HtmlWebpackPlugin = require("html-webpack-plugin"); var webpackConfig = { entry: "index.js", output: { path: "dist", filename: "index_bundle.js" }, plugins: [new HtmlWebpackPlugin({ title: "按照ejs模板生成出来的页面", filename: "index.html", template: "index.ejs", })], };
那么,最后生成出来的HTML文件会是这样的:
按照ejs模板生成出来的页面 这是一个用html-webpack-plugin生成的HTML页面
大家仔细瞧好了
到这里,我们已经可以控制整个HTML文件的内容了,那么生成后端渲染所需的模板也就不是什么难事了,以PHP的模板引擎smarty为例:
处理资源的动态路径<%= htmlWebpackPlugin.options.title %> 这是一个用html-webpack-plugin生成的HTML页面
大家仔细瞧好了
这是用smarty生成的内容:{$articleContent}
接下来在上面例子的基础上,我们演示如何处理资源的动态路径:
var HtmlWebpackPlugin = require("html-webpack-plugin"); var webpackConfig = { entry: "index.js", output: { path: "dist", filename: "index_bundle.[chunkhash].js" }, plugins: [new HtmlWebpackPlugin({ title: "按照ejs模板生成出来的页面", filename: "index.html", template: "index.ejs", })], module: { loaders: { // 图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求 // 如下配置,将小于8192byte的图片转成base64码 test: /.(png|jpg|gif)$/, loader: "url?limit=8192&name=./static/img/[hash].[ext]", }, }, };
<%= htmlWebpackPlugin.options.title %> 这是一个用html-webpack-plugin生成的HTML页面
大家仔细瞧好了
我们改动了什么呢?
参数output.filename里,我们添了个变量[chunkhash],这个变量的值会随chunk内容的变化而变化,那么,这个chunk文件最终的路径就会是一个动态路径了。
我们在页面上添加了一个
这是一个用html-webpack-plugin生成的HTML页面
大家仔细瞧好了
显然,html-webpack-plugin成功地将chunk加载了,又处理好了转化为DataUrl格式的图片,这一切,都是我们手工难以完成的事情。
还未结束至此,我们实现了使用webpack生成HTML页面并尝到了它所带来的甜头,但我们尚未实现“对多个页面共有的部分实现复用”,下一篇《webpack多页应用架构系列(十三):构建一个简单的模板布局系统》我们就来介绍这部分的内容。
示例代码诸位看本系列文章,搭配我在Github上的脚手架项目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed)。
附系列文章目录(同步更新)webpack多页应用架构系列(一):一步一步解决架构痛点:https://segmentfault.com/a/1190000006843916
webpack多页应用架构系列(二):webpack配置常用部分有哪些?:https://segmentfault.com/a/1190000006863968
webpack多页应用架构系列(三):怎么打包公共代码才能避免重复?:https://segmentfault.com/a/1190000006871991
webpack多页应用架构系列(四):老式jQuery插件还不能丢,怎么兼容?:https://segmentfault.com/a/1190000006887523
webpack多页应用架构系列(五):听说webpack连less/css也能打包?:https://segmentfault.com/a/1190000006897458
webpack多页应用架构系列(六):听说webpack连图片和字体也能打包?:https://segmentfault.com/a/1190000006907701
webpack多页应用架构系列(七):开发环境、生产环境傻傻分不清楚?:https://segmentfault.com/a/1190000006952432
webpack多页应用架构系列(八):教练我要写ES6!webpack怎么整合Babel?:https://segmentfault.com/a/1190000006992218
webpack多页应用架构系列(九):总有刁民想害朕!ESLint为你阻击垃圾代码:https://segmentfault.com/a/1190000007030775
webpack多页应用架构系列(十):如何打造一个自定义的bootstrap:https://segmentfault.com/a/1190000007043716
webpack多页应用架构系列(十一):预打包Dll,实现webpack音速编译:https://segmentfault.com/a/1190000007104372
webpack多页应用架构系列(十二):利用webpack生成HTML普通网页&页面模板:https://segmentfault.com/a/1190000007126268
webpack多页应用架构系列(十三):构建一个简单的模板布局系统:https://segmentfault.com/a/1190000007159115
webpack多页应用架构系列(十四):No复制粘贴!多项目共用基础设施
webpack多页应用架构系列(十五):论前端如何在后端渲染开发模式下夹缝生存
webpack多页应用架构系列(十六):善用浏览器缓存,该去则去,该留则留
本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。
原文地址:https://segmentfault.com/a/1190000007126268
如果您对本系列文章感兴趣,欢迎关注订阅这里:https://segmentfault.com/blog/array_huang
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/80638.html
摘要:原文地址如果您对本系列文章感兴趣,欢迎关注订阅这里前言上文多页应用架构系列十二利用生成普通网页页面模板我们基本上已经搞清楚如何利用来生成普通网页页面模板,本文将以我的脚手架项目介绍如何在这基础上搭建一套简单的模板布局系统。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/1190000007...
摘要:回到纯静态页面开发阶段,让页面不需要后端渲染也能跑起来。改造开始本文着重介绍如何将静态页面改造成后端渲染需要的模板。总结在后端渲染的项目里使用多页应用架构是绝对可行的,可不要给老顽固们吓唬得又回到传统前端架构了。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/119000000820338...
摘要:回到纯静态页面开发阶段,让页面不需要后端渲染也能跑起来。改造开始本文着重介绍如何将静态页面改造成后端渲染需要的模板。总结在后端渲染的项目里使用多页应用架构是绝对可行的,可不要给老顽固们吓唬得又回到传统前端架构了。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/119000000820338...
摘要:本文首发于的技术博客实用至上,非经作者同意,请勿转载。原文地址如果您对本系列文章感兴趣,欢迎关注订阅这里这系列文章讲什么本系列文章主要介绍如何用这一当前流行的构建工具来设计一个多页应用的架构。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/1190000006843916如果您对本系列文章...
摘要:在上一篇文章多页应用架构系列二配置常用部分有哪些中,我介绍了如何配置多页应用的入口,然而,如果仅仅如此操作,带来的后果就是,打包生成出来的每一个入口文件都会完整包含所有代码。的初始化常用参数有哪些,给这个包含公共代码的命个名唯一标识。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/1190...
阅读 3263·2021-10-11 10:59
阅读 2815·2021-10-11 10:58
阅读 2245·2021-09-04 16:45
阅读 2719·2019-08-30 15:44
阅读 674·2019-08-30 15:44
阅读 3201·2019-08-30 10:51
阅读 1600·2019-08-29 18:46
阅读 2750·2019-08-29 13:57