webpack如何将vue3单页面应用改造成多页面应用

作者:松果

时间:2026-10-30

浏览:200

本文介绍如何使用webpack将Vue3单页面应用改造为多页面应用。通过配置多个entry入口文件和HtmlWebpackPlugin生成独立HTML模板,实现页面间的独立路由与组件管理。同时演示了如何在多页面环境中共享Pinia状态,并通过实际代码示例展示页面跳转与状态变更的测试过程。

文章目录

此前已完成一个Vue单页面应用的搭建,本文旨在通过简单示例,演示如何将其改造为多页面应用。

核心改动在于调整Webpack的入口文件和HTML模板配置。在架构上,每个页面保留独立的Vue实例和路由配置,而Pinia状态管理则选择由所有页面共享。

以下配置基于前文项目结构进行调整,更详细的背景信息可参考之前的文章。

一、改一下项目结构

首先在src目录下新建pages目录,并在其中为每个页面创建独立的子文件夹。每个页面需包含各自的main.js和App.vue,以及独立的views和router目录。通用组件components和pinia文件夹则放置在pages目录的同级区域,具体结构参考下图:

一、改一下项目结构

以index文件夹为例进行了详细展开,page1的结构与之类似,仅将入口文件由index.js改为page1.js,组件由index.vue改为page1.vue(当然,统一命名为main.js和App.vue也是可行的,此处仅为个人习惯)。每个页面的配置逻辑与vue-cli生成的单页面应用类似。注:忽略底部的templates目录,该目录用于存放HTML模板。

二、更改webpack的配置

配置主要涉及两部分:首先,由于存在两个页面,因此需要定义两个入口文件。

entry: {
        index: path.resolve(__dirname, './src/pages/index/index.js'),
        page1: path.resolve(__dirname, './src/pages/page1/page1.js')
    },
    output: {
        path: path.resolve(__dirname, 'dist'), // 打包出口
        filename: '[name].js', // 打包完的静态资源文件名
        clean: true,//每次打包都会删除dist里面旧的内容
    },

与上一篇文章相比,output配置中的filename有所调整,这些配置并非最终形态,后续还将对结构进行优化。

其次是HTML模板的配置,需要为每个页面创建对应的模板文件。

plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './templates/index.html'), // 我们要使用的 html 模板地址
            filename: 'index.html', // 打包后输出的文件名
            title: 'index页面',
            chunks: ["index"]
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './templates/page1.html'), // 我们要使用的 html 模板地址
            filename: 'page1.html', // 打包后输出的文件名
            title: 'page1页面',
            chunks: ["page1"]
        }),
        new VueLoaderPlugin() //vue-loader插件
    ],

这里配置了两个HtmlWebpackPlugin插件实例,每个实例对应一个页面。两个HTML模板文件存放在与pages同级的template文件夹中,目录结构如下:

一、改一下项目结构

两个模板文件的内容基本一致,具体如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        <%= htmlWebpackPlugin.options.title %>
    </title>
</head>
<body>
    <div id="root"></div>
</body>

主要区别在于body标签内增加了一个id为root的div元素,用于挂载Vue实例。

此外需注意,两个页面的Vue实例共享同一个Pinia实例。由于不确定这种共享方式是否完全稳定,因此进行了测试:创建了一个名为userInfor的Pinia模块,配置如下:

import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
    state: () => {
        return { userName: "黄烽" }
    },
    // 也可以这样定义
    // state: () => ({ count: 0 })
    actions: {
        changeName () {
            this.userName = "gss"
        }
    },
})

在index页面的views/Home.vue中进行展示,该页面包含一个按钮,点击后触发change函数,将页面跳转至page1.html。

<template>
    <div class="msg">this msg is from page index
        <span>this is from span</span><br />
        <span>{{ "userName: " + user.userName }}</span>
        <button @click="change">跳转</button>
    </div>
</template>
<script setup>
import { onMounted } from 'vue';
import { useUserStore } from "../../../pinia/userInfor.js"
const user = useUserStore()
const testFunction = (msg) => {
    alert(msg)
}
onMounted(() => {
    testFunction("hhhh")
})
const change = () => {
    window.location.href = "./page1.html"
}
</script>
<style scoped lang="scss">
.msg {
    color: red;
    span {
        color: green;
    }
}
</style>

对应的page1页面中Home.vue配置如下:

<template>
    <div class="msg">this msg is from page1
        <span>this is from span</span><br />
        <span>{{ "userName: " + user.userName }}</span>
        <button @click="change">改变用户姓名</button>
    </div>
</template>
<script setup>
import { onMounted } from 'vue';
import { useUserStore } from "../../../pinia/userInfor.js"
const user = useUserStore()
const change = () => {
    user.changeName()
}
const testFunction = (msg) => {
    alert(msg)
}
onMounted(() => {
    testFunction("hhhh")
})
</script>
<style scoped lang="scss">
.msg {
    color: red;
    span {
        color: green;
    }
}
</style>

两者基本一致,区别仅在于msg内容不同,且page1中的change函数用于测试Pinia中的mutation操作。

最后一步是启动开发服务器进行测试,执行npm run dev即可。虽然实现较为简单,但基本逻辑已通。打包后,dist文件夹内的结构如下:

一、改一下项目结构

三、结尾

整体改造过程较为简单,难点在于后续的优化工作。目前我对优化方案尚感模糊,未来有机会将补充相关的优化示例。

至此,关于webpack将Vue3单页面应用改造成多页面应用的介绍结束。如需了解更多相关内容,请搜索本站历史文章或继续浏览后续文章,感谢大家的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章