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


    一、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 node
    
    import { 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

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

  • 相关阅读:
    GitLab搭建
    ctfshow菜狗杯 web 无算力以及easyPytHon_P
    XDAG同步节点部署
    PTA平台-2023年软件设计综合实践_5(指针及引用)
    交换机与路由器技术-03-交换机基本配置
    前端的(typeScript)interface详解(个人学习用)
    蓝桥杯C++AB算法辅导
    在WordPress网站上添加文章分类信息
    当今旗舰电视最新画质技术,马上就被联发科搬到手机上了
    HTML5学习系列之简单使用1
  • 原文地址:https://blog.csdn.net/m0_66492535/article/details/142144852