摘要:徹底分離源文件目錄和生成文件目錄使用生成出來的頁面可以很安心地跟打包好的其它資源放到一起,相對于另起一個目錄專門存放頁面文件來說,整個文件目錄結(jié)構(gòu)更加合理如何利用生成頁面生成頁面主要是通過來實現(xiàn)的,下面來介紹如何實現(xiàn)。
本文首發(fā)于Array_Huang的技術(shù)博客——實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。為什么要用webpack來生成HTML頁面
原文地址:https://segmentfault.com/a/1190000007126268
如果您對本系列文章感興趣,歡迎關(guān)注訂閱這里:https://segmentfault.com/blog/array_huang
按照我們前面的十一篇的內(nèi)容來看,自己寫一個HTML頁面,然后在上面加載webpack打包的js或其它類型的資源,感覺不也用得好好的么?
是的沒錯,不用webpack用requireJs其實也可以啊,甚至于,傳統(tǒng)那種人工管理模塊依賴的做法也沒有什么問題嘛。
但既然你都已經(jīng)看到這一篇了,想必早已和我一樣,追求著以下這幾點吧:
更懶,能自動化的事情絕不做第二遍。
更放心,調(diào)通的代碼比人靠譜,更不容易出錯。
代碼潔癖,什么東西該放哪,一點都不能含糊,混在一起我就要死了。
那么,廢話不多說,下面就來說說使用webpack生成HTML頁面有哪些好處吧。
對多個頁面共有的部分實現(xiàn)復(fù)用在實際項目的開發(fā)過程中,我們會發(fā)現(xiàn),雖然一個項目里會有很多個頁面,但這些頁面總有那么幾個部分是相同或相似的,尤其是頁頭頁尾,基本上是完全一致的。那我們要怎么處理這些共有的部分呢?
復(fù)制粘貼流不就是復(fù)制粘貼的事嘛?寫好一份完整的HTML頁面,做下個頁面的時候,直接copy一份文件,然后直接在copy的文件上進行修改不就好了嗎?
誰是這么想這么做的,放學(xué)留下來,我保證不打死你!我曾經(jīng)接受過這么一套系統(tǒng),頂部欄菜單想加點東西,就要每個頁面都改一遍,可維護性爛到爆啊。
Iframe流Iframe流常見于管理后臺類項目,可維護性O(shè)K,就是缺陷比較多,比如說:
點擊某個菜單,頁面是加載出來了但是瀏覽器地址欄上的URL沒變,刷新的話又回到首頁了。
搜索引擎收錄完蛋,前臺項目一般不能用Iframe來布局。
沒有逼格,Low爆了,這是最重要的一點(大誤)。
SPA流最近這幾年,隨著移動互聯(lián)網(wǎng)的興起,SPA也變得非常常見了。不過SPA的局限性也非常大,比如搜索引擎無法收錄,但我個人最在意的,是它太復(fù)雜了,尤其是一些本來業(yè)務(wù)邏輯就多的系統(tǒng),很容易懵圈。
后端模板渲染這倒真是一個辦法,只是,需要后端的配合,利用后端代碼把頁面的各個部分給拼合在一起,所以這方法對前端起家的程序員還是有點門檻的。
利用前端模板引擎生成HTML頁面所謂“用webpack生成HTML頁面”,其實也并不是webpack起的核心作用,實際上靠的還是前端的模板引擎將頁面的各個部分給拼合在一起來達到公共區(qū)域的復(fù)用。webpack更多的是組織統(tǒng)籌整個生成HTML頁面的過程,并提供更大的控制力。最終,webpack生成的到底是完整的頁面,還是供后端渲染的模板,就全看你自己把控了,非常靈活,外人甚至察覺不出來這到底是你自己寫的還是代碼統(tǒng)一生成的。
處理資源的動態(tài)路徑如果你想用在文件名上加hash的方法作為緩存方案的話,那么用webpack生成HTML頁面就成為你唯一的選擇了,因為隨著文件的變動,它的hash也會變化,那么整個文件名都會改變,你總不能在每次編譯后都手動修改加載路徑吧?還是放心交給webpack吧。
自動加載webpack生成的css、less如果你使用webpack來生成HTML頁面,那么,你可以配置好每個頁面加載的chunk(webpack打包后生成的js文件),生成出來的頁面會自動用來加載這些chunk,路徑什么的你都不用管了哈(當(dāng)然前提是你配置好了output.publicPath)。另外,用extract-text-webpack-plugin打包好的css文件,webpack也會幫你自動添加到里,相當(dāng)方便。
徹底分離源文件目錄和生成文件目錄使用webpack生成出來的HTML頁面可以很安心地跟webpack打包好的其它資源放到一起,相對于另起一個目錄專門存放HTML頁面文件來說,整個文件目錄結(jié)構(gòu)更加合理:
build - index - index - entry.js - page.html - login - entry.js - page.html - styles.css如何利用webpack生成HTML頁面
webpack生成HTML頁面主要是通過html-webpack-plugin來實現(xiàn)的,下面來介紹如何實現(xiàn)。
html-webpack-plugin的配置項每一個html-webpack-plugin的對象實例都只針對/生成一個頁面,因此,我們做多頁應(yīng)用的話,就要配置多個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, // 為靜態(tài)資源生成hash值 minify: true, xhtml: true, }); configPlugins.push(htmlPlugin); });
pageArr實際上是各個chunk的name,由于我在output.filename設(shè)置的是"[name]/entry.js",因此也起到構(gòu)建文件目錄結(jié)構(gòu)的效果(具體請看這里),附上pageArr的定義:
module.exports = [ "index/login", "index/index", "alert/index", "user/edit-password", "user/modify-info", ];
html-webpack-plugin的配置項真不少,這里僅列出多頁應(yīng)用常用到的配置:
filename,生成的網(wǎng)頁HTML文件的文件名,注意可以利用/來控制文件目錄結(jié)構(gòu)的,其最終生成的路徑,是基于webpack配置中的output.path的。
template,指定一個基于某種模板引擎語法的模板文件,html-webpack-plugin默認(rèn)支持ejs格式的模板文件,如果你想使用其它格式的模板文件,那么需要在webpack配置里設(shè)置好相應(yīng)的loader,比如handlebars-loader啊html-loader啊之類的。如果不指定這個參數(shù),html-webpack-plugin會使用一份默認(rèn)的ejs模板進行渲染。如果你做的是簡單的SPA應(yīng)用,那么這個參數(shù)不指定也行,但對于多頁應(yīng)用來說,我們就依賴模板引擎給我們拼裝頁面了,所以這個參數(shù)非常重要。
inject,指示把加載js文件用的插入到哪里,默認(rèn)是插到的末端,如果設(shè)置為"head",則把插入到里。
minify,生成壓縮后的HTML代碼。
hash,在由html-webpack-plugin負(fù)責(zé)加載的js/css文件的網(wǎng)址末尾加個URL參數(shù),此URL參數(shù)的值是代表本次編譯的一個hash值,每次編譯后該hash值都會變化,屬于緩存解決方案。
chunks,以數(shù)組的形式指定由html-webpack-plugin負(fù)責(zé)加載的chunk文件(打包后生成的js文件),不指定的話就會加載所有的chunk。
生成一個簡單的頁面下面提供一份供生成簡單頁面(之所以說簡單,是因為不指定頁面模板,僅用默認(rèn)模板)的配置:
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,內(nèi)容如下所示:
簡單頁面
由于沒有指定模板文件,因此生成出來的HTML文件僅有最基本的HTML結(jié)構(gòu),并不帶實質(zhì)內(nèi)容??梢钥闯?,這更適合React這種把HTML藏js里的方案。
利用模板引擎獲取更大的控制力接下來,我們演示如何通過制定模板文件來生成HTML的內(nèi)容,由于html-webpack-plugin原生支持ejs模板,因此這里也以ejs作為演示對象:
<%= htmlWebpackPlugin.options.title %> 這是一個用html-webpack-plugin生成的HTML頁面
大家仔細(xì)瞧好了
"html-webpack-plugin"的配置里也要指定template參數(shù):
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頁面
大家仔細(xì)瞧好了
到這里,我們已經(jīng)可以控制整個HTML文件的內(nèi)容了,那么生成后端渲染所需的模板也就不是什么難事了,以PHP的模板引擎smarty為例:
處理資源的動態(tài)路徑<%= htmlWebpackPlugin.options.title %> 這是一個用html-webpack-plugin生成的HTML頁面
大家仔細(xì)瞧好了
這是用smarty生成的內(nèi)容:{$articleContent}
接下來在上面例子的基礎(chǔ)上,我們演示如何處理資源的動態(tài)路徑:
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,更適合圖片,可以將較小的圖片轉(zhuǎn)成base64,減少http請求 // 如下配置,將小于8192byte的圖片轉(zhuǎn)成base64碼 test: /.(png|jpg|gif)$/, loader: "url?limit=8192&name=./static/img/[hash].[ext]", }, }, };
<%= htmlWebpackPlugin.options.title %> 這是一個用html-webpack-plugin生成的HTML頁面
大家仔細(xì)瞧好了
我們改動了什么呢?
參數(shù)output.filename里,我們添了個變量[chunkhash],這個變量的值會隨chunk內(nèi)容的變化而變化,那么,這個chunk文件最終的路徑就會是一個動態(tài)路徑了。
我們在頁面上添加了一個
這是一個用html-webpack-plugin生成的HTML頁面
大家仔細(xì)瞧好了
顯然,html-webpack-plugin成功地將chunk加載了,又處理好了轉(zhuǎn)化為DataUrl格式的圖片,這一切,都是我們手工難以完成的事情。
還未結(jié)束至此,我們實現(xiàn)了使用webpack生成HTML頁面并嘗到了它所帶來的甜頭,但我們尚未實現(xiàn)“對多個頁面共有的部分實現(xiàn)復(fù)用”,下一篇《webpack多頁應(yīng)用架構(gòu)系列(十三):構(gòu)建一個簡單的模板布局系統(tǒng)》我們就來介紹這部分的內(nèi)容。
示例代碼諸位看本系列文章,搭配我在Github上的腳手架項目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed)。
附系列文章目錄(同步更新)webpack多頁應(yīng)用架構(gòu)系列(一):一步一步解決架構(gòu)痛點:https://segmentfault.com/a/1190000006843916
webpack多頁應(yīng)用架構(gòu)系列(二):webpack配置常用部分有哪些?:https://segmentfault.com/a/1190000006863968
webpack多頁應(yīng)用架構(gòu)系列(三):怎么打包公共代碼才能避免重復(fù)?:https://segmentfault.com/a/1190000006871991
webpack多頁應(yīng)用架構(gòu)系列(四):老式j(luò)Query插件還不能丟,怎么兼容?:https://segmentfault.com/a/1190000006887523
webpack多頁應(yīng)用架構(gòu)系列(五):聽說webpack連less/css也能打包?:https://segmentfault.com/a/1190000006897458
webpack多頁應(yīng)用架構(gòu)系列(六):聽說webpack連圖片和字體也能打包?:https://segmentfault.com/a/1190000006907701
webpack多頁應(yīng)用架構(gòu)系列(七):開發(fā)環(huán)境、生產(chǎn)環(huán)境傻傻分不清楚?:https://segmentfault.com/a/1190000006952432
webpack多頁應(yīng)用架構(gòu)系列(八):教練我要寫ES6!webpack怎么整合Babel?:https://segmentfault.com/a/1190000006992218
webpack多頁應(yīng)用架構(gòu)系列(九):總有刁民想害朕!ESLint為你阻擊垃圾代碼:https://segmentfault.com/a/1190000007030775
webpack多頁應(yīng)用架構(gòu)系列(十):如何打造一個自定義的bootstrap:https://segmentfault.com/a/1190000007043716
webpack多頁應(yīng)用架構(gòu)系列(十一):預(yù)打包Dll,實現(xiàn)webpack音速編譯:https://segmentfault.com/a/1190000007104372
webpack多頁應(yīng)用架構(gòu)系列(十二):利用webpack生成HTML普通網(wǎng)頁&頁面模板:https://segmentfault.com/a/1190000007126268
webpack多頁應(yīng)用架構(gòu)系列(十三):構(gòu)建一個簡單的模板布局系統(tǒng):https://segmentfault.com/a/1190000007159115
webpack多頁應(yīng)用架構(gòu)系列(十四):No復(fù)制粘貼!多項目共用基礎(chǔ)設(shè)施
webpack多頁應(yīng)用架構(gòu)系列(十五):論前端如何在后端渲染開發(fā)模式下夾縫生存
webpack多頁應(yīng)用架構(gòu)系列(十六):善用瀏覽器緩存,該去則去,該留則留
本文首發(fā)于Array_Huang的技術(shù)博客——實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。
原文地址:https://segmentfault.com/a/1190000007126268
如果您對本系列文章感興趣,歡迎關(guān)注訂閱這里:https://segmentfault.com/blog/array_huang
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/80638.html
摘要:原文地址如果您對本系列文章感興趣,歡迎關(guān)注訂閱這里前言上文多頁應(yīng)用架構(gòu)系列十二利用生成普通網(wǎng)頁頁面模板我們基本上已經(jīng)搞清楚如何利用來生成普通網(wǎng)頁頁面模板,本文將以我的腳手架項目介紹如何在這基礎(chǔ)上搭建一套簡單的模板布局系統(tǒng)。 本文首發(fā)于Array_Huang的技術(shù)博客——實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/1190000007...
摘要:回到純靜態(tài)頁面開發(fā)階段,讓頁面不需要后端渲染也能跑起來。改造開始本文著重介紹如何將靜態(tài)頁面改造成后端渲染需要的模板??偨Y(jié)在后端渲染的項目里使用多頁應(yīng)用架構(gòu)是絕對可行的,可不要給老頑固們嚇唬得又回到傳統(tǒng)前端架構(gòu)了。 本文首發(fā)于Array_Huang的技術(shù)博客——實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/119000000820338...
摘要:回到純靜態(tài)頁面開發(fā)階段,讓頁面不需要后端渲染也能跑起來。改造開始本文著重介紹如何將靜態(tài)頁面改造成后端渲染需要的模板??偨Y(jié)在后端渲染的項目里使用多頁應(yīng)用架構(gòu)是絕對可行的,可不要給老頑固們嚇唬得又回到傳統(tǒng)前端架構(gòu)了。 本文首發(fā)于Array_Huang的技術(shù)博客——實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/119000000820338...
摘要:本文首發(fā)于的技術(shù)博客實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。原文地址如果您對本系列文章感興趣,歡迎關(guān)注訂閱這里這系列文章講什么本系列文章主要介紹如何用這一當(dāng)前流行的構(gòu)建工具來設(shè)計一個多頁應(yīng)用的架構(gòu)。 本文首發(fā)于Array_Huang的技術(shù)博客——實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/1190000006843916如果您對本系列文章...
摘要:在上一篇文章多頁應(yīng)用架構(gòu)系列二配置常用部分有哪些中,我介紹了如何配置多頁應(yīng)用的入口,然而,如果僅僅如此操作,帶來的后果就是,打包生成出來的每一個入口文件都會完整包含所有代碼。的初始化常用參數(shù)有哪些,給這個包含公共代碼的命個名唯一標(biāo)識。 本文首發(fā)于Array_Huang的技術(shù)博客——實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/1190...
閱讀 3333·2021-10-11 10:59
閱讀 2909·2021-10-11 10:58
閱讀 2305·2021-09-04 16:45
閱讀 2791·2019-08-30 15:44
閱讀 729·2019-08-30 15:44
閱讀 3253·2019-08-30 10:51
閱讀 1656·2019-08-29 18:46
閱讀 2812·2019-08-29 13:57