3. 开发环境搭建:Node.js + Vite 前端项目初始化,安装地图库依赖,配置TypeScript
好,咱们正式开始动手。这一章的目标很明确——把开发环境搭起来,让项目能跑、能编译、能调地图。我见过不少同学卡在这一步,要么依赖装不上,要么TypeScript报一堆红。别急,咱们一步步来。
3.1 为什么选 Node.js + Vite + TypeScript?
先说说技术选型。Node.js 是前端开发的基石,Vite 是新一代构建工具,TypeScript 给 JavaScript 加了类型系统。这三者组合,说白了就是「快 + 稳 + 可维护」。
我个人习惯用 Vite 替代 Webpack,原因很简单:开发服务器启动只要几百毫秒,热更新几乎是秒级。你想想看,无人机航迹数据动不动就几千个点,每次改代码都要等十几秒重新打包,那得多崩溃。
| 工具 | 作用 | 为什么选它 |
|---|---|---|
| Node.js | 运行时环境 | 前端工具链的基础,npm/yarn 管理依赖 |
| Vite | 构建工具 | 开发服务器极快,原生ESM支持,配置简单 |
| TypeScript | 类型系统 | 减少运行时错误,代码提示更友好,适合地图API调用 |
核心要点:Vite 的开发服务器基于浏览器原生 ES Module,不需要像 Webpack 那样先打包再启动。这意味着你改一行代码,浏览器几乎立即刷新——对于频繁调试地图图层和航迹点的场景,这个体验差距非常大。
3.2 环境准备:检查 Node.js 版本
在开始之前,先确认你的机器上已经安装了 Node.js。打开终端,输入:
node -v
npm -v
我建议使用 Node.js 18.x 或 20.x 的 LTS 版本。为什么?Vite 5.x 对 Node.js 版本有要求,低于 18 会报错。我曾经在旧项目上吃过亏,Node 16 跑 Vite 5,结果启动直接崩了,查了半天文档才发现是版本问题。
注意:如果你用的是 Node.js 16 或更低版本,请先升级。推荐使用 nvm(Node Version Manager)管理多版本,切换方便。
3.3 初始化 Vite + TypeScript 项目
打开终端,进入你打算存放项目的目录,执行:
npm create vite@latest drone-map-app -- --template vanilla-ts
这里我选了 vanilla-ts 模板,因为它最干净,没有 React 或 Vue 的额外代码。咱们做地图可视化,用原生 TypeScript 反而更灵活,不受框架约束。
然后进入项目目录,安装依赖:
cd drone-map-app
npm install
启动开发服务器验证一下:
npm run dev
浏览器打开 http://localhost:5173,你应该能看到 Vite 的默认页面。嗯,到这里基础架子就搭好了。
3.4 安装地图库依赖
咱们课程选用 Leaflet 作为地图库。为什么不是 Mapbox 或 Cesium?Leaflet 轻量、开源、API 简洁,非常适合教学场景。等后面讲到三维航迹时,我们再引入 Cesium。
安装 Leaflet 和它的 TypeScript 类型声明:
npm install leaflet
npm install -D @types/leaflet
这里有个坑——Leaflet 的 CSS 文件需要手动引入。很多新手只装了 JS 包,结果地图渲染出来一片空白。我在项目中遇到过这个问题,排查了半天才发现是 CSS 没加载。
在项目根目录下找到 src/style.css,清空内容后加入:
@import "leaflet/dist/leaflet.css";
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body, #app {
width: 100%;
height: 100%;
}
小技巧:把 #app 设置为宽高 100%,这样地图容器能自动填满整个视口。后面我们会在 #app 里挂载地图实例。
3.5 配置 TypeScript
Vite 生成的 tsconfig.json 已经有一些默认配置,但我们需要针对地图开发做一些调整。打开 tsconfig.json,修改为:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"]
}
重点说几个配置:
strict: true—— 开启严格模式。地图 API 调用参数多,类型检查能帮你提前发现错误。baseUrl和paths—— 配置路径别名。后面我们写import Map from '@/map'比import Map from '../../map'清爽得多。lib包含DOM—— 地图操作涉及大量 DOM 事件,必须加上。
然后安装路径别名对应的 Vite 插件:
npm install -D @types/node
在 vite.config.ts 中配置别名:
import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
})
3.6 验证环境:写一个简单的地图加载测试
环境搭好了,咱们写几行代码验证一下。在 src/main.ts 中写入:
import L from 'leaflet'
import './style.css'
const app = document.getElementById('app')
if (!app) throw new Error('找不到 #app 容器')
const map = L.map(app).setView([39.9042, 116.4074], 13)
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map)
// 加一个标记,验证交互
L.marker([39.9042, 116.4074])
.addTo(map)
.bindPopup('北京 — 我们开始的地方')
.openPopup()
console.log('地图加载成功!')
保存后,浏览器应该自动刷新。你会看到北京天安门附近的地图,中间有一个弹窗标记。
验证清单:
- 地图瓦片正常显示(没有灰色格子)
- 鼠标拖拽、滚轮缩放流畅
- 控制台没有红色报错
- TypeScript 类型提示正常(比如输入
L.后有代码补全)
3.7 项目结构一览
到这里,你的项目目录应该长这样:
drone-map-app/
├── node_modules/
├── public/
├── src/
│ ├── main.ts # 入口文件
│ ├── style.css # 全局样式 + Leaflet CSS
│ └── vite-env.d.ts # Vite 类型声明
├── index.html
├── package.json
├── tsconfig.json
└── vite.config.ts
这个结构很干净,后面我们添加航迹可视化模块时,会在 src/ 下新建 map/、track/、utils/ 等目录。
3.8 本章知识体系
下面这张图帮你理清本章的核心逻辑:
3.9 常见问题与避坑
最后,分享几个我实际踩过的坑:
- 地图瓦片加载失败 —— 检查网络,OpenStreetMap 在国内某些网络环境下可能被墙。可以换成
https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}高德地图瓦片。 - TypeScript 报错找不到模块 'leaflet' —— 确认
@types/leaflet已安装,并且tsconfig.json中moduleResolution设置为bundler。 - Vite 热更新不生效 —— 检查
vite.config.ts是否有语法错误。我曾经少写了一个括号,导致整个配置失效,终端也没报错,排查了半小时。
我的建议:每完成一步,都跑一下 npm run dev 确认没问题。别一口气装完所有依赖再调试,那样出了问题很难定位。小步快跑,这是我从多年开发里总结出来的经验。