资讯专栏INFORMATION COLUMN

webpack多页应用架构系列(十五):论前端如何在后端渲染开发模式下夹缝生存

dinfer / 3296人阅读

摘要:回到纯静态页面开发阶段,让页面不需要后端渲染也能跑起来。改造开始本文着重介绍如何将静态页面改造成后端渲染需要的模板。总结在后端渲染的项目里使用多页应用架构是绝对可行的,可不要给老顽固们吓唬得又回到传统前端架构了。

本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。
原文地址:https://segmentfault.com/a/1190000008203380
如果您对本系列文章感兴趣,欢迎关注订阅这里:https://segmentfault.com/blog/array_huang
前言

近年来前端领域发展迅猛,前后端分离早已成为业界共识,各类管控系统(to B)上个SPA什么的也不值一提,但唯独偏展示类的项目,为了SEO,始终还是需要依赖于服务器端渲染html。

我过往也曾尝试为SPA弥补SEO,但现在看来,效果虽然达到了,但工作量也大大地增加(因为后端用的PHP,不能做到前后同构)。

虽然无法改变依赖服务器端渲染这一现实,但我们可以去勇敢地拥抱它,用前端的坚船利炮(aka webpack),把服务器端模板层给啃下来!

前导知识

webpack的基本使用

利用webpack生成HTML文件,及,构建模板布局系统

你所在项目后端模板引擎(如我目前使用的Slim框架,模板引擎仅为原生PHP)

两个阶段

整个前端项目,以本文主题的视角来看,可以分为两个阶段:

纯静态页面开发阶段

在这个阶段里,一切开发都跟静态网站无二致,按UI稿切好页面搞好交互,要用到ajax请求API的也尽管写,跟后端的协作点仅在于API文档。

传统前端的工作也就到这里为止了,但对我们来说,目前的成果并不是我们最终的交付;因此,注意了,在这个阶段我们是可以“偷懒”的,比如说,一些明显应该由服务器端循环生成的部分(商品列表、文章列表等),我们写一遍就OK了。

动态页面改造阶段

这就是所谓的“套页面”,传统来说是由后端来做的,实际上后端也是苦不堪言,毕竟模板不是自己写的,有时还是需要改造一番,而这正是我们前端要大力争取的活。

在这个阶段里,我们的主要工作是按照后端模板引擎的规则来撰写模板变量占位符,当然这里面也不会少了循环输出和逻辑判断,另外也可能需要用到后端定义的一些函数,视项目需求而定。

在两个阶段里来回往返

这两个阶段不一定是完全独立的,有需要的话也是可以做到来回往返的。

那什么时候才叫做“有需要”呢?举个例子,当你把原先的静态页面都改造成需要后端渲染的页面模板后,却发现后端此时并未准备好相应的模板变量,而你此时又需要对页面的UI部分进行修改,那么你就很被动了,因为改好的这些页面模板根本跑不起来了。有两种解决方案:

参考API mock的思路,来个模板变量 mock,这就相当于一直留在动态页面改造阶段了。

回到纯静态页面开发阶段,让页面不需要后端渲染也能跑起来。具体怎么做呢?

区分开两个阶段,使用不同的webpack配置。

在我们构建生成页面的前端模板(注意分清与后端模板的区别),判断(判断依据看这里)本次执行webpack打包是在哪个“阶段”,继而选择是生成静态(且完整)的element,还是带有模板变量占位符的element。这样一来,我们就可以随时选择在不同的阶段(或称环境)里进行开发了。

改造开始

本文着重介绍如何将静态页面改造成后端渲染需要的模板。

配合后端模板命名规则生成相应模板文件

不同项目因应本身所使用的后端框架或是其它需求,对模板放置的目录结构也会有所不一样,那么,如何构建后端所需要的目录结构呢?

在静态网页阶段,我习惯把html/css/js都按照所属页面归到各自的目录中(公用的css/js也当然是放到公用目录中),看HtmlWebpackPlugin配置:

pageArr.forEach((page) => {
  const htmlPlugin = new HtmlWebpackPlugin({
    filename: `${page}/index.html`, // page变量形如"product/index"、"product/detail"
    template: path.resolve(dirVars.pagesDir, `./${page}/html.js`),
    chunks: [page, "commons/commons"],
    hash: true,
    xhtml: true,
  });
  pluginsConfig.push(htmlPlugin);
});

而在改造阶段,则放到后端指定位置:

pageArr.forEach((page) => {
  const htmlPlugin = new HtmlWebpackPlugin({
    filename: `../../view/frontend/${page}.php`, // 通过控制相对路径来确定模板的根目录
    template: path.resolve(dirVars.pagesDir, `./${page}/html.js`),
    chunks: [page, "commons/commons"],
    hash: true,
    xhtml: true,
  });
  pluginsConfig.push(htmlPlugin);
});

此时我模板目录结构是这样的:

│  
├─alert
│      index.php
│      
├─article
│      detail.php
│      index.php
│      
├─index
│      index.php
│      
├─product
│      detail.php
│      index.php
│      
└─user
        edit-password.php
        modify-info.php

这里需要注意的是,我的前端项目目录实际上是作为后端目录里的一个子目录来存放的,这样才能依靠相对路径来确定模板文件存放的根目录位置。

处理站内链接

对于站内链接,我建议在前端模板里使用一个函数来适配两个阶段:

{
  /* 拼接系统内部的URL */
  constructInsideUrl(url, request, urlTail) {
    urlTail = urlTail || "";
    let finalUrl = config.PAGE_ROOT_PATH + url;
    if (!config.IS_PRODUCTION_MODE) {
      finalUrl += "/index.html" + urlTail;
      return finalUrl;
    }
    return ` "${url}"), $isStaticize)?>`;
  },
};

在前端模板里这么用:

">
  ">

这样做,就能分别在静态页面阶段和后端渲染阶段生成相应的超链接。再者,在后端渲染阶段,我们生成出来的也不一定是一个完整的url,可以像我上述代码一样,生成调用后端函数的模板代码,从而灵活满足后端的一些需求(比如说,我的项目有静态化的需求,那么,静态化后的站内链接跟动态渲染的又会有所不同了)。

处理模板变量

这一块其实我要说的不多,无非就是按照后端模板引擎的规则,输出变量、循环输出变量、判断条件输出变量、调用后端(模板引擎)函数调整输出变量。

关键是,我们需要拿到一份模板变量文档,跟API文档类似,它实际上也是一份前后端的数据协议。有了这份文档,我们才能在后端未完工的情况下,进入动态页面改造阶段,并根据其中内容实现模板变量 mock

争讨模板布局渲染权

关于利用模板布局系统对多个页面共有的部分实现复用,在之前的文章里已经提及了,我设计该系统的思路恰恰是来自于后端模板渲染。那么,在前后端均可以实现模板布局系统的前提下,我们应如何抉择呢?我的答案是,前端一定要吃下来!

从前端的角度来看:

我们在纯静态页面开发阶段的产物就已经是一个个完整的页面了,再要拆开并不现实。

由于在webpack的辅助下这套模板布局系统功能相当强大,因此并没有给整个项目添加额外的成本。

从后端的角度来看:

服务器拼接多个HTML代码段本身也是有成本(比如磁盘IO成本)的,倒不如渲染一个完整的页面。

在公共组件的分治管理上不会有很大变化,只不过以前是一个一个组件渲染好后再拼在一起,而现在是把各个组件的数据整合在一起来统一渲染罢了。

总结

在后端渲染的项目里使用webpack多页应用架构是绝对可行的,可不要给老顽固们吓唬得又回到传统前端架构了。

示例代码

诸位看本系列文章,搭配我在Github上的脚手架项目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed)。

附系列文章目录(同步更新)

webpack多页应用架构系列(一):一步一步解决架构痛点

webpack多页应用架构系列(二):webpack配置常用部分有哪些?

webpack多页应用架构系列(三):怎么打包公共代码才能避免重复?

webpack多页应用架构系列(四):老式jQuery插件还不能丢,怎么兼容?

webpack多页应用架构系列(五):听说webpack连less/css也能打包?

webpack多页应用架构系列(六):听说webpack连图片和字体也能打包?

webpack多页应用架构系列(七):开发环境、生产环境傻傻分不清楚?

webpack多页应用架构系列(八):教练我要写ES6!webpack怎么整合Babel?

webpack多页应用架构系列(九):总有刁民想害朕!ESLint为你阻击垃圾代码

webpack多页应用架构系列(十):如何打造一个自定义的bootstrap

webpack多页应用架构系列(十一):预打包Dll,实现webpack音速编译

webpack多页应用架构系列(十二):利用webpack生成HTML普通网页&页面模板

webpack多页应用架构系列(十三):构建一个简单的模板布局系统

webpack多页应用架构系列(十四):No复制粘贴!多项目共用基础设施

webpack多页应用架构系列(十五):论前端如何在后端渲染开发模式下夹缝生存

webpack多页应用架构系列(十六):善用浏览器缓存,该去则去,该留则留

本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。
原文地址:https://segmentfault.com/a/1190000008203380
如果您对本系列文章感兴趣,欢迎关注订阅这里:https://segmentfault.com/blog/array_huang

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30543.html

相关文章

  • webpack多页应用架构系列十五):如何在后渲染开发模式夹缝生存

    摘要:回到纯静态页面开发阶段,让页面不需要后端渲染也能跑起来。改造开始本文着重介绍如何将静态页面改造成后端渲染需要的模板。总结在后端渲染的项目里使用多页应用架构是绝对可行的,可不要给老顽固们吓唬得又回到传统前端架构了。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/119000000820338...

    dingda 评论0 收藏0
  • webpack多页应用架构系列(一):一步一步解决架构痛点

    摘要:本文首发于的技术博客实用至上,非经作者同意,请勿转载。原文地址如果您对本系列文章感兴趣,欢迎关注订阅这里这系列文章讲什么本系列文章主要介绍如何用这一当前流行的构建工具来设计一个多页应用的架构。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/1190000006843916如果您对本系列文章...

    Lowky 评论0 收藏0
  • webpack多页应用架构系列(三):怎么打包公共代码才能避免重复?

    摘要:在上一篇文章多页应用架构系列二配置常用部分有哪些中,我介绍了如何配置多页应用的入口,然而,如果仅仅如此操作,带来的后果就是,打包生成出来的每一个入口文件都会完整包含所有代码。的初始化常用参数有哪些,给这个包含公共代码的命个名唯一标识。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/1190...

    oliverhuang 评论0 收藏0
  • webpack多页应用架构系列(九):总有刁民想害朕!ESLint为你阻击垃圾代码

    摘要:本文首发于的技术博客实用至上,非经作者同意,请勿转载。如果你使用了,或类似的,那么,通过编译前后的代码相差就很大了,这会造成两个问题以为例把你的代码转成什么样你自己是无法控制的,这往往导致无法通过的审查。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/1190000007030775如果您...

    dingding199389 评论0 收藏0
  • webpack多页应用架构系列(十二):利用webpack生成HTML普通网页&页面模板

    摘要:彻底分离源文件目录和生成文件目录使用生成出来的页面可以很安心地跟打包好的其它资源放到一起,相对于另起一个目录专门存放页面文件来说,整个文件目录结构更加合理如何利用生成页面生成页面主要是通过来实现的,下面来介绍如何实现。 本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。原文地址:https://segmentfault.com/a/119000000712...

    BaronZhang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<