Vue前端项目增量更新

Vue前端项目增量更新

Vue前端项目打包时会将项目页面代码封装成一个个的js和css,命名规则为chunk+哈希值。
当页面代码有变动并重新打包时,webpack只会更新有变动的文件,并更新文件名称里的哈希值,其他的文件并不会更新,根据这一特性,可以实现vue前端项目增量更新。
操作步骤如下:
1、 上一版本的打包文件命名为dist1,并重新打包前端项目(生成文件默认为dist)。如图
在这里插入图片描述

将执行程序拷贝到前端项目根目录下
在这里插入图片描述
点击空白处右键+shift,选择“在此处打开powershell窗口”,或者cmd进到上图中项目根目录下,执行命令“python compare.py ”,如图
在这里插入图片描述
3、 执行命令后会在当前目录下生成distAdd文件夹和distDel.txt
在这里插入图片描述distAdd文件夹按原有目录结构存放有变动的文件
distDel.txt保存了原有的变更文件名称和路径
4、 增量更新
将distAdd文件夹下的所有文件复制到nginx(我用的nginx,其他的同理)下的html文件夹中,覆盖原有的文件,并根据distDel.txt中的文件名称删除原有的的变更文件即可。
注:文档中dist1、distAdd和distDel.txt命名都可在 compare.py中修改

程序代码我放这了:
python版:

# -*-coding:utf-8-*-    
  
#===============================================================================  
# 目录对比工具(包含子目录 ),并列出
# 1、A比B多了哪些文件  
# 2、B比A多了哪些文件  
# 3、二者相同的文件: md5比较
#===============================================================================  
  
import os
import time
import difflib
import hashlib
from shutil import copy


def getFileMd5(filename):
    if not os.path.isfile(filename):
        print('file not exist: ' + filename)
        return
    myhash = hashlib.md5()
    f = open(filename,'rb')
    while True:
        b = f.read(8096)
        if not b :
            break
        myhash.update(b)
    f.close()
    return myhash.hexdigest()


def getAllFiles(path):
    flist=[]
    for root, dirs , fs in os.walk(path):
        for f in fs:
            f_fullpath = os.path.join(root, f)
            f_relativepath = f_fullpath[len(path):]
            flist.append(f_relativepath)
    return flist

def dirCompare(apath,bpath):
    afiles = getAllFiles(apath)
    bfiles = getAllFiles(bpath)

    setA = set(afiles)
    setB = set(bfiles)

    commonfiles = setA & setB  # 处理共有文件
    difFile = []
    for f in sorted(commonfiles):
        amd=getFileMd5(apath+'\\'+f)
        bmd=getFileMd5(bpath+'\\'+f)
        if amd != bmd:  
            difFile.append(f)

    # 处理仅出现在dist目录中的文件
    onlyFiles = setA ^ setB
    onlyInB = []
    for of in onlyFiles:
        if of in afiles:
            difFile.append(of)
        elif of in bfiles:
            onlyInB.append(of)
            
    if len(difFile) > 0:
        print ('-' * 20,"dif file: %s" %(f), '-' * 20)
        newPath = os.getcwd()+'\distAdd'
        isExists=os.path.exists(newPath)
        if not isExists:
            # 创建不同文件存放的目录
            os.makedirs(newPath)
        for of in sorted(difFile):
            print (aPath+of+'---------'+newPath+of)
            of2 = of[0:of.rfind('\\')]
            if  not os.path.exists(newPath+of2):
                os.makedirs(newPath+of2)
            copy(aPath+of,newPath+of)
            
    if len(onlyInB) > 0:
        print ('-' * 20,"only in ", bpath, '-' * 20)
        f = open('distDel.txt','w+')
        for of in sorted(onlyInB):
            f.write(of+'\n')        
        f.close()
        
if __name__ == '__main__':
    aPath = os.getcwd()+'\\dist'
    bPath = os.getcwd()+'\\dist1'
    dirCompare(aPath, bPath)
    print("\ndone!")

如果没有使用过Python或者电脑没有安装Python的环境的朋友,可以用下面我用Java写的(相应的路径需要根据自己项目的实际路径修改)
java版:


import cn.hutool.core.io.FileUtil;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.*;
import java.util.*;

public class ReportCheckerTest {
    /**
     * 根据路径获取所有的文件夹和文件,及文件的md5值
     *
     * @param path 路径
     */
    private static Map<String, FileModel> getFiles(String path) throws IOException {
        Map<String, FileModel> map = new HashMap<String, FileModel>();
        File folder = new File(path);
        Object[] files = getFileList(folder).toArray();
        Arrays.sort(files);
        for (Object obj : files) {
            File file = (File) obj;
            // 去掉根目录,正则的\\\\,转义为java的\\,再转义为\
            String key = file.getAbsolutePath().replaceAll("\\\\", "/").replaceAll(path, "");
            String md5 = "";// 文件夹不比较md5值
            if (file.isFile()) {
                md5 = DigestUtils.md5Hex(new FileInputStream(file));
            }
            FileModel fileModel = new FileModel(file, md5);
            map.put(key, fileModel);
        }
        return map;
    }

    /**
     * 递归获取路径下所有文件夹和文件
     *
     * @param folder 文件路径
     */
    private static List<File> getFileList(File folder) {
        List<File> list = new ArrayList<File>();
        File[] files = folder.listFiles();
        for (File file : files) {
            list.add(file);
            if (file.isDirectory()) {
                List<File> fileList = getFileList(file);
                list.addAll(fileList);
            }
        }
        return list;
    }

    /**
     * 比较两个文件集合的不同
     *
     * @param fileMap1 文件集合
     * @param fileMap2 文件集合
     */
    public static List<FileModel> compareFile(Map<String, FileModel> fileMap1, Map<String, FileModel> fileMap2,Boolean checkMd5) {
        List<FileModel> list = new ArrayList<FileModel>();
        for (String key : fileMap1.keySet()) {
            FileModel fileModel1 = fileMap1.get(key);
            FileModel fileModel2 = fileMap2.get(key);
            // 将fileMap2中没有的文件夹和文件,添加到结果集中
            if (fileModel2 == null) {
                list.add(fileModel1);
                continue;
            }
            // 文件的md5值不同则add到比较结果集中
            if (checkMd5 && fileModel1.getFile().isFile() && !fileModel1.getMd5().equals(fileModel2.getMd5())) {
                list.add(fileModel1);
            }
        }
        return list;
    }

    public static void main(String[] args) throws IOException {
        //上一版本dist文件路径
        String pathOld = "D:/workspace/appProject/vue/dist1";
        //最新版本dist文件路径
        String pathNew = "D:/workspace/appProject/vue/dist";
        //记录待删除文件的文本路径
        String distDel = "D:/workspace/appProject/vue/distDel.txt";
        //新增文件的文件夹路径
        String distAdd= "D:/workspace/appProject/vue/distAdd";

        File fileOld = new File(pathOld);
        File fileNew = new File(pathNew);
        if (!fileOld.exists() || !fileNew.exists()) {
            System.out.println("请检查路径是否存在!");
            return;
        }
        // 获取路径下所有文件夹和文件,及文件的md5值
        Map<String, FileModel> fileMap1 = getFiles(pathOld);
        Map<String, FileModel> fileMap2 = getFiles(pathNew);
        List<FileModel> resultList = new ArrayList<FileModel>();
        List<FileModel> resultList2 = new ArrayList<FileModel>();
        // 得到fileMap2中没有的文件夹和文件,及md5值不同的文件
        resultList.addAll(compareFile(fileMap1, fileMap2,false));
        // 得到fileMap1中没有的文件夹和文件,及md5值不同的文件
        resultList2.addAll(compareFile(fileMap2, fileMap1,true));

        //将旧的文件名称及路径写入到txt文件中
        String pathTxt = "";
        for (FileModel fileModel : resultList) {
            System.out.println("old-----" + fileModel.getFile().getAbsolutePath());
            pathTxt += fileModel.getFile().getAbsolutePath() + "\n";
        }
        try {
            File file = new File(distDel);
            boolean b = file.createNewFile();
            if (b) {
                Writer out = new FileWriter(file);
                out.write(pathTxt);
                out.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        //将新生成的文件复制到另一文件夹中
        File file2 = new File(distAdd);
        if (!file2.exists()) {
            file2.mkdirs();
        }
        for (FileModel fileModel : resultList2) {
            System.out.println("new-----" + fileModel.getFile().getAbsolutePath());
            String filePath = fileModel.getFile().getAbsolutePath().replace("dist", "distAdd");
            FileUtil.copy(fileModel.getFile().getAbsolutePath(), filePath, true);
        }
    }
}




FileModel:

import java.io.File;

public class FileModel {
    public File file;
    public String md5;

    public FileModel(File file, String md5) {
        this.file = file;
        this.md5 = md5;
    }
    public File getFile() {
        return file;
    }
    public void setFile(File file) {
        this.file = file;
    }
    public String getMd5() {
        return md5;
    }
    public void setMd5(String md5) {
        this.md5 = md5;
    }
}

一个前端Vue项目实战案例可以按照以下开发流程进行: 1. 项目立项:包括需求分析、技术选型和确定项目人员等。 2. 产品原型设计:设计产品原型图,并进行UI设计。 3. 项目开发:前端与后端进行开发,前端部分包括设计图和切图,后端部分包括服务端的开发。 4. 项目测试:由测试部门进行测试。 5. 项目上线:由运维和后端负责项目的上线。 开发环境方面,可以使用开发工具如VS Code,并安装Vue开发工具vetur。项目运行环境可以是Node v10,Vue脚手架可以使用vue-cli 4.5.7。代码版本工具可以使用Git/Gitee。 一个具体的前端Vue项目实战案例可以是根据《Vue项目开发实战》开发的项目Vue.js是一套构建用户界面的渐进式框架,相对于其他重量级框架,Vue采用自底向上增量开发的设计,它的核心库只关注视图层,并且非常容易学习和整合到其他库或已有项目中。 该实战案例可以包含以下内容: - 创建登录页面,使用snipaste截图软件进行页面设计。 - 安装element-ui和axios请求库,用于页面的样式和数据请求。 - 配置myaxiosapi文件接口,用于与后端进行数据交互。 - 实现常见的跨域方式,确保前端项目能够正常与后端进行通信。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Vue综合实战项目](https://blog.csdn.net/m0_45272038/article/details/113828939)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [vue项目开发实战](https://download.csdn.net/download/weixin_38596117/19953278)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值