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小时内与您取得联系。