在看這篇文章之前,需要你對構建多頁面應用有一定的基礎認識,如果沒有的話,可以先參考這篇文章webpack 構建多頁面應用。

多頁面應用是由一個個獨立的頁面組成。因此,細粒度的處理一個個單頁面是構建單頁面框架之後的一個重要實現。

因為所涵蓋的知識點較碎,所以就不按照頁面的位置結合組成元素來講,如:head, body, script等。這裡主要介紹head。因為script操作其實就是上一篇文章中已經介紹過的js操作,而body因為內容較多,需要另起一篇文章。

頁面的頭部

在上一篇文章中,我們講述了如何用html-webpack-plugin 生成一個html文件,其中使用了兩個配置項chunksfilename,前者指代頁面所要引入的js模塊,也就是我們常見的html頁面中的<script src="..."></script>形式,後者指代文件的名字。

那麼,在這一部分,要說的就是如何給不同的頁面配置生成不同的頁面<head>...</head>。我們都知道頁面頭部包括titlelink/stylemetascript 這四部分組成,尤其前三者居多。

當然,在web前端開發中js很強大,我們可以用js直接控制,在不同頁面的入口js文件中寫相應的js代碼。

這種方法雖然可行,但維護起來比較麻煩,當你修改的時候,你需要查找一個個頁面。

相對來講,使用html-webpack-plugin提供的配置項,會使你的開發工作變得簡單起來。

html-webpack-plugin 插件的配置項

title 選項可以為頁面指定名字,meta 選項可以為頁面指定html文檔關聯信息,如:描述,作者等,favicon 可以為頁面添加一個小圖標。 修改 webpack.config.js,代碼如下:

...
nnew HtmlWebapckPlugin({
/* inital page */
filename: index.html,
chunks: [index],
/* page head */
title: index,
meta: {
description: 這是首頁,
keywords: webpack, multi-page, 首頁,
author: https://github.com/lvzhenbang/
},
favicon: ./assets/19884132.jpg
})
...

這樣頭部常用的三個元素我們已經解決了兩個。那麼接下來就是解決link這個元素的。

註:有一個比較特殊的就是html頁面圖標<link rel="shortcut icon" href="19884132.jpg"> ,我們使用 html-webpack-plugin 插件的 favicon 選項已經解決。

linkstyle 部分的處理

這兩個元素常常被用來處理樣式。link 處理外部樣式,style 處理內聯樣式。

註:很多人會誤解,或曲解,這裡的樣式處理是這樣的:在定義的頁面入口文件,或者頁面入口文件引用的文件中,引入css文件,webapck會將這些樣式以內聯的形式或者link的形式注入到生成的html頁面中。

這樣我們的應用的目錄結構就變成如下這樣(本片文章使用如下的目錄結構,它也介紹了各個js文件對css文件的引用):

├── src

│ ├── common // 公用的模塊

│ │ ├── a.js // 引用了a.css│ │ ├── b.js // 引用了b.css│ │ ├── c.js // 引用了c.css│ │ ├── d.js├── assets // 靜態資源│ ├── 19224132.jpg // 用來做頁面圖標│ ├── css│ │ ├── a.css│ │ ├── b.css

│ │ ├── c.css

│ │ ├── main.css│ │ ├── abutus.css│ ├── uttils // 工具│ │ ├── load.js // 工具代碼load.js│ ├── index.js // 主模塊index.js (包含a.js, b.js, c.js, d.js),引用了main.css│ ├── aboutUs.js // 主模塊aboutus.js (包含a.js, b.js),引用了main.css, aboutus.css│ ├── contactUs.js // 主模塊contactus.js (包含a.js, c.js),引用了main.css├── webpack.config.js // css js 和圖片資源├── package.json

├── yarn.lock

處理為內聯樣式

如果是webpack3.x 推薦使用 css-loaderstyle-loaderextract-text-webpack-plugin;如果是webapck4.x推薦使用的 css-loader, mini-css-extract-plugin

webpack3.x與webapck4.x都一樣,修改webpack.config.js如下:

...
module: {
rules: [
{
test: /.css$/,
use: [
style-loader,
css-loader
]
}
]
},
...

因為mini-css-extract-plugin是專門為webpack4.x設計的,如果webapck3.x使用它會報錯。

處理為外部鏈接(link)

webpack3.x中webpack.config.js修改如下:

...
const ExtractTextPlugin = require(extract-text-webapck-plugin)
...
module: {
rules: [
{
test: /.css$/,
use: ExtractTextPlugin.extract({
fallback: style-loader,
use: css-loader
})
}
]
},
plugins: [
...
new ExtractTextPlugin({
filename: [name].css
})
]

webpack4.x中webpack.config.js修改如下:

...
const MiniCssExtractPlugin = require(mini-css-extract-plugin)
...
module: {
rules: [
{
test: /.css$/,
use: [
MiniCssExtractPlugin.loader,
css-loader
]
}
]
},
plugins: [
...
MiniCssExtractPlugin()
],

從js文件中分離出css文件,webpack3.x藉助於extract-text-webpack-plugin,webpack4.x藉助於mini-css-extract-plugin,前者給不同的css代碼塊命名需要在extract-text-webapck-plugin的示例中配置,它使用的是內置的CommonsChunkPlugin插件的拆分原則,後者不需要配置分離css代碼塊的名字選項,後者藉助於SplitsChunkPlugin插件的拆分原則。

所以,它們的分離形式與js代碼塊一致。

webpack3.x為每個入口點生成了一個css文件,並提取了它們的公共代碼生成了一個新的css文件;webapck4.x為每個入口生成了一個css文件,並提取並生成了這些文件相互之間的公共文件(它和前者不同,後者更精細化,只要是某一個或者幾個文件有公共代碼就提取出來,然後生成新的文件)。

為什麼將css文件和js文件分的這麼細?是因為這樣可以顯著的減小首次載入頁面時請求文件的大小(lazyload),但是這樣做會增加HTTP的請求次數。

在多頁面應用的過程中,有的人喜歡將所有的css放在一個或兩個文件中,而不是像本文中那樣為每個頁面生成一個css文件,包括它們之間的共用文件。但在多頁面應用中,這樣精密的細分也有其好處。

相對來說,使用CommonsChunkPlugin拆分的css模塊更合理些,而使用SplitsChunkPlugin拆分的css模塊,則過於細化。

至於如何取捨,還需要根據實際情況來定。

當然,這裡面還有一些小的問題需要優化,後期我會視情況來寫相應的文章描述。

源代碼

webpack3.x multi-page

lvzhenbang/webpack4.x-multi-page


推薦閱讀:
相关文章