webpack學習筆記(三)使用ejs語法建立模版+提取chunk
本章描述的主要功能
- 引入jq模組
- expose-loader 簡單介紹
- 提供公共模組
- tpl模版的介紹(使用ejs語法)
引入jq模組
各種基於mvc、mvvm框架的出現,單純的jq已不適合這樣的開發了,但如果是不使用框架的專案,使用jq總比寫原生好吧0.0
既然都使用了webpack來開發,就不要使用<script>
來引入
npm i -D jquery
然後回到index.js
檔案,通過require('jquery')
引入jquery
,順便在index.html
裡面隨便寫點什麼(前面兩章寫的已刪除)
/* index.js */ import '../style/index.css'; import '../style/less.less'; import '../style/scss.scss'; import '../style/sass.sass'; const $ = require('jquery'); console.log($); console.log($('#J-demo1').html()); $('#J-btn1').click(function () { alert('hello'); }); /* index.html */ <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>webpack學習筆記(三)</title> </head> <body> <div id="J-demo1">引入jquery</div> <button id="J-btn1">點我呀</button> </body> </html>
npm start
執行可看到相關jquery
的功能都已實現,$
也被打印出來,但是你在控制檯列印$
jQuery
就會發現$
並不是上述列印的$
,jQuery
也會報錯jQuery is not defined
,說明我們使用的$
jQuery
不是全域性屬性
expose-loader
顧名思義,解析某個模組,然後暴露出去,如果不想使用全域性屬性那也就按照上述那樣吧,但若將其設定為全域性需要使用expose-loader
來解析相應的模組,然後在webpack.js
中新增其配
npm i -D expose-loader
/* webpack.js */ { // 通過require('jquery')來引入 test: require.resolve('jquery'), use: [ { loader: 'expose-loader', // 暴露出去的全域性變數的名稱 隨便你自定義 options: 'jQuery' }, { // 同上 loader: 'expose-loader', options: '$' } ] }
跑起來,控制檯列印$
jQuery
,它們已屬於全域性變數,如果上述程式碼中的options
值你自定義了的話,列印你的自定義名稱,其就是jQuery
方法,之後你可以在以index.js
作為入口檔案的任意.js
檔案裡面呼叫$
jQuery
提供公共模組(也可理解為公共chunk)
在單頁面開發中是否提取公共模組意義不大,但在多頁面運用中就需要提取了,上一章中我們建立了index.html
demo1.html
demo2.html
三個頁面,也建立了同名的三個入口js檔案,就拿上述的jQuery中,如果三個頁面都需要使用呢?我們在三個入口檔案裡面引入jquery
,檢視打包結果,我們就寫了幾行程式碼,由於引入了jquery
CommonsChunkPlugin
使用CommonsChunkPlugin
外掛來提取公共模組,webpack
中已集成了改外掛,只需要呼叫即可,我們在webpack.prod.js
裡面使用該外掛
/* webpack.prod.js */
...
new webpack.optimize.CommonsChunkPlugin({
// 提取出公共模組的chunkName,在html-webpack-plugin外掛使用該chunkName
name: 'commons',
// 生成的公共模組檔案路徑和檔名 [name]是其chunkName 即commons
filename: 'static/js/[name].[hash].js',
// 模組被引用的最小次數,低於該次數將不會被提取
minChunks: 3
})
...
執行結果
但是目前只是提取出來,html裡面並沒有通過<script>
來引入,我們已經知道公共模組其chunkName為commons,這就好辦啦,修改webpack.js
中html-webpack-plugin
配置即可,然後打包執行,html中也就引入了公共模組
/* webpack.js */
...
config.pageNames.forEach((page) => {
const htmlPlugin = new HtmlWebpackPlugin({
filename: `${page}.html`,
template: path.join(__dirname, `../src/page/${page}.html`),
// chunkName集合,page為當前入口檔案chunkName commons為公共模組chunkName
chunks: [page, 'commons']
});
HtmlPlugins.push(htmlPlugin);
Entries[page] = path.join(__dirname, `../src/script/${page}.js`);
});
...
目前這種做法有一個缺點,那就是引用次數大於等於3的檔案都會被打包進入公共模組,也就是說A頁面其多個(大於等於3)子項模組引入了某個tool.js
模組,然而B頁面沒有使用這個模組,tool.js
這個模組也依然會被打包進入公共模組,然後被A、B兩個頁面載入,要解決這個問題就需要程式碼分割、按需載入,我們後續再提
tpl模版(使用ejs語法)
前提條件—瞭解ejs
語法ejs傳送門
在開發過程中肯定會遇到一些公用,或者使用資料來渲染的模組,我們可以將這些模組製作成模版,傳入指定引數來渲染,首先先下載 ejs-loader
,用它來解析我們的模版,然後我們在src
下面建立一個tpl
資料夾並建立一個頭部模版
npm i -D ejs-loader
模版的路口同樣是.js
檔案,通過其來引入樣式或者html檔案(這裡建立不能起名叫.html,因為之前已經使用過對應的loader,否則會出錯),你可以將其命名為.ejs
.tpl
.tem
都行,只需要字尾不衝突即可,我們在外部引入該模版之後列印一下這個tpl
,這裡需要先在webpack.js
裡面加入對.tpl
檔案的解析,使用ejs-loader
/* webpack.js */
...
{
// 對模版檔案使用loader
test: /\.tpl$/,
use: 'ejs-loader'
}
...
控制檯看結果
可以看到我們的通過import
引入的tpl
其實是一個函式,返回值是字串型別的html
語句,我們可以將返回值通過節點操作掛到DOM樹上,並且我們也可以看到該函式需要傳入一個物件引數tpl({namex: xxx, sex: xx})
,如果是富文字的話也是支援傳入,並不需要<%- xxx %>
的寫法,如下圖栗子
使用ejs
的語法我們就能自由的建立字串模版,這樣就不再需要字串拼接啦~
tpl模版的基礎原理就是這樣,剩下的就自行慢慢進行各種騷操作吧,你可以把模版當作一個沙盒,資料都由外部傳入,也可以反過來行之,怎麼方便怎麼來就好~
到目前為止,算上前面兩章,基礎的webpack
配置結構已經搞定,接下來加上一點點瓦片,讓其能住得下人
自定義埠號和區域網訪問
該項功能只適合開發環境,並且是和webpack-dev-server
配套的,只需要在wepback.js
加入devServer
屬性並傳入相應的值,我們在config
中定義埠號和區域網IP即可
/* config.js */
module.exports = {
...
// 開發
dev: {
sourceMap: true,
extract: false,
// 區域網IP
host: '192.168.11.105',
// 埠號
port: '2018'
}
...
};
/* webpack.js */
module.exports = {
...
devServer: {
host: config.dev.host,
port: config.dev.port
}
...
}
顯示打包進度
webpak
提供了現實百分比進度的命令--progress
,我們只需要在package.json
修改即可
/* package.json */
"scripts": {
"start": "nodemon --watch build/ --exec \"webpack-dev-server --progress --config build/webpack.dev.js\"",
"build": "webpack --progress --config build/webpack.prod.js"
}
目前我也就只完成到這裡,剩下的程式碼分割,按需載入,HMR等功能都也還在構建中,之後的筆記再提~