3.6 為單頁應(yīng)用生成 HTML

3.6 為單頁應(yīng)用生成 HTML

問題一:單頁面常見問題彤避?

一個頁面常常有很多資源要加載

舉例說明

要求如下:

項目采用 ES6 語言加 React 框架焰扳。

給頁面加入Google Analytics,這部分代碼需要內(nèi)嵌進(jìn) HEAD 標(biāo)簽里去。

給頁面加入Disqus用戶評論禁熏,這部分代碼需要異步加載以提升首屏加載速度壤巷。

壓縮和分離 JavaScript 和 CSS 代碼邑彪,提升加載速度。

在開始前先來看看該應(yīng)用最終發(fā)布到線上的代碼:

<html><head><meta charset="UTF-8"><!--注入 Chunk app 依賴的 CSS--><style rel="stylesheet">h1{color:red}</style><!--內(nèi)嵌 google_analytics 中的 JavaScript 代碼--><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*newDate();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><!--導(dǎo)入 app 依賴的 JS--><script src="app_746f32b2.js"></script><!--Disqus 評論容器--><div id="disqus_thread"></div></body></html>

HTML 應(yīng)該是被壓縮過的胧华,這里為了方便大家閱讀而格式化了 HTML寄症,并且加入了注釋。

構(gòu)建出的目錄結(jié)構(gòu)為:

dist├── app_792b446e.js└── index.html

可以看到部分代碼被內(nèi)嵌進(jìn)了 HTML 的 HEAD 標(biāo)簽中矩动,部分文件的文件名稱被打上根據(jù)文件內(nèi)容算出的 Hash 值有巧,并且加載這些文件的 URL 地址也被正常的注入到了 HTML 中。 如果你還采用手寫index.html文件去完成以上要求悲没,這就會使工作變得復(fù)雜篮迎、易錯,項目難以維護(hù)示姿。 本節(jié)教你如何自動化的生成這個符合要求的index.html甜橱。

問題二:如何解決上述問題?

推薦一個用于方便的解決以上問題的 Webpack 插件web-webpack-plugin

下面具體介紹如何用它來解決上面的問題栈戳。

首先岂傲,修改 Webpack 配置為如下:

const path=require('path');const UglifyJsPlugin=require('webpack/lib/optimize/UglifyJsPlugin');const ExtractTextPlugin=require('extract-text-webpack-plugin');const DefinePlugin=require('webpack/lib/DefinePlugin');const{WebPlugin}=require('web-webpack-plugin');module.exports={entry:{app:'./main.js'// app 的 JavaScript 執(zhí)行入口文件},output:{filename:'[name]_[chunkhash:8].js',// 給輸出的文件名稱加上 Hash 值path:path.resolve(__dirname,'./dist'),},module:{rules:[{test:/\.js$/,use:['babel-loader'],// 排除 node_modules 目錄下的文件,// 該目錄下的文件都是采用的 ES5 語法子檀,沒必要再通過 Babel 去轉(zhuǎn)換exclude:path.resolve(__dirname,'node_modules'),},{test:/\.css$/,// 增加對 CSS 文件的支持// 提取出 Chunk 中的 CSS 代碼到單獨(dú)的文件中use:ExtractTextPlugin.extract({use:['css-loader?minimize']// 壓縮 CSS 代碼}),},]},plugins:[// 使用本文的主角 WebPlugin镊掖,一個 WebPlugin 對應(yīng)一個 HTML 文件newWebPlugin({template:'./template.html',// HTML 模版文件所在的文件路徑filename:'index.html'// 輸出的 HTML 的文件名稱}),newExtractTextPlugin({filename:`[name]_[contenthash:8].css`,// 給輸出的 CSS 文件名稱加上 Hash 值}),newDefinePlugin({// 定義 NODE_ENV 環(huán)境變量為 production,以去除源碼中只有開發(fā)時才需要的部分'process.env':{NODE_ENV:JSON.stringify('production')}}),// 壓縮輸出的 JavaScript 代碼newUglifyJsPlugin({// 最緊湊的輸出beautify:false,// 刪除所有的注釋comments:false,compress:{// 在UglifyJs刪除沒有用到的代碼時不輸出警告warnings:false,// 刪除所有的 `console` 語句褂痰,可以兼容ie瀏覽器drop_console:true,// 內(nèi)嵌定義了但是只用到一次的變量collapse_vars:true,// 提取出出現(xiàn)多次但是沒有定義成變量去引用的靜態(tài)值reduce_vars:true,}}),],};

以上配置中亩进,大多數(shù)都是按照前面已經(jīng)講過的內(nèi)容增加的配置,例如:

增加對 CSS 文件的支持缩歪,提取出 Chunk 中的 CSS 代碼到單獨(dú)的文件中归薛,壓縮 CSS 文件;

定義NODE_ENV環(huán)境變量為production,以去除源碼中只有開發(fā)時才需要的部分苟翻;

給輸出的文件名稱加上 Hash 值韵卤;

壓縮輸出的 JavaScript 代碼。

但最核心的部分在于plugins里的:

newWebPlugin({template:'./template.html',// HTML 模版文件所在的文件路徑filename:'index.html'// 輸出的 HTML 的文件名稱})

其中template: './template.html'所指的模版文件template.html的內(nèi)容是:

<html><head><meta charset="UTF-8"><!--注入 Chunk app 中的 CSS--><link rel="stylesheet"href="app?_inline"><!--注入 google_analytics 中的 JavaScript 代碼--><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><!--導(dǎo)入 Chunk app 中的 JS--><script src="app"></script><!--Disqus 評論容器--><div id="disqus_thread"></div></body></html>

該文件描述了哪些資源需要被以何種方式加入到輸出的 HTML 文件中崇猫。

以<link rel="stylesheet" href="app?_inline">為例沈条,按照正常引入 CSS 文件一樣的語法來引入 Webpack 生產(chǎn)的代碼。href屬性中的app?_inline可以分為兩部分,前面的app表示 CSS 代碼來自名叫app的 Chunk 中,后面的_inline表示這些代碼需要被內(nèi)嵌到這個標(biāo)簽所在的位置笔横。

同樣的<script src="./google_analytics.js?_inline"></script>表示 JavaScript 代碼來自相對于當(dāng)前模版文件template.html的本地文件./google_analytics.js嫌拣, 而且文件中的 JavaScript 代碼也需要被內(nèi)嵌到這個標(biāo)簽所在的位置。

也就是說資源鏈接 URL 字符串里問號前面的部分表示資源內(nèi)容來自哪里郁副,后面的 querystring 表示這些資源注入的方式。

除了_inline表示內(nèi)嵌外,還支持以下屬性:

_dist只有在生產(chǎn)環(huán)境下才引入該資源

_dev只有在開發(fā)環(huán)境下才引入該資源

_ie只有IE瀏覽器才需要引入的資源父款,通過[if IE]>resource<![endif]注釋實現(xiàn)

這些屬性之間可以搭配使用,互不沖突瞻凤。例如app?_inline&_dist表示只在生產(chǎn)環(huán)境下才引入該資源憨攒,并且需要內(nèi)嵌到 HTML 里去。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阀参,一起剝皮案震驚了整個濱河市肝集,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛛壳,老刑警劉巖杏瞻,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異衙荐,居然都是意外死亡捞挥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進(jìn)店門赫模,熙熙樓的掌柜王于貴愁眉苦臉地迎上來树肃,“玉大人,你說我怎么就攤上這事瀑罗⌒刈欤” “怎么了?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵斩祭,是天一觀的道長劣像。 經(jīng)常有香客問我,道長摧玫,這世上最難降的妖魔是什么耳奕? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任绑青,我火速辦了婚禮,結(jié)果婚禮上屋群,老公的妹妹穿的比我還像新娘闸婴。我一直安慰自己,他們只是感情好芍躏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布邪乍。 她就那樣靜靜地躺著,像睡著了一般对竣。 火紅的嫁衣襯著肌膚如雪庇楞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天否纬,我揣著相機(jī)與錄音吕晌,去河邊找鬼。 笑死临燃,一個胖子當(dāng)著我的面吹牛睛驳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谬俄,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼柏靶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了溃论?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤痘昌,失蹤者是張志新(化名)和其女友劉穎钥勋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辆苔,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡算灸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了驻啤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菲驴。...
    茶點(diǎn)故事閱讀 38,697評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖骑冗,靈堂內(nèi)的尸體忽然破棺而出赊瞬,到底是詐尸還是另有隱情,我是刑警寧澤贼涩,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布巧涧,位于F島的核電站,受9級特大地震影響遥倦,放射性物質(zhì)發(fā)生泄漏谤绳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缩筛。 院中可真熱鬧消略,春花似錦、人聲如沸瞎抛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婿失。三九已至钞艇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間豪硅,已是汗流浹背哩照。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留懒浮,地道東北人飘弧。 一個月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像砚著,于是被迫代替她去往敵國和親次伶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評論 2 350

推薦閱讀更多精彩內(nèi)容