当前位置: 首页 > news >正文

如何模拟一个小程序项目打包的流程

一、Uni-app 执行 yarn run dev:mp-weixin后会发生什么

(一)准备工作

  1. 克隆项目:创建以 typescript 开发的工程(如命令行创建失败,请直接访问 https://gitee.com/dcloud/uni-preset-vue/repository/archive/vite-ts.zip 下载模板)。
    • npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project
  2. 执行 dev:mp-weixin这个命令时,yarnnpm会运行package.json文件中定义的scripts部分的对应命令。通常会类似于这样定义:
    "scripts": {"dev:mp-weixin": "uni -p mp-weixin" 
    }
    

(二)执行后发生的事情

  1. 编译项目uni -p mp-weixin命令会调用 uni-app 的 CLI 工具,编译你的项目代码。uni-app 会将你的 Vue.js 代码转换为微信小程序可以识别的代码,包括将 .vue文件编译成微信小程序的wxmlwxssjsjson文件。
  2. 生成微信小程序项目文件:编译完成后,uni-app 会在项目的dist目录下生成一个专门为微信小程序准备的项目文件夹。这个文件夹包含了所有编译好的代码和资源文件,可以直接在微信开发者工具中打开并运行。
  3. 监视文件变化(开发模式):如果命令是针对开发环境的(如dev:mp-weixin),uni-app CLI 通常会启动一个开发服务器,并持续监视项目文件的变化。当你修改项目中的文件时,它会自动重新编译,并更新到dist目录中的微信小程序项目文件夹中。
  4. 启动开发服务器:在某些情况下,uni-app 还可能会启动一个本地开发服务器,方便在浏览器中实时预览应用的 H5 版本,并且可以同步调试。

二、实现类似 uni 插件的 vite 插件

(一)创建命令行工具

  1. 在项目中创建一个可以在命令行执行的工具,通常可以通过在package.json中定义一个脚本来实现。可以使用 Node.js 创建一个 CLI 工具,并通过配置package.json来实现全局或本地运行。在package.json中定义vue-mini作为一个可执行命令,并且将bin/vue-mini.js文件链接到该命令。
    {"name": "vue-mini-plugin","version": "1.0.0","main": "index.js","license": "MIT","bin": {"vue-mini": "./bin/vue-mini.js"},"scripts": {"vue-mini": "vue-mini"},"dependence": {},"dependencies": {}
    }
    

(二)项目结构

[图片]

(三)编写vue-mini.js

bin目录下创建vue-mini.js文件,这个文件会作为 CLI 工具的入口文件。

#!/usr/bin/env nodeimport { spawn } from "child_process";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";// 获取当前文件的路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);// 获取 mode 参数
const mode = process.argv.includes("--mode")? process.argv[process.argv.indexOf("--mode") + 1]: "development";
console.log(`mode: ${mode}`);// 运行不同的脚本
if (mode === "development") {const devScript = resolve(__dirname, "../scripts/development.js");const childProcess = spawn("node", [devScript], {stdio: "inherit",cwd: __dirname,shell: false,});childProcess.on("exit", (code, signal) => {if (code!== 0) {console.error(`服务启动失败,退出码: ${code}`);} else {console.log(`服务正常退出`);}});
} else {console.error("无效的模式参数");
}

(四)编写development.js

scripts目录下创建development.js文件,这个文件将负责实际的开发模式下的构建和启动过程。

import { spawn } from "child_process";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);const serveScript = resolve(__dirname, "../serve.js");const childProcess = spawn("node", [serveScript], {stdio: "inherit",cwd: __dirname,shell: false,
});childProcess.on("exit", (code, signal) => {if (code!== 0) {console.error(`服务启动失败,退出码: ${code}`);} else {console.log(`服务正常退出`);}
});

(五)编写build.js

import express from "express";
import { dirname } from "path";
import { fileURLToPath } from "url";
import { mkdir, readFileSync, rm, writeFileSync } from "fs";
import { transform } from "esbuild";
import { parse } from "@vue/compiler-sfc";const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);const app = express();const port = 3000;if (process.argv.includes("--clean")) {rm(__dirname + "/dist", { recursive: true }, (err) => {if (err) console.log(err);});
}mkdir(__dirname + "/dist/index", { recursive: true }, (err) => {if (err) console.log(err);
});app.get("/", (req, res) => {res.sendFile(__dirname + "/src/index.html");
});app.get("/*.js", (req, res) => {const path = req.path;const file = readFileSync(__dirname + "/src" + path, "utf-8");writeFileSync(__dirname + "/dist/index.js", file);
});app.get("/*.css", (req, res) => {const path = req.path;const file = readFileSync(__dirname + "/src" + path, "utf-8");writeFileSync(__dirname + "/dist/index.css", file);
});app.get("/*.ts", async (req, res) => {const path = req.path;const file = readFileSync(__dirname + "/src" + path, "utf-8");const transformResult = await transform(file, {loader: "ts",format: "esm",target: "es6",});writeFileSync(__dirname + "/dist/index.js", transformResult.code);
});app.get("/*.vue", (req, res) => {const path = req.path;const fileContent = readFileSync(__dirname + "/src" + path, "utf-8");const parsed = parse(fileContent);if (parsed.descriptor.template) {writeFileSync(__dirname + "/dist/index/index.wxml",parsed.descriptor.template.content);}if (parsed.descriptor.scriptSetup) {writeFileSync(__dirname + "/dist/index/index.js",parsed.descriptor.scriptSetup.content);}if (parsed.descriptor.styles[0].content) {writeFileSync(__dirname + "/dist/index/index.wxss",parsed.descriptor.styles[0].content);}writeFileSync(__dirname + "/dist/index/index.json", "");const projectJson = readFileSync(__dirname + "/src/project.config.json","utf-8");writeFileSync(__dirname + "/dist/project.config.json", projectJson);
});app.listen(port, () => {console.log(`http://localhost:${port}`);
});

(六)安装和测试

在项目根目录下运行以下命令,确保你的 CLI 工具可以运行:

  1. yarn
  2. yarn link

这将创建一个全局链接,允许你直接使用vue-mini命令。现在你可以测试运行以下命令:vue-mini --mode development

得到打包的文件:
在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 力扣题解2555
  • STM32F1+HAL库+FreeTOTS学习10——任务相关API函数使用
  • Vue/cli不同环境下打包后js文件没有添加hash值-会导致缓存问题-解决
  • 基于C#+SQLServer 2005实现(CS界面)校园卡消费信息系统
  • Redis:发布(pub)与订阅(sub)实战
  • Python-pptx:如何在幻灯片中轻松插入与填充表格
  • 【线程同步】关于静态扫描时出现的静态字段访问线程同步实际问题小结
  • linux高级学习13
  • 后端面试经典问题汇总
  • python列表判断是否为空的三种方式
  • Linux: network: esp:收到了重复的包?
  • Python基础语法(1)下
  • Modbus-RTU之C语言实现
  • 智慧水务建设的核心内容
  • 异步编程的实现方式
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • C学习-枚举(九)
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Druid 在有赞的实践
  • Flannel解读
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • Java 23种设计模式 之单例模式 7种实现方式
  • JavaWeb(学习笔记二)
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Next.js之基础概念(二)
  • 闭包--闭包作用之保存(一)
  • 从零搭建Koa2 Server
  • 记录:CentOS7.2配置LNMP环境记录
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 如何在 Tornado 中实现 Middleware
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 我这样减少了26.5M Java内存!
  • 学习使用ExpressJS 4.0中的新Router
  • 移动端唤起键盘时取消position:fixed定位
  • Spring第一个helloWorld
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • # Kafka_深入探秘者(2):kafka 生产者
  • # Redis 入门到精通(九)-- 主从复制(1)
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • %check_box% in rails :coditions={:has_many , :through}
  • (C语言)共用体union的用法举例
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (动态规划)5. 最长回文子串 java解决
  • (二)Kafka离线安装 - Zookeeper下载及安装
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (分类)KNN算法- 参数调优
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (十八)SpringBoot之发送QQ邮件
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)nsfocus-绿盟科技笔试题目
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (转)程序员疫苗:代码注入
  • *ST京蓝入股力合节能 着力绿色智慧城市服务