ebpack實戰:手把手教你輕松打包多頁面Web應用,實現高效優化與部署
---
在現代Web開發中,Webpack作為一款強大的靜態模塊打包工具,以其靈活的配置能力和豐富的生態贏得了開發者們的青睞。尤其在構建多頁面Web應用時,Webpack可以幫助我們有效地管理和優化資源,提升加載速度和運行效率。本文將深入淺出地解析如何使用Webpack打包多頁面應用,并結合實戰案例演示其優化與部署過程。
2.1 Webpack核心概念
-
入口(entry)
javascript
module.exports={
entry: {
page1: './src/page1.js',
page2: './src/page2.js',
},
};
Webpack從指定的`entry`開始遞歸地找出項目的所有依賴文件。
2.2 輸出(output)
javascript
module.exports={
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js',
},
};
定義Webpack打包后文件的輸出路徑和文件名。
2.3 Loader與Plugin
Loader用于轉換某些類型的模塊,如處理CSS、圖片等非JavaScript文件;Plugin則負責更廣泛的構建步驟,如壓縮代碼、提取公共模塊等。
3.1 配置多個入口
javascript
// ...
entry: {
page1: './src/pages/page1/index.js',
page2: './src/pages/page2/index.js',
},
// ...
針對每個頁面創建一個入口點,Webpack會分別生成對應的打包文件。
3.2 HTMLWebpackPlugin動態生成HTML
javascript
const HtmlWebpackPlugin=require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
template: './src/pages/page1/index.html',
filename: 'page1.html',
chunks: ['page1'],
}),
// 同理配置page2...
],
4.1 代碼分割與懶加載
javascript
optimization: {
splitChunks: {
chunks: 'all',
},
},
借助`import()`語法或`SplitChunksPlugin`進行代碼分割,實現按需加載和延遲加載。
4.2 使用Tree Shaking去除無用代碼
javascript
module.exports={
mode: 'production', // 開啟生產模式,自動優化代碼
// ...
};
開啟`mode`為`production`,Webpack會自動啟用Tree Shaking功能。
5.1 打包上線
通過`webpack --mode production`命令進行生產環境下的打包,生成最小化、高度優化的代碼。
5.2 靜態資源CDN部署
javascript
output: {
publicPath: 'https://cdn.example.com/assets/', // CDN路徑
// ...
},
利用`publicPath`設置靜態資源的引用地址,便于CDN部署。
通過本篇實戰教程,我們不僅了解了如何運用Webpack對多頁面Web應用進行打包,還學習了相關的優化方法以及部署策略。Webpack的世界遠不止于此,持續關注并深入探究Webpack的更多高級特性,定能助你在Web開發領域更上一層樓。
---
以上內容僅為大綱式示例,實際創作時應詳細展開每個部分,配合具體實例和操作步驟,以達到6000字左右的篇幅要求,并確保讀者能夠跟隨教程一步步完成實際操作。同時,為了保持文章時效性和實用性,建議引入最新版本Webpack的相關配置和技術要點。
篇我們主要介紹Webpack打包Javascript。當然,除了可以打包Javascript之外,webpack還可以打包html。但是這不是我們本篇的重點。我們可以參考 Webpack HTML 打包介紹——跡憶客
現在讓我們擴展我們的項目——webpack-example,并為 entry 和 output 屬性指定自定義名稱。 在 webpack.config.js 中,我們在 plugins 屬性之前添加以下內容:
entry: {
main: path.resolve(__dirname, './src/app.js'),
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'deploy')
},
完整代碼如下所示
webpack.config.js 文件
const HtmlWebpackPlugin=require("html-webpack-plugin");
const path=require('path');
module.exports={
entry: {
main: path.resolve(__dirname, './src/app.js'),
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'deploy')
},
plugins: [
new HtmlWebpackPlugin({
hash: true,
title: 'Webpack - 跡憶客(jiyik.com)',
})
],
};
這里我們不使用 html 模板
在這里,我們將入口文件更改為 app.js,并將輸出文件夾更改為 deploy 。 我們還稍微調整了生成的包文件的名稱。 現在它將以條目的名稱(“main”)開頭,后跟單詞“bundle”和 .js 文件擴展名。
現在我們創建 src/component.js 文件:
src/component.js
export default (text="Hello, Webpack!!")=> {
const element=document.createElement("h1");
element.innerHTML=text;
return element;
};
接下來,我們將現在項目中的 index.js 重命名為 app.js 以此反映我們的更改,并將其內容替換為以下內容:
app.js
import component from './component';
document.body.appendChild(component());
現在讓我們運行 webpack,看一下發生了什么
$ npm run dev
> webpack-example@1.0.0 dev /Users/jiyik/workspace/js/webpack-example
> webpack --mode development
asset main.bundle.js 4.33 KiB [emitted] (name: main)
asset index.html 552 bytes [emitted] [compared for emit]
runtime modules 670 bytes 3 modules
cacheable modules 235 bytes
./src/app.js 77 bytes [built] [code generated]
./src/component.js 158 bytes [built] [code generated]
webpack 5.54.0 compiled successfully in 142 ms
運行之后我們會在項目目錄中看到生成了deploy文件夾,其中包含靜態html文件和js文件
此時我們在瀏覽器中運行 deploy/index.html 文件,結果如下:
此外,如果我們檢查 index.html 的源代碼,我們會看到 script 標簽中 src 屬性的值更新為 main.bundle.js。
此時,我們可以刪除 webpack 最初生成的 dist 文件夾,因為我們不再需要它了。
接下來我們將了解如何將 ES6 轉換為適用于所有瀏覽器的 ES5 的代碼。 讓我們從運行以下命令開始:
$ npm run dev -- --devtool inline-source-map
在這里,我運行 webpack 并將 devtool 選項設置為 inline-source-map 以使代碼更具可讀性。 這樣可以更清楚地演示從 ES6 到 ES5 的代碼轉換。
下面我們打開 main.bundle.js
main.bundle.js 部分代碼
/***/ "./src/component.js":
/*!**************************!*\
!*** ./src/component.js ***!
\**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__)=> {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": ()=> (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__=((text="Hello, Webpack!")=> {
const element=document.createElement("h1");
element.innerHTML=text;
return element;
});
/***/ })
/******/ });
如您所見,來自 component.js 模塊的現代 ES6 特性(箭頭函數和 const 聲明)默認不會轉換為符合 ES5 的代碼。 為了讓我們的代碼在舊瀏覽器中工作,我們必須添加 Babel 加載器:
$ npm install babel-loader @babel/core @babel/preset-env --save-dev
然后在 webpack.config.js 文件中,在 output 項之后添加 module 項,如下所示
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
]
},
當我們為 webpack loader 定義規則時,通常需要定義三個主要屬性:
webpack.config.js
const HtmlWebpackPlugin=require("html-webpack-plugin");
const path=require('path');
module.exports={
entry: {
main: path.resolve(__dirname, './src/app.js'),
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'deploy')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack - 跡憶客(jiyik.com)',
})
],
};
然后在運行 webpack 看會生成什么樣的文件
$ npm run dev -- --devtool inline-source-map
> webpack-example@1.0.0 dev /Users/liuhanzeng/workspace/js/webpack-example
> webpack --mode development "--devtool" "inline-source-map"
asset main.bundle.js 7.02 KiB [emitted] (name: main)
asset index.html 257 bytes [compared for emit]
runtime modules 670 bytes 3 modules
cacheable modules 301 bytes
./src/app.js 76 bytes [built] [code generated]
./src/component.js 225 bytes [built] [code generated]
webpack 5.54.0 compiled successfully in 1340 ms
這次 main.bundle.js 中的代碼:
/***/ "./src/component.js":
/*!**************************!*\
!*** ./src/component.js ***!
\**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__)=> {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": ()=> (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__=(function () {
var text=arguments.length > 0 && arguments[0] !==undefined ? arguments[0] : "Hello, Webpack!";
var element=document.createElement("h1");
element.innerHTML=text;
return element;
});
/***/ })
/******/ });
非常完美。 現在我們可以使用現代 JS 功能(ES6),webpack 將轉換我們的代碼,以便它可以被舊瀏覽器執行。
言
現實應用環境,會有使用vue開發多頁面環境的需求,這些頁面擁有共同的依賴,但是卻又都是獨立的,為了實現vue的多頁面打包,可以使用webpack,同時又因為vue-cli自帶了webpack,所以我們還可以采用vue-cli本身的配置文件進行多頁打包操作。
VUE3多頁面打包
方式一:webpack配置
webpack安裝參考:[安裝 | webpack 中文網]。
直接在package.json同級目錄下創建webpack.config.js(創建一個webpack的配置文件即可),然后在配置文件內輸入內容:
/**
*配置
* */
/*path處理模塊,可有可無,主要是為了方便路徑鏈接,因為在配置文件內對于參數而言只接受絕對路徑,利用path.resovle(__dirname, 相對路徑)可以自動生成絕對路徑,此模塊為webpack自帶*/
let path=require('path')
/*vue-loader,vue加載插件,使用npm install vue-loader直接安裝即可
*同時對于vue3而言需要單獨安裝@vue/compiler-sfc,vue2的話是vue-compiler
*/
let vueLoader=require('vue-loader')
/*html-webpack-plugin,模版處理插件,如果存在多個html模版就需要安裝
*直接用npm install html-webpack-plugin
*/
let htmlWebPackPlugin=require('html-webpack-plugin')
/**
*compression-webpack-plugin,這是一個可選插件,目的是為了對打包后的文件進行壓縮,因為打包后會形成一個大的js文件,文件越大網頁打開速度越慢。
*/
let compressionWebpackPlugin=require('compression-webpack-plugin')
module.exports={
/*打包入口,多入口就是從這里來的,當打包時,會去找到每一個入口文件,
并根據這個文件依賴去打包,每一個入口寫一個key-value對*/
entry: {
/*key-value格式
key就是標識名稱,之所以寫成 "/js/index/index" 格式是為了在打包時將文件輸出到對應目錄,
默認情況下,文件只會輸出到output所指定的目錄下,之后便沒有區分,這里用“/”分割就是利用輸出路徑時小漏洞形成目錄*/
/*value是要打包入口的地址,利用path.resolve處理絕對路徑問題*/
'/js/index/index': path.resolve(__dirname, './src/entry/index.js'),
'/js/index2/index2': path.resolve(__dirname, './src/entry/index2.js')
},
/*文件輸出目錄,只能有一個,[官方要求](https://www.webpackjs.com/concepts/output/)*/
output: {
/*輸出的入口文件的名稱,【name】就是剛才上面我們指定的key值,這個值不能通過外部變量或數組動態修改*/
filename: '[name].js',
/*輸出目錄,也需要指定絕對路徑*/
path: path.resolve(__dirname, './dist')
},
/*插件配置與加載*/
plugins: [
/*加載vue文件打包插件*/
new vueLoader.VueLoaderPlugin,
/*html模版打包插件,有幾個入口就要用幾個,書寫順序與上方入口順序一致,
如果只有一個,那么所有入口都會通過這一個模版打包*/
new htmlWebPackPlugin({
template: path.resolve(__dirname, './public/html/index.html'),
filename: 'index.html'
}),
new htmlWebPackPlugin({
template: path.resolve(__dirname, './public/html/index2.html'),
filename: 'xxjszx.html'
}),
/*加載壓縮插件,將test中查找到的文件類型全部壓縮,test的值對應的是一個正則表達式*/
new compressionWebpackPlugin({
test: /\.js$|\.html$|\.css$|\.jpg$|\.png$/,
threshold: 100000,
deleteOriginalAssets: false
})
],
module:{
/*文件處理規則*/
rules: [
{
/*css處理規則,直接用css-loader插件默認加載,css-loader插件也需要使用npm安裝*/
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
/*vue文件加載規則*/
test: /\.vue$/,
use: ['vue-loader']
},
{
/*圖片文件處理規則,使用url-loader插件改寫文件名并放到指定位置*/
test: /\.(jp?g|png|svg|ico)$/,
use: 'url-loader?limit=2048&name=./img/[hash:8].[name].[ext]'
}
]
}
}
方式二:vue-cli配置
vue-cli目前已不提供vue.config.js配置文件,但是我們可以手動在package.json同級目錄創建一個,創建成功后此文件將作為優先調用對象,結構與內容同webpack類似(其實就是內置的webpack配置),可參考官網配置解釋:配置參考 | Vue CLI:
module.exports={
/*pages指定入口,同樣是key-value對的形式,只不過是將配置集成到了一起*/
pages: {
/*名稱*/
xxjszx: {
/*入口,同上面的entry*/
entry: 'src/entry/xxjszx.js',
/*模版,同上面的html-webpack-plugin插件*/
template: 'public/html/xxjszx.html',
/*輸出后的文件名稱*/
filename: 'xxjszx.html',
},
index: {
entry: 'src/entry/index.js',
template: 'public/html/index.html',
/*這里是html輸出到的文件地址,也可以利用/斜杠表示目錄,例如index/index.html就代表創建index目錄并把index.html放到目錄下*/
filename: 'index.html',
}
}
}
vue3多頁面直接運行
使用vue.config.js配置好后,直接使用npm run dev命令即可,對應vue的vue-cli-service serve,運行可根據pages定義的key值進行路由調用頁面,key值為index那么調用格式就是/index,默認頁面是index路由對應頁面。如果采用webpack打包是無法直接運行多頁面的,需要在打包后部署到服務器上。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。