• vue单页面改造多页面应用


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

    1. 如果项目过于庞大,就会有很不好的体验问题。
    2. 拆分多个项目的话,又会有额外的开支,如服务器资源部署等问题。
    基于此改造的目标
    1. 单独业务逻辑单独一个页面
    2. 可实现单命令打包
    3. 可单独打包
    首先我们准备一个基础的项目,目录结构如下

    image.png

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

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

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

    npm i element-ui -S
    npm i ant-design-vue -S 
    
    • 1
    • 2

    在home和index中分别引入 image.png 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
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

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

     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 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

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

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

    // 获取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
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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"
     } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    我们如何能拿到 传入的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[page] = {
        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
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    这时候我们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 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    现在我们已经实现了,单独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);
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

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

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

    没怎么写过文章,排版大家将就看吧

  • 相关阅读:
    [开源]研发管理项目,支持从需求到代码发布全过程全生命周期管理
    Android逆向学习(番外一)smali2java部分文件无法反编译的bug与修复方法
    Python点云显示:open3d快速上手
    算法51-Dijkstra算法
    从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr
    vue 大文件断点续传、并发控制、请求重试
    解决报错:Vue移动端项目中鼠标无动作时,滚动条自动下滑,拉取数据
    C++ 迭代器 iterator 详解
    小白学编程(CSS):呼吸灯
    基于Linux并结合socket网络编程的ftp服务器的实现
  • 原文地址:https://blog.csdn.net/web220507/article/details/125449078