Skip to content

1.4 ES 模块和现代 JavaScript

📦 基于 OpenLayers 10.5.0+ 最新标准

🎯 学习目标

本章节将介绍 OpenLayers 中的 ES 模块使用和现代 JavaScript 特性。学完本章你将掌握:

  • ES 模块导入规范和最佳实践
  • OpenLayers 10.x 的 TypeScript 支持
  • 现代 JavaScript 特性的实际应用
  • 最新 API 变更要点

📦 ES 模块基础

什么是 ES 模块

OpenLayers 完全基于 ES 模块(ECMAScript Modules)构建,这是 JavaScript 的官方模块系统。

🔧 模块导入语法

默认导入(类)

javascript
// CamelCase 模块提供类作为默认导出
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';

命名导入(函数/常量)

javascript
// lowercase 模块提供函数或常量作为命名导出
import { getUid } from 'ol/util.js';
import { fromLonLat, toLonLat } from 'ol/proj.js';
import { boundingExtent } from 'ol/extent.js';

便捷导入

javascript
// 从主模块导入多个类
import { Map, View } from 'ol';
import { Tile, Vector } from 'ol/layer.js';

📋 模块命名规则

模块类型命名规则导出方式示例
CamelCase默认导出ol/Map.js
函数/常量lowercase命名导出ol/proj.js
类型定义CamelCase命名导出ol/coordinate.js

🌳 树摇优化

什么是树摇

树摇(Tree Shaking)是一种优化技术,只打包实际使用的代码,减小最终包的大小。

最佳导入实践

javascript
// ❌ 不推荐:导入整个库
import ol from 'ol';

// ✅ 推荐:按需导入(支持树摇)
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';

构建优化

Vite 配置示例

javascript
// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          openlayers: ['ol']
        }
      }
    }
  }
};

🚀 现代 JavaScript 特性

ES6+ 语法应用

解构赋值

javascript
// 解构导入
import { fromLonLat, toLonLat } from 'ol/proj.js';

// 解构事件对象
const { coordinate, pixel } = event;

// 解构坐标数组
const [x, y] = coordinate;
const [lon, lat] = toLonLat(coordinate);

箭头函数

javascript
// 事件处理
map.on('click', (event) => {
  console.log('点击坐标:', event.coordinate);
});

// 数组处理
const features = source.getFeatures();
const coordinates = features.map(feature =>
  feature.getGeometry().getCoordinates()
);

模板字符串

javascript
// 动态内容生成
const popupContent = `
  <div>
    <h3>位置信息</h3>
    <p>经度: ${lon.toFixed(4)}</p>
    <p>纬度: ${lat.toFixed(4)}</p>
  </div>
`;

async/await

javascript
// 异步数据加载
async function loadGeoJSON() {
  try {
    const response = await fetch('/data/features.geojson');
    const data = await response.json();

    return new VectorSource({
      features: new GeoJSON().readFeatures(data)
    });
  } catch (error) {
    console.error('加载失败:', error);
  }
}

📘 TypeScript 支持

内置类型定义

OpenLayers 10.x 包含完整的 TypeScript 类型定义:

typescript
// 无需额外安装 @types/ol
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';
import type { Coordinate } from 'ol/coordinate.js';
import type { MapBrowserEvent } from 'ol/MapBrowserEvent.js';

// 类型安全的地图创建
const map: Map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      source: new OSM(),
    }),
  ],
  view: new View({
    center: [0, 0],
    zoom: 2,
  }),
});

// 类型安全的事件处理
map.on('click', (event: MapBrowserEvent<UIEvent>) => {
  const coordinate: Coordinate = event.coordinate;
  console.log('点击坐标:', coordinate);
});

🆕 OpenLayers 10.x API 变更

样式系统更新

typescript
// ❌ 已移除(10.4.0+)
// import type { WebGLStyle } from 'ol/style/webgl';

// ✅ 新的扁平样式系统
import type { FlatStyle } from 'ol/style/flat';

const style: FlatStyle = {
  'fill-color': 'rgba(255, 0, 0, 0.5)',
  'stroke-color': 'red',
  'stroke-width': 2,
  'circle-radius': 8
};

WebGL 图层变更

typescript
// ❌ 已弃用
// import WebGLPointsLayer from 'ol/layer/WebGLPoints.js';

// ✅ 新的 WebGL 矢量图层
import WebGLVectorLayer from 'ol/layer/WebGLVector.js';

表达式系统改进

javascript
// ❌ 旧的类型提示(已移除)
// ['get', 'foo', 'number[]']

// ✅ 简化的表达式
['get', 'foo']

错误处理最佳实践

typescript
// 现代化的错误处理
const createMapSafely = async (): Promise<Map | null> => {
  try {
    const map = new Map({
      target: 'map',
      layers: [
        new TileLayer({
          source: new OSM(),
        }),
      ],
      view: new View({
        center: [0, 0],
        zoom: 2,
      }),
    });

    // 等待地图加载完成
    await new Promise<void>((resolve) => {
      map.once('rendercomplete', () => {
        console.log('地图加载完成');
        resolve();
      });
    });

    return map;

  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error('地图初始化失败:', error.message);
    }
    return null;
  }
};

⚙️ 开发工具配置

TypeScript 配置

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "lib": ["ES2020", "DOM"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Vite 配置优化

javascript
// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          openlayers: ['ol']
        }
      }
    }
  },
  optimizeDeps: {
    include: ['ol']
  }
};

📚 学习资源

官方文档

开发工具

🎯 总结

通过本章学习,你已经掌握了:

  • ES 模块:正确的导入语法和模块化开发
  • 现代 JavaScript:ES6+ 特性的实际应用
  • TypeScript:内置类型定义和类型安全
  • API 变更:OpenLayers 10.x 的重要更新
  • 开发工具:现代化的构建和开发配置

下一步:让我们开始学习 地图基础操作,将现代 JavaScript 技术应用到实际的地图开发中!

如有转载或 CV 的请标注本站原文地址