项目场景:

一个uniapp小程序与原生小程序合并为一个小程序的需求


合并

`在网上查询各种相关方法,决定通过自动化脚本,将老项目内容合并到新项目里

1、uni-app 项目进行小程序端编译,并输出到 dist 目录。

2、执行自动化脚本。

第一步:将 uni-app 输出的小程序内容,拷贝到预上传目录 XXX 中。
第二步:将原生的小程序项目的指定内容,以分包的结构目录拷贝到预上传目录 XXX 中。
第三步:将 uni-app 项目输出的 app.json 配置文件,与原生小程序项目 app.json 文件中的路由配置进行校验并合并。
第四步:通过微信开发者工具预览预上传目录,校验小程序功能是否完整,并最终发布到官方平台。


出现问题

以上第2条的第二步,可以使用vue-cli的copy-webpack-plugin组件,在vue.config.js配置里一键自动化拷贝进包里。但是我发现,在打包后会卡在 - 开始编译当前项目至 mp-weixin 平台… 这个地方(一天一夜都没打包完,说明不是打包慢就是卡住了),使用各种方法依旧无法解决。


解决方案:

后面不使用webpack,
使用别的语言的脚本,再封装一层算了

写个脚本:

电脑环境里安装了python,用python做一个自动化脚本

第一步:1、uni-app 项目进行小程序端编译,并输出到 dist 目录。

无非就是输入打包命令 打开命令行并运行 ‘npm run build’ 命令

# 启动控制台输入打包命令
def run_npm_build():
    try:
        # 获取当前脚本所在的文件夹路径
        current_folder = os.path.dirname(os.path.abspath(__file__))

        # 提取文件夹名字
        folder_name = os.path.basename(current_folder)

        print("当前文件夹名字:", folder_name)

        # 如果你的uniapp项目是xiaochengxu判断当前目录是否为xiaochengxu
        if folder_name == "xiaochengxu":
            subprocess.run(['npm', 'run', 'serve'], shell=True, check=True)
        else: 
            if folder_name == "shelltool":
                subprocess.run(['cd', '..'], check=True, shell=True)
                subprocess.run(['npm', 'run', 'serve'], shell=True, check=True)
            else:
                print('当前目录不正确');
        
    except subprocess.CalledProcessError as e:
        print(f"Error: {e}")
    except FileNotFoundError:
        print("Error: 未找到 'npm' 命令,请确保已安装 Node.js 并且 npm 已配置到系统路径中")
    except Exception as e:
        print(f"Error: {e}")

第二步:

将原生的小程序项目的指定内容,以分包的结构目录拷贝到预上传目录 XXX 中(有一些配置文件没有用了可以删除)

# 文件移动
def fileMove():
	# source_folder 原生小程序目录 destination_folder打包后uniapp小程序目录
    shutil.move(source_folder, destination_folder)
    print(f"成功将文件夹从 {source_folder} 移动到 {destination_folder}")

第三步
将 uni-app 项目输出的 app.json 配置文件,与原生小程序项目 app.json 文件中的路由配置进行校验并合并。

new_config = {
    "subPackages": [
        {
            "root": "ICP",
            "pages": [
                "pages/index/index",
                "pages/login/index"
            ],
            "independent": True 
        }
    ]
}
# json合并
def fileEdit():
    try:
        # 打开文件并加载JSON数据
        with open(file_path, 'r', encoding='utf-8') as file:
            data = json.load(file)

        # 插入新的配置到原有配置的末尾
        if 'subPackages' in data:
            data['subPackages'].extend(new_config['subPackages'])
        else:
            data['subPackages'] = new_config['subPackages']

        # 写入更新后的JSON数据
        with open(file_path, 'w', encoding='utf-8') as file:
            json.dump(data, file, ensure_ascii=False, indent=2)

        print(f"配置已成功插入到 '{file_path}'")
    except Exception as e:
        print(f"编辑文件时发生错误: {str(e)}")

再次出现问题

问题1:如果第二次打包的话,源文件是存在的(有时候webpack会删除原来的包但是有时候时机不太对),那会执行一遍然后不执行了。
问题2:还有一个问题的是本地开发模式 处于webpack热更新,每次修改代码会出现重新打包的情况。

解决方案

这时候需要,另外开启一个线程,去监听包的情况,如果出现修改,说明webpack重新打包了,需要在执行一次移动和json修改操作。
问题1:

def lisToFile():
    time.sleep(10)
                
    while True:
        if os.path.exists(source_folder):
            # print(f"文件 {source_folder} 存在")
            # # 判断目录是否存在
            # if os.path.exists(destination_folder):
            #     # 如果存在删除目录在执行移动操作
            #     os.removedirs(destination_folder)
            # 移动文件夹 
            fileMove()
            
            fileEdit()
            break
        else:
            print(f"文件 {source_folder} 不存在")
            time.sleep(8)

问题2

def listenJson():
    # 自定义的事件处理程序,在文件发生变化时会被调用
    class MyHandler(FileSystemEventHandler):
        def on_modified(self, event):
            if not event.is_directory and event.src_path == app_json_path:
                print("文件被修改了")
                fileEdit()

    # 创建Observer对象和事件处理程序对象
    event_handler = MyHandler()
    observer = Observer()

    # 设置监控的文件和事件
    observer.schedule(event_handler, path, recursive=True)

    # 启动监控
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        # 停止监控
        observer.stop()

    # 等待监控线程的结束
    observer.join()

最后将各个方法合并,开启三个线程

import subprocess
import shutil
import threading  #多线程
import os
import time
import json
# 监控配置文件修改情况
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# 获取当前工作目录的绝对路径
current_path = os.path.abspath(os.getcwd())

source_folder = r'dist'
destination_folder = r'dist'
app_json_path = r'dist\app.js'
file_path = r'dist\app.json'
path = r'dist\mp-weixin'

source_folder = os.path.join(current_path, source_folder)
destination_folder = os.path.join(current_path, destination_folder)
app_json_path = os.path.join(current_path, app_json_path)
file_path = os.path.join(current_path, file_path)
path = os.path.join(current_path, path)

# 要插入的配置
new_config = {
    "subPackages": [
        {
            "root": "ICP",
            "pages": [
                "pages/index/index",
                "pages/login/index"
            ],
            "independent": True
        }
    ]
}
# 启动控制台输入打包命令
def run_npm_serve():
    try:
        # 获取当前脚本所在的文件夹路径
        current_folder = os.path.dirname(os.path.abspath(__file__))

        # 提取文件夹名字
        folder_name = os.path.basename(current_folder)

        print("当前文件夹名字:", folder_name)

        # 判断当前目录是否为xiaochengxu
        if folder_name == "xiaochengxu":
            subprocess.run(['npm', 'run', 'serve'], shell=True, check=True)
        else: 
            if folder_name == "shelltool":
                subprocess.run(['cd', '..'], check=True, shell=True)
                subprocess.run(['npm', 'run', 'serve'], shell=True, check=True)
            else:
                print('当前目录不正确');
        
    except subprocess.CalledProcessError as e:
        print(f"Error: {e}")
    except FileNotFoundError:
        print("Error: 未找到 'npm' 命令,请确保已安装 Node.js 并且 npm 已配置到系统路径中")
    except Exception as e:
        print(f"Error: {e}")

# 文件移动
def fileMove():
    shutil.move(source_folder, destination_folder)
    print(f"成功将文件夹从 {source_folder} 移动到 {destination_folder}")

# json合并
def fileEdit():
    try:
        # 打开文件并加载JSON数据
        with open(file_path, 'r', encoding='utf-8') as file:
            data = json.load(file)

        # 插入新的配置到原有配置的末尾
        if 'subPackages' in data:
            data['subPackages'].extend(new_config['subPackages'])
        else:
            data['subPackages'] = new_config['subPackages']

        # 写入更新后的JSON数据
        with open(file_path, 'w', encoding='utf-8') as file:
            json.dump(data, file, ensure_ascii=False, indent=2)

        print(f"配置已成功插入到 '{file_path}'")
    except Exception as e:
        print(f"编辑文件时发生错误: {str(e)}")

# 
def lisToFile():
    time.sleep(10)
                
    while True:
        if os.path.exists(source_folder):
            # print(f"文件 {source_folder} 存在")
            # # 判断目录是否存在
            # if os.path.exists(destination_folder):
            #     # 如果存在删除目录在执行移动操作
            #     os.removedirs(destination_folder)
            # 移动文件夹 
            fileMove()
            
            fileEdit()
            break
        else:
            print(f"文件 {source_folder} 不存在")
            time.sleep(8)

# 230010
def listenJson():
    # 自定义的事件处理程序,在文件发生变化时会被调用
    class MyHandler(FileSystemEventHandler):
        def on_modified(self, event):
            if not event.is_directory and event.src_path == app_json_path:
                print("文件被修改了")
                fileEdit()

    # 创建Observer对象和事件处理程序对象
    event_handler = MyHandler()
    observer = Observer()

    # 设置监控的文件和事件
    observer.schedule(event_handler, path, recursive=True)

    # 启动监控
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        # 停止监控
        observer.stop()

    # 等待监控线程的结束
    observer.join()




# 调用函数执行命令并移动文件夹
# run_npm_serve_and_move_files()
t1 = threading.Thread(target=run_npm_serve)
t2 = threading.Thread(target=lisToFile)
t3 = threading.Thread(target=listenJson)
# 启动线程
t1.start()
t2.start()
t3.start()
# 等待线程完成
t1.join()
t2.join()
t3.join()

提前安装一些依赖
python还有 python的pip。