动态

详情 返回 返回

效能工具(八)之vite開發或生產環境下的命令行變量傳參(比如啓動項目時多視圖選擇其一) - 动态 详情

需求描述

  • 前段時間有這樣的一個需求:
  • 筆者有一個項目,在啓動或者打包的時候
  • 需要根據一些實際情況,去選擇展示那個視圖
  • 就是我們在項目啓動或者打包的時候,需要注入一個全局變量(保存在.env.development或.env.production文件中)通過命令行npm run dev的方式
  • 一般來説,vue-router就可以實現這個需求
  • 但是,某些情況下,這個需求不太適合用vue-router去實現
  • 所以,筆者分享這篇文章,給到一個思路和示例
  • 完整代碼附上,在文末的github上

效果圖

第一步,在啓動項目的時候命令行傳參,修改package.json

  • 實際上,類似的功能效果筆者之前分享過一篇文章
  • 《效能工具之node在項目中的應用(二)《以開發環境多後端服務切換問題為例》》
  • 那個是使用的 inquirer 的npm包
  • 相比較而言,本篇文章,不使用包
  • 即用Vue和Vite自帶功能的實現之
  • 首先,我們去自定義腳本"de": "node ./choose.js",實現啓動或者打包
  • (這裏刪除了默認的npm run dev腳本即:"dev": "vite",),如下:
{
  "name": "build",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "de": "node ./choose.js",
    "pr": "node ./choose.js"
  },
  "dependencies": { ... },
  "devDependencies": { ... }
}
  • 也就是説,當執行npm run de這個腳本的時候,會驅動node去執行choose.js這個文件腳本js文件
  • 當然了,這個文件在和package.json在同一目錄下(根目錄)

第二步 編寫腳本choose.js文件

想要編寫好一個choose.js文件,我們需要掌握以下的前置知識

前置知識child\_process

  • 説到child_process模塊,就不得不提process模塊
  • 大家類比一下理解即可
  • 前者是 Node.js 中的全局對象,這個對象提供了與當前 Node.js 進程進行交互的各種信息和控制能力。
  • 後者是一個 Node.js 內置模塊,該模塊允許 Node.js 創建新的子進程,實現多進程編程
  • 所以,我們可以使用child\_process來啓動一個vite項目

即為:

  • 假設此文件和vite項目在同一根目錄,叫做c.js
  • 那麼,我們執行node c.js就可以把同級目錄的vite項目跑起來了
  • 相當於執行了,npm run dev
  • 因為前者也是驅動vite運行項目的("dev": "vite",
  • 默認package.json文件如下:
  "scripts": {
    "start": "npm run dev",
    "dev": "vite",
    "build:prod": "vite build",
    "build:stage": "vite build --mode staging",
    "preview": "vite preview",
  }

我們直接改動手動地,通過node的child\_process模塊驅動vite項目跑起來

// c.js
import { execSync } from 'child_process'

// 啓動開發環境
execSync(`vite --host`, { stdio: 'inherit' });

// 啓動生產環境
execSync(`vite build`, { stdio: 'inherit' });
execSync可以執行外部命令,如執行vite的命令

腳本choose.js文件

  • 有了上述前置知識,我們就可以編寫出以下腳本
  • 拿到命令行輸入的參數比如
  • npm run de -- 1 或者 npm run de -- 2 或者 npm run de -- 3
  • 根據傳進來的 1 或者 2 或者 3
  • 去選擇對應的視圖單位
  • 注意,這裏要把命令行傳遞進來參數,存一份到.env.development文件中(開發環境,生產環境.env.production)
  • 我們直接寫入到文件中,這樣在任何一個.vue文件中都可以訪問到這個命令行參數變量了
  • 比如:fs.writeFileSync('./.env.development', VITE_UNIT = ${params})
  • 注意,命令行傳參的格式,否則Vite接受不到
  • npm run de -- xxx ,才能接收到這個xxx參數(let params = process.argv.at(-1)
  • npm run de -- xxx ,才能接收到這個xxx參數(let params = process.argv.at(-1)
  • npm run de -- xxx ,才能接收到這個xxx參數(let params = process.argv.at(-1)
import process from 'process'
import { execSync } from 'child_process'
import fs from 'fs'

// 假設校驗只有三個單元視圖
const checkArr = ['1', '2', '3']

// 獲取命令行參數
let params = process.argv.at(-1) 
if (!checkArr.includes(params)) {
    throw new Error('參數不對') // process.exit(1); // 遇到錯誤退出
}

if (process.env.npm_lifecycle_event == 'de') {
    fs.writeFileSync('./.env.development', `VITE_UNIT = ${params}`)
    execSync(`vite --host`, { stdio: 'inherit' });
} else if (process.env.npm_lifecycle_event == 'pr') {
    fs.writeFileSync('./.env.production', `VITE_UNIT = ${params}`)
    execSync(`vite build`, { stdio: 'inherit' });
}

.env.development和.env.production文件

  • .env.development和.env.production都是環境變量文件
  • 一個開發,一個生產
  • 這裏直接存放對應值就行了
  • 如:VITE\_UNIT = 1
  • 我們通過fs模塊,直接往這個文件中寫入內容:
  • fs.writeFileSync('./.env.development', 'VITE_UNIT = ${params}')
  • .env.development.env.production有內容後,
  • 這樣的話,就可以在任意的.vue文件中使用這個變量了

訪問vite環境變量文件中的變量數據

直接:import.meta.env.VITE_UNIT,如下:

<template>
  <div>{{ unit }}</div>
</template>

<script setup>
let unit = import.meta.env.VITE_UNIT;
</script>
  • 這裏,筆者去把一些用到的html文件存放在
  • public文件夾unitView文件夾
  • 如下圖

  • 這樣的話,就可以啓動的時候,根據存放在.env.development文件中的變量VITE_UNIT使用對應視圖了
  • 比如,當我啓動項目的時候,執行命令是:npm run de -- 2
  • 代表着開發環境,我要查看視圖2
  • 這個時候,choose.js腳本會把傳遞的參數2寫入到.env.development文件中,如下圖:
  • 最後,就可以通過import.meta.env.VITE_UNIT去動態使用了
<template>
  <div>
    <div v-html="htmlContent"></div>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";

// 獲取傳遞進來的unit參數
let unit = import.meta.env.VITE_UNIT;

// 定義一個響應式變量來存儲HTML內容
const htmlContent = ref("");

onMounted(async () => {
  try {
    // 使用fetch API讀取publick文件架下unitView中的html視圖文件
    const response = await fetch(`/unitView/${unit}.html`);
    if (response.ok) {
      // 將響應內容轉換為文本
      const html = await response.text();
      // 賦值響應式變量
      htmlContent.value = html;
    } else {
      console.error("error");
    }
  } catch (error) {
    console.error("Error fetching HTML file:", error);
  }
});
</script>

這樣的話,就可以實現相應效果了

補充:使用http-server本地訪問打包好的dist文件夾

  • 我們打包後的dist文件夾的入口文件,不能雙擊打開查看項目
  • 關於Vite打包dist後的index.html雙擊無法訪問參考文章
  • vite 打包本地文件無法直接打開, file 類型 URL 引發跨域等問題探討
  • https://blog.csdn.net/qq_34727886/article/details/136163494
  • 這個時候,我們可以使用http-server快速啓動一個服務(不用部署在服務器上)
// 打開cmd,全局安裝http-server
npm install -g http-server

// 進入指定打包的目錄
cd dist

// cmd中輸入啓動服務
http-server

如下圖:

這樣的話,我們在本地,也能直接查看到打包好的dist文件夾的內容效果

完整代碼

  • 在筆者的github倉庫:https://github.com/shuirongshuifu/build-choose
  • 建議大家pull下項目,跑起來操作一下,更好理解
user avatar front_yue 头像 u_16307147 头像 yulong1992 头像 ccVue 头像 yuhuashi_584a46acea21f 头像 zhuyundataflux 头像 robin_ren 头像 lenve 头像 zyuxuaner 头像 meiduyandechengzi 头像 stephentian 头像 compose_hub 头像
点赞 22 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.