vue单页面改造多页面应用详解第1/2页

单页面和多页面的区别这里就不细说了。我司业务适合多页面,许多小应用都是通过iframe整体嵌入的形式。

  • 如果项目过于庞大,就会有很不好的体验问题。
  • 拆分多个项目的话,又会有额外的开支,如服务器资源部署等问题。

基于此改造的目标

  • 单独业务逻辑单独一个页面
  • 可实现单命令打包
  • 可单独打包

首先我们准备一个基础的项目,目录结构如下

src目录为我们平时开发的目录,dist为打包后的目录,整体结构如图

1 将当前项目改造成多页面目录

pages下为我们开发的目录文件,改造过程就是将原src下所有目录结构复制到home,index每个页面单独一份 为了提现多页面优势,这里我们选用两款ui框架,以便最后做下打包体积对比

npm i element-ui -S
npm i ant-design-vue -S

在home和index中分别引入

home页面类似,然后我们更改vue.config.js

module.exports = {
  publicPath: './',
  productionSourceMap: false,
  pages: { // vue cli3 自带多页面配置
    index: {
      entry: `src/pages/index/main.js`,
      template: `public/index.html`,
      filename: `index.html`
    },
    home: {
      entry: `src/pages/home/main.js`,
      template: `public/index.html`,
      filename: `home.html`
    }
  },
  devServer: {
    port: 8080
  },
  lintOnSave: false
}

现在我们打包,看一下生成的目录结构

 File                                   Size              Gzipped

  dist\js\chunk-vendors.239e820f.js      2544.36 KiB       703.20 KiB
  dist\js\index.1716ccad.js              11.33 KiB         4.13 KiB
  dist\js\home.e4410a07.js               7.08 KiB          2.57 KiB
  dist\js\about.ca80b2fc.js              0.76 KiB          0.29 KiB
  dist\css\chunk-vendors.68b49edf.css    666.01 KiB        89.04 KiB
  dist\css\index.5dfa7415.css            0.45 KiB          0.28 KiB
  dist\css\home.d995708f.css             0.44 KiB          0.27 KiB

  Images and other types of assets omitted.
  Build at: 2022-05-01T12:26:06.551Z - Hash: 693bf5bdcf72896b - Time: 16240ms

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html

可以看到打包出来的是混在一起的。我们下一步就是将他们拆分开,并且可配置命令单独打包 思路是循环pages下文件夹 我们找出pages下目录中带有main.js的所有文件夹名。当然我们也可以手动写死,每次增加页面的时候,我们单独维护这个数组

const pages = ['home', 'index'] // 在增加页面的时候,手动维护这个数组

当然我们也有方法可以帮我们维护这个数组,可以在我们更新的时候省事一些

// 获取pages下文件夹
const path = require('path')
const glob = require('glob')
// 找到pages所在文件夹 hello-world\src\pages
const PATH_ENTRY = path.resolve(__dirname, '../src/pages')
// 匹配到pages路径下 main.js 的文件
// [
//   'D:/测试项目/hello-world/src/pages/home/main.js',
//   'D:/测试项目/hello-world/src/pages/index/main.js'
// ]
const entryFilePaths = glob.sync(PATH_ENTRY + '/**/main.js')

const buildEntries = []
entryFilePaths.forEach((filePath) => {
  // 找到对应的文件名,index  home
  const FILENAME = filePath.match(/([^/]+)\/main\.js$/)[1]
  buildEntries.push(FILENAME)
})
module.exports = {
  buildEntries
}

buildEntries 既为我们拿到的数组

现在我们继续改造vue.config.js, 我们先通过更改package.json中的命令传参的形式,根据我们传递的参数,单独打包对应的page

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "build:index": "vue-cli-service build index --no-clean", // 注意no-clean 不能清除文件,不然可能将文件夹下打包的其他page清理掉,如果是每次部署一个page,这就无所谓了
    "build:home": "vue-cli-service build home --no-clean",
    "build:prod": "vue-cli-service build",
    "_build": "node build/build.js",
    "lint": "vue-cli-service lint"
 }

我们如何能拿到 传入的index 或者home参数呢 结果是process.argv这个参数中可以取到,具体可以自行搜索下 process.argv为一个数组,第一项为可执行文件的目录 第二项为当前执行的JavaScript文件路径 剩余的是传递的参数,就如我们传递的index 是在process.argv[3]中 现将vue.config.js改造如下

// 编译配置的多页面
const modules = {}
const isProduction = process.env.NODE_ENV === 'production'
const { buildEntries } = require('./config/getPages')

// 初始化页面参数
function initPageParams(page) {
  modules = {
    entry: `src/pages/${page}/main.js`, // page 的入口
    template: `public/index.html`, // 模板来源
    filename: `${page}.html`, // 在 dist/index.html 的输出
  }
}

const page = process.argv[3] || 'index'
// 如果是 开发环境,运行阶段
if (!isProduction) {
  for (const page of buildEntries) {
    initPageParams(page)
  }
} else {
  // 只有在生产打包的时候,单独打包,拆成不用的文件夹
  initPageParams(page)
}

module.exports = {
  publicPath: './',
  outputDir: 'dist',
  assetsDir: isProduction ? page : 'static',
  productionSourceMap: false,
  pages: modules,
  devServer: {
    port: 8080
  },
  lintOnSave: false
}

这时候我们npm run build:index 尝试查看打包结果,可以看到,可以将index对应的文件全部放在index文件目录下,如果我们需要打包home,直接npm run build:home

 File                                      Size             Gzipped

  dist\index\js\chunk-vendors.c60bfe2f.j    1837.82 KiB      527.87 KiB
  s
  dist\index\js\index.e2aa144d.js           11.28 KiB        4.12 KiB
  dist\index\js\about.2a86a3cb.js           0.43 KiB         0.28 KiB
  dist\index\css\chunk-vendors.ef376986.    456.88 KiB       55.99 KiB
  css
  dist\index\css\index.5dfa7415.css         0.45 KiB         0.28 KiB

  Images and other types of assets omitted.
  Build at: 2022-05-03T03:46:54.824Z - Hash: e2d53105a245deab - Time: 12711ms

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html

现在我们已经实现了,单独page单独打包,但我们如果想,一个命令打包所有的page呢。这个时候我们就需要node一个方法来帮助我们实现了 我们在单独建一个js文件代码如下

const fs = require('fs');
const execSync = require('child_process').execSync;
const { buildEntries } = require('../config/getPages');

// 移除目录
function deleteDist(path) {
  let files = [];
  // 判断目录是否存在
  if (fs.existsSync(path)) {
    files = fs.readdirSync(path); // 读取目录
    // @ts-ignore
    files.forEach((file) => {
      const curPath = path + '/' + file; // 拼接目录写文件完整路径
      if (fs.statSync(curPath).isDirectory()) { // 读取文件路径状态 判断是否为文件夹 如果为文件夹,递归
        deleteDist(curPath);
      } else {
        fs.unlinkSync(curPath); // 删除文件
      }
    });
    fs.rmdirSync(path);
  }
}
try {
  const startTime = Date.now();
  process.env.NODE_ENV = 'production';  // 切换环境为生产
  // 执行打包前删除dist目录
  deleteDist('./dist');
  for (const page of buildEntries) {
    // 可以执行我们的命令,第一个参数是命令,第二个参数的意思是输出子进程中的日志
    execSync(`vue-cli-service build ${page} --no-clean`, { stdio: 'inherit' });
  }
  // 重置
  process.env.NODE_ENV = undefined;
  const time = Date.now() - startTime;
  console.log('\033[42;30m ALL DONE \033[0m Build Compiled successfully in ' + `${time / 1000}s`);
} catch (e) {
  console.log('\033[41;30m FAILED \033[0m ' + e);
}

思想就是循环执行打包命令 关键在于execSync方法来替我们执行打包命令,现在我们执行,npm run _build

至此我们的多页面打包基本完成,后续也可以做一些cdn的处理,或者chunks的拆包等优化。小伙伴们自行研究

到此这篇关于vue单页面改造多页面应用详解的文章就介绍到这了,更多相关vue单页面改造多页面 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue将单页面改造成多页面应用的方法

    问题描述: 手头有一个项目是使用 vue-cli 搭建的单页面应用.项目分为了管理平台和用户查看页面,用户查看页面是很简单的页面,但是在加载过程中,却加载了整个应用的打包代码,量重且影响了响应和体验.我想要的效果是,查看页面只加载查看页面的代码,不包含管理系统的代码,因此着手将单页面应用改造成多页面应用,这里分享下方法. 1.改造文件目录 改造前: 改造后: assets:这里不变,依然放置公用的静态资源文件:components:这里存放应用下所有的vue组件:pages:这里存放我们的多页面

  • vue单页面改造多页面应用的全过程记录

    前言 单页面和多页面的区别这里就不细说了.我司业务适合多页面,许多小应用都是通过iframe整体嵌入的形式. 如果项目过于庞大,就会有很不好的体验问题. 拆分多个项目的话,又会有额外的开支,如服务器资源部署等问题. 基于此改造的目标 单独业务逻辑单独一个页面 可实现单命令打包 可单独打包 首先我们准备一个基础的项目 目录结构如下 src目录为我们平时开发的目录,dist为打包后的目录,整体结构如图 1 将当前项目改造成多页面目录 pages下为我们开发的目录文件,改造过程就是将原src下所有目录

  • Vue-cli创建项目从单页面到多页面的方法

    对于某些项目来说,单页面不能很好的满足需求,所以需要将vue-cli创建的单页面项目改为多页面项目. 需要修改以下几个文件: 1.下载依赖glob $npm install glob --save-dev 2.修改build下的文件 (1)修改webpack.base.conf.js 添加以下代码: var glob = require('glob'): var entries = getEntry('./src/pages/**/*.js') 将module.exports中的 entry:

  • Vue单文件组件开发实现过程详解

    第一步:配置环境 安装cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org 安装@vue/cli cnpm install -g @vue/cli 检查版本是否正确 vue --version 使用vue.server和vue.build对*.vue文件进行快速原型开发,需要安装vue serve cnpm install -g @vue/cli-service-global 新建一个App.vue文件测试安装是否

  • vue单页面改造多页面应用详解第1/2页

    单页面和多页面的区别这里就不细说了.我司业务适合多页面,许多小应用都是通过iframe整体嵌入的形式. 如果项目过于庞大,就会有很不好的体验问题. 拆分多个项目的话,又会有额外的开支,如服务器资源部署等问题. 基于此改造的目标 单独业务逻辑单独一个页面 可实现单命令打包 可单独打包 首先我们准备一个基础的项目,目录结构如下 src目录为我们平时开发的目录,dist为打包后的目录,整体结构如图 1 将当前项目改造成多页面目录 pages下为我们开发的目录文件,改造过程就是将原src下所有目录结构复

  • Java中Spring Boot+Socket实现与html页面的长连接实例详解

    Spring Boot+Socket实现与html页面的长连接,客户端给服务器端发消息,服务器给客户端轮询发送消息,附案例源码 功能介绍 客户端给所有在线用户发送消息客户端给指定在线用户发送消息服务器给客户端发送消息(轮询方式) 注意:socket只是实现一些简单的功能,具体的还需根据自身情况,代码稍微改造下 项目搭建 项目结构图 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xml

  • JS技巧多状态页面中的mock方案详解

    目录 引言 技术选型 业务逻辑改造 Eruda 插件 Mock 数据整理 引言 我们有时候会遇到一个业务页面存在很多个状态,甚至子状态,比如订单详情就是其中的典型,涉及从订单创建到订单结束,以及售后等流程.维护起来每个状态对应一份数据,虽然我们 QA 提供了数据构造平台,但构造一份对应状态的数据还是需要花费不少时间,而且串行流程一旦出错的话只能重新来一遍. 后期维护阶段也不容易构造对应状态的数据,导致排查页面问题比较耗时. 另外一个问题就是从头熟悉业务的话成本比较高,如果有一个直观的页面能够看到

  • vue组件编写之todolist组件实例详解

    我们在topNav这个页面上插入一个todolist子组件 我不知道怎么回事,这里的markdown的代码总是串行..所以代码看得不舒服,见谅啊,我最后会放github的源代码地址. 1. 父组件topNav中注册子组件,引入子组件 <template> <div> <p>下面这一行就是定义的组件名称</p> <todo-list></todo-list> <router-view></router-view>

  • Vue项目全局配置微信分享思路详解

    这个项目为移动端项目,主要用于接入公众号服务.项目采用两种登录方式,微信授权登录以及账号密码登录.对于移动端项目而言,为了便于项目扩展以及提供开发热更新速度,项目分为不同的模块,每个模块是一个单页面应用.页面分为两种,一种是需要用户登录之后才能浏览,另一种是用户无需登录即可浏览.无论哪一种,均配置微信分享. 使用的技术 1.使用vue作为框架 2.使用vux作为UI组件库 全局配置微信分享思路 1.区分一般和特殊,一般情况,全局配置默认分享文案:特殊情况分两种,一种是分享内容不需要异步获取,则在

  • Vue.js图片预览插件使用详解

    Vue.js 是什么 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合.另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动. 如果你想在深入学习 Vue 之前对它有更多了解,我们制作了一个视频,带您了解其核心概念和一个示例工程. 如果你已经是有经验的前端开发者,想知道 Vue

  • Vue路由对象属性 .meta $route.matched详解

    $route.fullPath 1 路由是:/path/:type真正路径是:/path/list 2 path匹配路径: /path/list 3 fullPath匹配路由: /path/:type 路由元信息 .meta const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar, // a meta field meta:

  • vue 自定义组件的写法与用法详解

    三个技能,父组件 -> 子组件传值(props).子组件 -> 父组件传值(emit用来使这个独立的组件通过一些逻辑来融入其他组件中.举个具体点的例子,假如你要做一辆车,车轮是要封装的一个独立组件,props指的就是根据整个车的外形你可以给轮子设置一些你想要的且符合车风格的花纹,图案等:而$emit的作用则是让这些轮子能够和整辆车完美契合的运作起来. (1)使用props可以实现父子组件之间的传值 (2)使用this.$emit()可是实现子组件调用父组件的方法 一.在commponents文

随机推荐