1. 程式人生 > >webpack學習筆記(三)使用ejs語法建立模版+提取chunk

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.jshtml-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等功能都也還在構建中,之後的筆記再提~