透過 webpack 管理所有的 .html 與所有載入 .js 的部份。
安裝 html-webpack-plugin
1 2 3 | npm install --save-dev html-webpack-plugin // 載入會是 webpack 5 版,需使用下面指令 npm i --save-dev html-webpack-plugin@4 // webpack 4 版專用 npm i --save-dev html-webpack-plugin@3.2.0 // 課程使用版本 |
設定 html-webpack-plugin
調整專案資料夾結構
調整專案資料夾結構,透過 webpack 自動生成 .html,而生成前需要一個模版來使用。
在 src/ 下方在多開一個資料夾命名為 html,對應資料夾分別有 CSS、SCSS、js,而 html 也有自已獨立的資料夾,接著將原本外面的 index.html 移入到 src/html 資料夾中,移入的 index.html 檔後修改檔名為 template.html 就是模版的部份。
index.html 裡只要單純的基本結構就好,連 <script src="./js/index.js"></script> 也不用留,內容約如下。
1 2 3 4 5 6 7 8 9 | <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> </body> </html> |
設定 webpack.config.js 設定檔
在 webpack.config.js 設定檔加入下面內容,將先前安裝的 html-webpack-plugin 引入。
1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); |
調用 html-webpack-plugin,在 plugins: [] 的部份以加入新實體的方式 new HtmlWebpackPlugin() 裡面會是個 {} 物件來設定,設定如下。
1 2 3 4 5 6 7 8 9 | new HtmlWebpackPlugin({ title: 'Webpack前端自動化開發', filename: 'index.html', template: 'html/template.html', viewport: 'width=device-width, initial-scale=1.0', // 範例原為 'width=640, user-scalable=no', description: 'Webpack前端自動化開發,讓你熟悉現代前端工程師開發的方法', Keywords: 'Webpack前端自動化開發、前端、工程師、線上教學、教學範例', chunks: ['index'], }), |
以下為設定說明
- title::為產生 .html 檔中的 <head><title></title></head> 內容。
- filename::將模版透過設定產生的 x.html 的 x 名稱。
- template::模版的來源,指向專案資料夾路徑 html/template.html 檔。
- viewport::設定後對應的是 <head> 內的 content <meta name="viewport" content="width=device-width, initial-scale=1.0">
- description::設定的是 <head> 內的描述標籤 (Meta Description)。
- Keywords::設定的是 <head> 內的關鍵字。
- chunks: ['index'],:注入點是 index.js 檔,所以就是在這個設定檔中指定載入 index.js 檔,設定所載入的部份會是 <script src="./js/index.js"></script>
注入點 index.js 引入 file-loader 的 .html 檔,執行 webpack 發生錯誤修正
使用指令 npm run dev 開啟 webpack-dev-server 開啟頁面,但此時瀏覽器會出現錯誤提示,內容如下。
1 2 3 | ERROR in ./js/index.js Module not found: Error: Can't resolve 'index.html' in 'XXXX/webpack/src/js' @ ./js/index.js |
這個問題主要是使用了 html-webpack-plugin 之後,就不需要在由 index.js 裡在引入 import 'index.html'; 這支檔案進入 JS 的注入點,此時的 .html 檔已由 html-webpack-plugin 產生。
另外在 webpack.config.js 裡的 module: { rules: [] } 下的 test: /\.html$/, 的 file-loader 讀取 .html 的設定就可註解或是刪除。
重新執行指令 npm run dev 運行 webpack 後,就可以見到在注入點 index.js 下的二個 console.log() 在瀏覽器已成功執行。
html-webpack-plugin 將注入點的 .js 檔,不經由模版檔的設定,動自產生在編譯後頁面上
接著透過檢視原始碼,開啟 html 頁面內的內容查看,可以見到在模版裡原本刪除的 <script src="./js/index.js"></script> 程式碼,又透過 html-webpack-plugin 加入頁面中。
<script src="./js/index.js"></script> 程式碼,是透過 new HtmlWebpackPlugin({}) 裡面的 chunks: ['index'], 的設定所產生,主要是針對設定注入點 entery: [index: index.js] 設定由指向 index.js 帶入頁面中,這樣的方式也就不用在手動載入模版中注入點中的 .js 檔。
由 html-webpack-plugin 所帶入的的設定,以參數方式加入 html haed 模版進行編譯
但此時的 <haed></haed> 裡相關的 <meta> 與 <title> 的部份,也翾沒有透過 webpack.config.js 裡的 new HtmlWebpackPlugin({}) 設定呈現。
目前透過 webpack 把 html 模版帶入,並沒有將模版中設定的動態化內容導入模版中,此時需要將設定的部份以參數的形式帶入模版中。
撰寫方式如下
1 | <%= htmlWebpackPlugin.options.[参數] %> |
主要是由 [参數] 修改,以 webpack.config.js 裡的 new HtmlWebpackPlugin({}) 的設定將物件下的屬性以參數帶入模版車,下面是以 <title> 為例
1 | <title><%= htmlWebpackPlugin.options.title %></title> |
webpack.config.js 裡的 new HtmlWebpackPlugin({}) 的設定,對應 template.html 檔的內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="<%= htmlWebpackPlugin.options.viewport %>" /> <meta name="description" content="<%= htmlWebpackPlugin.options.description %>"> <meta name="keywords" content="<%= htmlWebpackPlugin.options.Keywords %>"> <title><%= htmlWebpackPlugin.options.title %></title> <link rel="shortcut icon" href="#" /> </head> <body></body> </html> |
修改完 template.html 檔後,透過 webpack 編譯結果,前往 dest/index.html 查看結果如下
1 | <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="description" content="Webpack前端自動化開發,讓你熟悉現代前端工程師開發的方法"><meta name="keywords" content="Webpack前端自動化開發、前端、工程師、線上教學、教學範例"><title>Webpack前端自動化開發</title><link rel="shortcut icon" href="#"/></head><body><script src="./js/index.js?60873a27"></script></body></html> |
載入複數的 html 設定
在 plugins: [] 的陣列中,將 HtmlWebpackPlugin() 再多透過一個 new 實體的方式,再多增加筆數上去,在進行裡面物件屬性的設定。
以加入 about.html 與注入點方鋨為例,新增修改內容如下
不同的 .html 檔中的 .js 是不一樣的,就可以透過 chunks: 屬性另外在設定,透過不同注入點設定就可用來區份引入注入點 .js 的部份。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | new HtmlWebpackPlugin({ title: 'Webpack前端自動化開發', filename: 'index.html', template: 'html/template.html', viewport: 'width=device-width, initial-scale=1.0', // 'width=640, user-scalable=no', description: 'Webpack前端自動化開發,讓你熟悉現代前端工程師開發的方法', Keywords: 'Webpack前端自動化開發、前端、工程師、線上教學、教學範例', chunks: ['index'], }), new HtmlWebpackPlugin({ title: 'About', filename: 'about.html', template: 'html/template.html', viewport: 'width=device-width, initial-scale=1.0', // 'width=640, user-scalable=no', description: 'Webpack前端自動化開發,讓你熟悉現代前端工程師開發的方法', Keywords: 'Webpack前端自動化開發、前端、工程師、線上教學、教學範例', chunks: ['about'], }), |
瀏覽器前往 localhost:3000/about.html 頁面時,開啟檢視原始碼查看,以 <title> 與下方的 <script> 的部份,都是以 about.html 對應到 about.js 注入點中,結果也不同於 index.html。
透過 npm run deploy 查看產生的 .html 檔案,也分別有 about.html 與 index.html 二支二個頁面。
output 編輯 .js 路徑,透過 ?[hash:8] 產生 8 碼亂數,讓每次編譯時的 .js 都產生不同的編號,讓 .js 不取用快取內原舊有 .js
透過編譯後的 <script src=""></script> 的方式,在連結的網址後方帶上 ?[hash:8],新的網址任定是新的頁面,就不會在取用瀏覽器內的快取。
額外處理的方式
透過框架來開發使用 template 模版與指定 JS 注入點
透過框架來開發,就可直接單以一支 template.html 來管理開發,主要是由 chunks: [} 指定注入點 .js 檔的方式來注入使用。
各自獨立頁面只透過 HtmlWebpackPlugin() 處理 haed 與注入點 .js 的設定來管理
但如果只是前端以特同頁面方式,而 content 的內容就直接寫入在沒管理到的地方,主要只由 plugins: [] 裡的 new HtmlWebpackPlugin() 方式,來管理 <head> 裡的 <meta> 設定與注入點 .js 引前的部份,而專案資料夾下就直接在 src/html 的資料夾下,分別一特定頁面的 .html 名稱開出特定頁面。
而頁面部份各自在 <body> 下使用各自的內容,而其他的 <head> 內的部份都一樣。
最後透過 webpack.config.js 檔,透過 plugins: [] 裡的 new HtmlWebpackPlugin() 方式,自已獨立引用不同的注入點。
這樣會透過各自獨立出來的模版檔,在沒有引用框架的狀態來處理。
但如果直接使用框架,就可以直接以 template.html 單一個模版檔處理,如果要以傳統方式各自處理頁面中的內容,就只有各自處理各自頁面下的內容,但好處是注入點 .js 可以透過 new HtmlWebpackPlugin() 方式管理,不用在一支支加入引用,透過手動自行加入各自頁面,有可能會處理時忘記加入。