整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

"Webpack实战:手把手教你轻

"Webpack实战:手把手教你轻松打包多页面Web应用,

ebpack实战:手把手教你轻松打包多页面Web应用,实现高效优化与部署

---

一、引言:Webpack的重要性

在现代Web开发中,Webpack作为一款强大的静态模块打包工具,以其灵活的配置能力和丰富的生态赢得了开发者们的青睐。尤其在构建多页面Web应用时,Webpack可以帮助我们有效地管理和优化资源,提升加载速度和运行效率。本文将深入浅出地解析如何使用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则负责更广泛的构建步骤,如压缩代码、提取公共模块等。

三、Webpack配置多页面应用

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...
],

四、Webpack性能优化

4.1 代码分割与懒加载

javascript
optimization: {
  splitChunks: {
    chunks: 'all',
  },
},

借助`import()`语法或`SplitChunksPlugin`进行代码分割,实现按需加载和延迟加载。

4.2 使用Tree Shaking去除无用代码

javascript
module.exports={
  mode: 'production', // 开启生产模式,自动优化代码
  // ...
};

开启`mode`为`production`,Webpack会自动启用Tree Shaking功能。

五、Webpack部署策略

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,并为 entryoutput 属性指定自定义名称。 在 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

接下来我们将了解如何将 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 定义规则时,通常需要定义三个主要属性:

  • test - 它描述了应该转换什么样的文件。
  • exclude - 它定义了不应该从加载器处理的文件。
  • use - 它告诉应该对匹配的模块使用哪个加载器。 在这里,我们还可以设置加载器选项,就像我们刚刚完成的 presets 选项一样。

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打包是无法直接运行多页面的,需要在打包后部署到服务器上。