webpack高级应用篇(八):多页面应用程序

尽管单页面应用很流行,但是我们并不总是需要它。
在多页面应用程序中,server 会拉取一个新的 HTML 文档给你的客户端。页面重新加载此新文档,并且资源被重新下载。然而,这给了我们特殊的机会去做很多事,例如使用 为页面间共享optimization.splitChunks的应用程序代码创建 bundle。由于入口起点数量的增多,多页应用能够复用多个入口起点之间的大量代码/模块,从而可以极大地从这些技术中受益。

下面以一个例子来演示如何实现多页面应用程序

目录结构

├── dist                               # 打包产物
├── public                             # 静态资源
│   │── index1.html                    # 应用① html模板
│   └── index2.html                    # 应用② html模板
├── src                                # 源码目录
│   ├── views                          # views 所有页面
│   └── main													 # 入口文件目录
│       ├── main1.js                   # 应用① 入口文件
│       └── main2.js                   # 应用② 入口文件
...
├── package.json                        # package.json
├── package-lock.json                   # package.json 锁定版本文件
└── webpack.config.js                   # webpack 配置文件

安装基础配置

npm i webpack webpack-cli webpack-dev-server html-webpack-plugin -D

配置多入口(multi-main entry)

在之前 webpack基础篇(五):代码分离(Code Splitting)有过关于多入口(multi-main entry)的讲解,这里再来深入一下

main1.js

import _ from 'lodash'

console.log(_.join(['hello', 'app-1'], ' '));

main2.js

import _ from 'lodash'

console.log(_.join(['hello', 'app-2'], ' '));

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    
    
  mode: 'development',
  entry: {
    
     // 配置多入口
    main1: {
    
    
      import: './src/main/main1.js', // 启动时需加载的模块
      dependOn: 'common_lodash', // 当前入口所依赖的入口
      filename: 'app-1/[name].[contenthash].js', // 指定要输出的文件名称
    },
    main2: {
    
    
      import: './src/main/main2.js',
      dependOn: 'common_lodash',
      filename: 'app-2/[name].[contenthash].js',
    },

    common_lodash: {
    
     // 这里是上面定义的公用依赖模块
      import: 'lodash',
      filename: 'common/[name].[contenthash].js',
    },
  },

  output: {
    
    
    clean: true
  },

  plugins: [
    new HtmlWebpackPlugin(),
  ]
};

执行 webpack ,通过打包出来的文件大小可以看出,lodash 已经被打包到单独的js文件了

在这里插入图片描述

可以看到,会打包出来如下文件,

在这里插入图片描述

执行 npx webpack serve 可以看到能正常加载页面,并且控制台输出 hello app-1hello app-2

以上配置多入口实现了代码分离(普通js模块与公用模块)


描述入口的对象

用于描述入口的对象。你可以使用如下属性:

  • dependOn: 当前入口所依赖的入口。它们必须在该入口被加载前被加载。
  • filename: 指定要输出的文件名称。
  • import: 启动时需加载的模块。
  • library: 指定 library 选项,为当前 entry 构建一个 library。
  • runtime: 运行时 chunk 的名字。如果设置了,就会创建一个新的运行时 chunk。在 webpack 5.43.0 之后可将其设为 false 以避免一个新的运行时 chunk。
  • publicPath: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址。请查看 output.publicPath

Tip

  • runtimedependOn 不能在同一个入口上同时使用
  • 确保 runtime 不能指向已存在的入口名称
  • dependOn 不能循环引用

配置index.html模板

HtmlWebpackPlugin

HtmlWebpackPlugin 简化了 HTML 文件的创建,以便为你的 webpack 包提供服务。这对于那些文件名中包含哈希值,并且哈希值会随着每次编译而改变的 webpack 包特别有用。你可以让该插件为你生成一个 HTML 文件,使用 lodash 模板提供模板,或者使用你自己的 loader

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    
    
  mode: 'development',
  entry: {
    
     // 配置多入口
    main1: {
    
    
      import: './src/main/main1.js', // 启动时需加载的模块
      dependOn: 'common_lodash', // 当前入口所依赖的入口
      filename: 'app-1/[name].[contenthash].js', // 指定要输出的文件名称
    },
    main2: {
    
    
      import: './src/main/main2.js',
      dependOn: 'common_lodash',
      filename: 'app-2/[name].[contenthash].js',
    },

    common_lodash: {
    
     // 这里是上面定义的公用依赖模块
      import: 'lodash',
      filename: 'common/[name].[contenthash].js',
    },
  },

  output: {
    
    
    clean: true
  },

  plugins: [
    new HtmlWebpackPlugin({
    
    
      title: '多页面应用', // 用于生成的 HTML 文档的标题
      template: './index.html', // 指定模板
      filename: 'index.html', // 定义打包后输出的文件名
      inject: 'body', // 将 script 放在 html 文件的什么位置
      chunks: ['main1', 'common_lodash'] // 添加一些模块
    })
  ]
};

根目录下新建 index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <!-- ejs 语法(JavaScript 模板引擎) -->
  <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>

</body>
</html>

执行 webpack ,查看 dist/index.html,可以看到,我们刚刚的 HtmlWebpackPlugin 配置都生效了

在这里插入图片描述


配置多页面

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    
    
  mode: 'development',
  entry: {
    
     // 配置多入口
    main1: {
    
    
      import: './src/main/main1.js', // 启动时需加载的模块
      dependOn: 'common_lodash', // 当前入口所依赖的入口
      filename: 'app-1/[name].[contenthash].js', // 指定要输出的文件名称
    },
    main2: {
    
    
      import: './src/main/main2.js',
      dependOn: 'common_lodash',
      filename: 'app-2/[name].[contenthash].js',
    },

    common_lodash: {
    
     // 这里是上面定义的公用依赖模块
      import: 'lodash',
      filename: 'common/[name].[contenthash].js',
    },
  },

  output: {
    
    
    clean: true
  },

  devServer: {
    
    
    static: path.resolve(__dirname, './dist')
  },

  plugins: [
    new HtmlWebpackPlugin({
    
    
      title: '应用1',
      template: './public/index1.html',
      filename: './app-1/index.html',
      inject: 'body',
      chunks: ['main1', 'common_lodash'],
    }),

    new HtmlWebpackPlugin({
    
    
      title: '应用2',
      template: './public/index2.html',
      filename: './app-2/index.html',
      inject: 'body',
      chunks: ['main2', 'common_lodash'],
    })
  ]
};

执行 webpack 可以看到,已经将两个应用common都打包并且放入各自的目录中

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

执行npx webpack serve 可以看到界面加载正常,两个应用控制台分别会输出 hello app-1hello app-2

上面的 main1.js main2.js 可以是我们实际项目中的 main.js 入口文件


继续加油 ヾ(◍°∇°◍)ノ゙

猜你喜欢

转载自blog.csdn.net/qq_41887214/article/details/121880699