使用Vite創建一個動態網頁的前端項目
1. 引言
雖然現在的前端更新換代的速度很快,IDE和工具一批批的換,但是我們始終要理解一點基本的程序構建的思維,這些環境和工具都是為了幫助我們更快的發布程序。筆者還記得以前寫前端代碼的時候,只使用文本編輯器,然后在瀏覽器中刷新就可以了。對于純前端項目,其實這樣也是很方便的。不過一旦涉及到文件資源訪問的問題就麻煩了,因為瀏覽器的安全限制,不能訪問域以外的資源。那么你就需要將其部署到Web服務器中,這意味著你要起個服務器。另外,調試的時候也要每次都刷新頁面;第三方依賴包的引入也是問題,需要自己去管理,然后進行引入。于是,像Vite這樣的前端開發與構建工具就出現了,它可以幫助你將上述這些步驟自動化處理,加快你的前端程序的編程效率。這里筆者就總結一下如何使用Vite創建動態網頁的前端項目。
2. 操作
首先,安裝Node.js和npm。Node.js是JavaScript 的運行時環境,npm是一個包管理和任務運行工具,安裝過程比較簡單,這里就不復述了。
接下來,選擇一個文件夾,在終端中運行以下命令來創建項目:
npm create vite@latest my-native-js-app
這時,終端會讓你選擇一個框架:
> npx
> create-vite my-native-js-app
|
* Select a framework:
| > Vanilla
| Vue
| React
| Preact
| Lit
| Svelte
| Solid
| Qwik
| Angular
| Marko
| Others
—
這里筆者選擇使用Vanilla,表示使用原生的模板,不使用任何框架。接下來,終端會讓你選擇使用TypeScript還是JavaScript:
> npx
> create-vite my-native-js-app
|
o Select a framework:
| Vanilla
|
* Select a variant:
| > TypeScript
| JavaScript
—
這里筆者選擇使用JavaScript。然后等待一會兒,前端項目就創建完成了,如下所示:
> npx
> create-vite my-native-js-app
|
o Select a framework:
| Vanilla
|
o Select a variant:
| JavaScript
|
o Scaffolding project in C:\Work\js\my-native-js-app...
|
— Done. Now run:
cd my-native-js-app
npm install
npm run dev
雖然可以接著使用終端,但這時就可以使用VS Code接管項目了。通過VS Code打開my-native-js-app文件夾,并啟動終端,如下圖所示:

在終端執行指令:
npm install
這一步是為了安裝第三方依賴庫。一般來說,如果你開始一個新的項目,這一步是必須的。當然依賴庫安裝完成后,如果后續依賴庫沒有變動,就不需要執行這一步了。
此時的項目的文件組織如下所示:
my-native-js-app
├── public
│ └── vite.svg
├── src
│ ├── counter.js
│ ├── javascript.svg
│ ├── main.js
│ └── style.css
├── index.html
└── package.json
這里的package.json文件是npm的核心配置文件,如下所示:
{
"name": "my-native-js-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"vite": "^6.3.5"
}
}
主要作用有兩個:
- 依賴管理。dependencies字段和devDependencies字段,其中dependencies字段是項目需要的依賴庫包,devDependencies構建項目需要的依賴庫包。執行
npm install就是根據這兩個字段中的值自動安裝響應的依賴包。 - 執行任務腳本。scripts字段,通過自定義命令來執行跟構建相關的任務,這里的dev、build和preview就是最基礎和常用的三個指令。
dev就是執行指令:
npm run dev
表示在開發環境中啟動服務器,終端一般會有如下提示:
> my-native-js-app@0.0.0 dev
> vite
VITE v6.3.5 ready in 500 ms
? Local: http://localhost:5173/
? Network: use --host to expose
? press h + enter to show help
在瀏覽器中訪問地址:http://localhost:5173/ ,可以看到頁面中顯示了一個基礎的HTML +JS示例,如下所示:

另外兩個指令主要是為了實際發布時使用:
npm run build構建項目代碼,比如壓縮、拼接、混淆等。npm run preview發布經過構建后的代碼項目。
3. 解析
這個示例JS項目不僅僅是個歡迎頁面,甚至還是個動態頁面:可以對鼠標點擊的次數計數。那么我們就來稍微解析一下其中的代碼。首先是index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
可以看到這個HTML頁面并沒有顯示在界面的元素,因為這些元素都是通過JS動態加載上來的。另外,要注意的是這里的
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
是用來兼容高分屏的,具體可以參看筆者的文章《HTML頁面關于高分屏的設置》。可以看到即使是這個最簡化的示例都把這個元數據標簽帶上了,因為現在使用高分屏的設備已經非常多了。
接著我們來看一下main.js:
import './style.css'
import javascriptLogo from './javascript.svg'
import viteLogo from '/vite.svg'
import { setupCounter } from './counter.js'
document.querySelector('#app').innerHTML = `
<div>
<a target="_blank">
<img src="${viteLogo}" class="logo" alt="Vite logo" />
</a>
<a target="_blank">
<img src="${javascriptLogo}" class="logo vanilla" alt="JavaScript logo" />
</a>
<h1>Hello Vite!</h1>
<div class="card">
<button id="counter" type="button"></button>
</div>
<p class="read-the-docs">
Click on the Vite logo to learn more
</p>
</div>
`
setupCounter(document.querySelector('#counter'))
這段代碼的主要意思也就是剛才說的,查詢#app元素,并填充HTML字符串,也就是這個頁面是先顯示HTML,再通過js動態加載元素到頁面中。
另一個有意思的點是這里的導入:
import './style.css'
import javascriptLogo from './javascript.svg'
import viteLogo from '/vite.svg'
其實并不是原生JS的行為,而是Vite提供的。這其實也體現了一種思想,HTML、CSS和JavaScript三者來說,JavaScript才是最主要的,css樣式和HTML頁面都可以通過JavaScript來生成。
再來看下counter.js:
export function setupCounter(element) {
let counter = 0
const setCounter = (count) => {
counter = count
element.innerHTML = `count is ${counter}`
}
element.addEventListener('click', () => setCounter(counter + 1))
setCounter(0)
}
函數實現很簡單,就是個簡單的計數功能。不過要注意的是這里的export function setupCounter(element) 使用的是JavaScript ES6(ECMAScript 2015)中的模塊導出語法,表示將setupCounter這個函數導出。在main.js中則進行導入:
import { setupCounter } from './counter.js'
setupCounter(document.querySelector('#counter'))
4. 結語
之所以選擇使用原生JS項目沒有使用框架,是因為筆者想研究一下比較底層的實現,以及對比體會一些框架的設計思路。當然不能重復造輪子,但是也不能離開這些輪子就啥都不會了,理解一些更深層次、更底層的東西,有助于我們更新換代,使用更好的輪子。

浙公網安備 33010602011771號