摘要:原文地址如果您對本系列文章感興趣,歡迎關注訂閱這里前言上文多頁應用架構系列十二利用生成普通網頁頁面模板我們基本上已經搞清楚如何利用來生成普通網頁頁面模板,本文將以我的腳手架項目介紹如何在這基礎上搭建一套簡單的模板布局系統。
本文首發于Array_Huang的技術博客——實用至上,非經作者同意,請勿轉載。前言
原文地址:https://segmentfault.com/a/1190000007159115
如果您對本系列文章感興趣,歡迎關注訂閱這里:https://segmentfault.com/blog/array_huang
上文《webpack多頁應用架構系列(十二):利用webpack生成HTML普通網頁&頁面模板》我們基本上已經搞清楚如何利用html-webpack-plugin來生成HTML普通網頁&頁面模板,本文將以我的腳手架項目Array-Huang/webpack-seed介紹如何在這基礎上搭建一套簡單的模板布局系統。
模板布局系統架構圖 模板布局系統各部分詳解上文我們說到,利用模板引擎&模板文件,我們可以控制HTML的內容,但這種控制總體來說還是比較有限的,而且很大程度受限于你對該模板引擎的熟悉程度,那么,有沒有更簡單的方法呢?
有!我們可以就用我們最熟悉的js來肆意組裝、拼接出我們想要的HTML!
首先來看一個上文提到的例子:
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-webpack-plugin指定一個名為index.ejs的ejs模板文件,來達到生成HTML頁面文件的目的,從html-webpack-plugin的文檔我們可以看出,除了默認支持的ejs外,其實還可以使用其它模板引擎(例如jade、handlebars、underscore),支持的方法是在webpack配置文件中配置好相應的loader即可。
因此,我們可以推理出,html-webpack-plugin其實并不關心你用的是什么模板引擎,只要你的模板最后export出來的是一份完整的HTML代碼(字符串)就可以了。于是,我做了一個大膽的嘗試,給html-webpack-plugin的template參數指定一個js文件,然后在此js文件末尾export出一份完整的HTML代碼來。這個js文件我命名為“模板接口”(上面架構圖上有標識),意思是,不是光靠這一個js文件就能形成一份模板,“接口”之后是一套完整的模板布局體系。下面以webpack-seed項目里的src/pages/alert/index(“消息通知”頁)作為例子進行說明。
html-webpack-plugin配置先來看看我是如何給html-webpack-plugin指定一個js作為模板的:
/* 這是用來生成alert/index頁的HtmlWebpackPlugin配置 在原項目中是循環批量new HtmlWebpackPlugin的,此處為了更容易理解,特別針對alert/index頁做了修改 */ new HtmlWebpackPlugin({ filename: `alert/index/page.html`, template: path.resolve(dirVars.pagesDir, `./alert/index/html.js`), // 指定為一個js文件而非普通的模板文件 chunks: ["alert/index", "commons"], // 自動加載上index/login的入口文件以及公共chunk hash: true, // 為靜態資源生成hash值 xhtml: true, // 需要符合xhtml的標準 });模板接口
下面來介紹這個作為模板接口的js文件:
/* 選自webpack-seed/pages/alert/index/html.js */ const content = require("./content.ejs"); // 調取存放本頁面實際內容的模板文件 const layout = require("layout"); // 調用管理后臺內部所使用的布局方案,我在webpack配置里定義其別名為"layout" const pageTitle = "消息通知"; // 頁面名稱 // 給layout傳入“頁面名稱”這一參數(當然有需要的話也可以傳入其它參數),同時也傳入頁面實際內容的HTML字符串。content({ pageTitle })的意思就是把pageTitle作為模板變量傳給ejs模板引擎并返回最終生成的HTML字符串。 module.exports = layout.init({ pageTitle }).run(content({ pageTitle }));
從代碼里我們可以看出,模板接口的作用實際上就是整理好當前頁面獨有的內容,然后交與layout作進一步的渲染;另一方面,模板接口直接把layout最終返回的結果(完整的HTML文檔)給export出來,供html-webpack-plugin生成HTML文件使用。
頁面實際內容長啥樣?layout<%= pageTitle %>
接著我們來看看整套模板布局系統的核心——layout。layout的主要功能就是接收各個頁面獨有的參數(比如說頁面名稱),并將這些參數傳入各個公共組件生成各組件的HTML,然后根據layout本身的模板文件將各組件的HTML以及頁面實際內容的HTML拼接在一起,最終形成一個完整的HTML頁面文檔。
/* 選自webpack-seed/src/public-resource/layout/layout/html.js */ const config = require("configModule"); const noJquery = require("withoutJqueryModule"); const layout = require("./html.ejs"); // 整個頁面布局的模板文件,主要是用來統籌各個公共組件的結構 const header = require("../../components/header/html.ejs"); // 頁頭的模板 const footer = require("../../components/footer/html.ejs"); // 頁腳的模板 const topNav = require("../../components/top-nav/html.ejs"); // 頂部欄的模板 const sideMenu = require("../../components/side-menu/html.ejs"); // 側邊欄的模板 const dirsConfig = config.DIRS; /* 整理渲染公共部分所用到的模板變量 */ const pf = { pageTitle: "", constructInsideUrl: noJquery.constructInsideUrl, }; const moduleExports = { /* 處理各個頁面傳入而又需要在公共區域用到的參數 */ init({ pageTitle }) { pf.pageTitle = pageTitle; // 比如說頁面名稱,會在或面包屑里用到 return this; }, /* 整合各公共組件和頁面實際內容,最后生成完整的HTML文檔 */ run(content) { const headerRenderData = Object.assign(dirsConfig, pf); // 頁頭組件需要加載css/js等,因此需要比較多的變量 const renderData = { header: header(headerRenderData), footer: footer(), topNav: topNav(pf), sideMenu: sideMenu(pf), content, }; return layout(renderData); }, }; module.exports = moduleExports;
接下來看看layout本身的模板文件長啥樣吧:
<%= header %>組件<%= topNav %> <%= sideMenu %> <%= content %><%= footer %>
整個頁面的公共部分,被我以區域的形式切分成一個一個的組件,下面以頁頭組件作為例子進行解釋:
<% if (pageTitle) { %> <%= pageTitle %> - <% } %> XXXX后臺
頁頭組件控制的范圍基本上就是整個
以及的頭部。不要小看這的頭部,由于webpack在使用extract-text-webpack-plugin生成CSS文件并自動加載時,會把放在
的最后,而眾所周知,實現IE8下Media Queries特性的respond.js是需要放在css后面來加載的,因此,我們就只能把respond.js放到的頭部來加載了。由于我的腳手架項目還是比較簡單的,所以這些公共組件的HTML都是直接根據模板文件來輸出的;如果組件本身要處理的邏輯比較多,可以使用跟模板接口一樣的思路,利用js文件來拼接。
至于組件本身行為的邏輯(js),可以一并放到各組件的目錄里,在公共chunk里調用便是了。本文實際上只關注于如何生成HTML,這里提到這個只是提示一下組件的文件目錄結構。
這里稍微再解釋一下BUILD_FILE.js.*和BUILD_FILE.dll.*是什么,這些其實都是沒有用webpack打包起來的js/css,我用file-loader把這些文件從src目錄搬到build目錄了,這里模板變量輸出的都是搬運后的路徑,具體請看《webpack多頁應用架構系列(六):聽說webpack連圖片和字體也能打包?》。啟動搬運的代碼放在webpack-seed/src/public-resource/config/build-file.config.js。
總結有了這套模板布局系統,我們就可以輕松地生成具有相同布局的多個靜態頁面了,“如何管理頁面布局公共部分”這一多頁應用的痛點也就順利解決了。
示例代碼諸位看本系列文章,搭配我在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復制粘貼!多項目共用基礎設施:https://segmentfault.com/a/1190000007301770
webpack多頁應用架構系列(十五):論前端如何在后端渲染開發模式下夾縫生存
webpack多頁應用架構系列(十六):善用瀏覽器緩存,該去則去,該留則留
本文首發于Array_Huang的技術博客——實用至上,非經作者同意,請勿轉載。
原文地址:https://segmentfault.com/a/1190000007159115
如果您對本系列文章感興趣,歡迎關注訂閱這里:https://segmentfault.com/blog/array_huang
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80657.html
摘要:徹底分離源文件目錄和生成文件目錄使用生成出來的頁面可以很安心地跟打包好的其它資源放到一起,相對于另起一個目錄專門存放頁面文件來說,整個文件目錄結構更加合理如何利用生成頁面生成頁面主要是通過來實現的,下面來介紹如何實現。 本文首發于Array_Huang的技術博客——實用至上,非經作者同意,請勿轉載。原文地址:https://segmentfault.com/a/119000000712...
摘要:回到純靜態頁面開發階段,讓頁面不需要后端渲染也能跑起來。改造開始本文著重介紹如何將靜態頁面改造成后端渲染需要的模板。總結在后端渲染的項目里使用多頁應用架構是絕對可行的,可不要給老頑固們嚇唬得又回到傳統前端架構了。 本文首發于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...
閱讀 1597·2023-04-25 14:12
閱讀 1070·2021-08-27 16:24
閱讀 2533·2019-08-30 15:44
閱讀 2913·2019-08-30 13:16
閱讀 1665·2019-08-29 14:10
閱讀 966·2019-08-29 13:54
閱讀 1296·2019-08-29 13:09
閱讀 1803·2019-08-26 18:37