# Modern WebGIS Development Technologies and Tools
# Moderen WebGIS Architecture
Modern WebGIS is the application of modern web technologies in GIS. The architecture of modern WebGIS does not differ significantly in essence from the architecture of other modern web projects.
As shown in the figure, the foundation of modern WebGIS is the data layer, which provides fundamental data support such as spatial data and business data. The middle layer typically includes a GIS server that offers basic GIS services and a business logic server that provides application service support. The GIS server can be a professional GIS development platform, an open-source GIS project, or even a simple, widely-used map server, primarily supplying map data services and functional service resources to the application layer. The top layer is the client application layer, which can be developed using modern web technology stacks such as HTML5, ES6, WebGL, WebSocket, React, AngularJS, and Vue.js. By leveraging various WebGIS APIs, it interacts with the GIS server or business logic server to implement web applications that meet specific requirements.
In summary, the development of WebGIS is not only related to advancements in geographic information systems and digital mapping but also closely tied to the evolution of the World Wide Web or web technologies. Therefore, web technology is one of the foundational knowledge areas that WebGIS application developers must learn. In this page,we will focus on modern mainstream web development technologies. It first introduces the general development history of web technologies, followed by an overview of five key areas: front-end modularization, build tools, package managers, programming languages, and front-end frameworks. The aim is to help beginner WebGIS application developers gain a comprehensive understanding of web development technologies, enabling them to make informed decisions quickly.
# From Traditional Web to Modern Web Development
In 1991, Tim Berners-Lee publicly introduced his World Wide Web (commonly referred to as the Web) project, marking the first time the Web was presented to the world. That year, an increasing number of web servers connected to the network, and more and more websites emerged, signaling the arrival of the Web era.
Early web development was synonymous with content development, with no distinction between front-end and back-end development. Pages were generated on the server side by engineers using technologies like JSP and PHP, while browsers were responsible for rendering them. Beyond content, the early Web also supported browser-native behaviors such as hyperlinks and forms, enabling a page-level interaction model. Based on this interaction model, the earliest web applications emerged. As the demand for page-level interactions grew, people began to reject the practice of mixing code for generating and processing pages, leading to the development of server-side frameworks based on the MVC (Model-View-Controller) architecture. The code for generating HTML became the view layer. With the evolution of the internet, there was a growing demand for richer interactions. The advent of AJAX significantly enhanced the user experience of the Web, enabling rich interactive capabilities on HTML pages. This was followed by the rapid development of jQuery, which provided compatibility across various browsers, simplified DOM manipulation, and greatly improved development efficiency.
The explosion of mobile internet brought about major transformations in web technologies. Client-side requirements became more complex, numerous applications gained popularity, and expectations for user experience increased, making client-side rendering a necessity. Client-side programs had to adopt complete lifecycles, layered architectures, and technology stacks. This phase gave rise to a series of excellent frameworks like Angular 1, as well as module standards and loading tools such as AMD, UMD, and RequireJS. Front-end engineering became a specialized field of development, with its own independent technical system and architectural patterns separate from back-end development.
In recent years, as the complexity of web applications has increased and user demands for friendly interactions and performance optimization have grown, there has been an urgent need for more advanced and flexible development frameworks to assist in front-end development. This period has seen the emergence of many frameworks with more focused concerns and superior design philosophies. For example, component-based frameworks like React, Vue.js, and Angular 2 allow developers to use declarative programming instead of imperative programming centered around DOM operations, accelerating component development and enhancing reusability and composability. As the code maintained by front-end engineers has become extremely large and complex, processes like code maintenance, bundling, and deployment have also become highly cumbersome. In terms of build tools, task managers like Grunt and Gulp, as well as project bundling tools like webpack, have emerged to help developers better set up front-end build processes and automate tasks such as preprocessing and asynchronous loading.
Modern web development is characterized by the following features:
- Client-centric: The server-side component is lightweight, with a significant portion of mature business logic, data capabilities, operational capabilities, and infrastructure being API-driven and cloud-service-based.
- Not limited to the client-side: It includes server-side rendering, API Gateway, and some application-oriented microservices.
- Not limited to browsers: It extends to super application platforms and various hybrid technologies based on Web Runtime/JS Runtime.
# Modularity
In web front-end development, modularity refers to small, independent, and reusable units of code. Modular development offers numerous advantages, making it the most common approach to organizing front-end code today:
- It allows the program to be divided into multiple parts or modules, with each part responsible for a specific function or concern, rather than placing all components of the program in a single file.
- Code divided into modules is easier to maintain and has a lower probability of errors.
- Modules can be easily used and reused across different files and parts of a project without the need to write duplicate code.
- Since each module is independent, naming conflicts for variables or functions do not occur.
Native JavaScript does not natively support modular development very well, which led to the emergence of various solutions, including AMD, CMD, CommonJS, and others. Later, the ECMA organization introduced module functionality at the language standard level with ECMAScript modules (ESM).
# CommonJS
CommonJS is a module formatting standard. Currently, Node.js and Browserify are the most representative implementations. The CommonJS specification defines the following conventions:
requireis used to load a module.- In CommonJS, each JavaScript file is a separate module, referred to as a
module, which stores information about the current module. exportsis a property of themoduleobject, storing the interfaces or variables that the current module intends to export. The value obtained by usingrequireto load a module is the value exported by that module usingexports.
For example:
// add.js
function add (a,b){
return a + b
}
module.exports = add
//index.js
const add = require('./add')
console.log(add(4,5)) // 9
Advantages of CommonJS:
- Integrated dependency management: Modules can require other modules and load them in the necessary order.
requirecan be used anywhere.- Supports circular dependencies.
Limitations of CommonJS:
- Module loading is synchronous.
- Each module corresponds to a single file.
- Browsers require a loader library or transpilation.
Reference:
# Asynchronous Module Definition (AMD)
Asynchronous Module Definition (abbreviation: AMD) API specifies a mechanism for defining modules so that modules and their dependencies can be loaded asynchronously. This is particularly suitable for browser environments where synchronous module loading could cause performance, usability, debugging, and cross-origin access issues. The main difference between AMD and CommonJS is the support for asynchronous module loading. Currently, the most popular implementations are Require.js and Dojo. AMD has the following characteristics:
- Improved website performance: AMD implementations load smaller JavaScript files only when needed.
- Fewer page errors: AMD allows developers to define dependencies that must be loaded before executing a module, ensuring that modules do not attempt to use external code that is not yet available.
- Single function definition: The AMD specification defines a single function 'define', which can be used as a free variable or a global variable.
define(id?, dependencies?, factory);
Advantages of the AMD specification:
- Asynchronous loading, resulting in better startup times.
- Modules can be split into multiple files.
Limitations of the AMD specification:
- Slightly more complex syntax.
- Browsers require a loader library or transpilation.
Reference:
- AMD GitHub Project (opens new window)
- Use AMD in Dojo (opens new window)
- Use AMD in Require.js (opens new window)
# ECMAScript modules(ESM)
ECMAScript modules (ESM) are the official standard format for organizing JavaScript code for reuse. ESM is defined using various import and export statements:
importis used to bring modules into a file.exportis used to make modules available for use in other files.
Here is an example of importing a function using ESM:
import defaultExport from "module-name";
import * as name from "module-name";
import { name1 } from "module-name" ;
import { name1 as alias } from "module-name" ;
import { name1, name2 } from "module-name" ;
import { foo, bar } from "module-name/path/to/specific/un-exported/file" ;
import { name1, name2 as alias2 } from "module-name"
import defaultExport, { name1, name2 } from "module-name" ;
import defaultExport from "module-name";
import "module-name"
var promise = import( "module-name" );//This is a third-stage proposal.
Here is an example of exporting a function using ESM:
//Export a single feature
export let name1 = 1; // also var, const
export function FunctionName(){...}
export class ClassName {...}
//Export list
export { name1, name2, ..., nameN };
//Rename export
export { variable1 as name1, variable2 as name2, ..., nameN };
//Destructure exports and rename
export const { name1, name2: bar } = o;
//Defalut export
export default expression;
export default function (...) {...} // also class, function*
Node.js fully supports the currently specified ESM and provides interoperability between ESM and its original module format, CommonJS.
Advantages of the ESM specification:
- Supports both synchronous and asynchronous loading.
- Enables dead code elimination (tree shaking) during the build process.
- Supports circular dependencies.
- Modern browsers already support ESM natively.
Limitations of the ESM specification:
- A large number of module files can lead to frequent network requests.
Reference:
# Web mapping libraries are also aligning with the trend of modular development
In the GIS industry, mainstream web mapping libraries are also adapting to the evolution of modular specifications. For example: OpenLayers V3 adopted Google Closure, while V5 adopted to the ESM specification. Leaflet 1.1.0 adopted the ESM specification. MapboxGL 0.45.0 upgraded from CommonJS to ESM. SuperMap iClient JavaScript 9.0.0 adopted the ESM specification.
# Build Tools
Build tools are a set of software programs or frameworks that help developers automate software development and handle various tasks involved in the deployment process. These tools aim to simplify the build process, making it more efficient and reliable. Build tools typically handle tasks such as compiling source code into executable files, managing dependencies, optimizing and compressing assets, running tests, generating documentation, and packaging applications for deployment. Specifically, most build tools include the following features:
- Minifying and/or compressing files.
- Optimizing images and/or fonts.
- Concatenating files.
- Compiling or transpiling code.
- Generating a development server.
- Hot-reloading modules without requiring a full page refresh.
- Automatically watching files and generating builds when changes are detected.
Here is an introduction to some of the most widely used and popular build tools:
# webpack
webpack is a static module bundler for modern JavaScript applications. When webpack processes an application, it internally builds a dependency graph from one or more entry points and then combines every module needed by the project into one or more bundles, which are static assets.
Key features of webpack:
- Support for ES Modules, CommonJS, and AMD modules (even in combination).
- Ability to create a single bundle or multiple chunks that are loaded asynchronously at runtime to reduce initial loading time.
- Dependencies are resolved during compilation, reducing runtime size.
- Loaders can preprocess files during compilation, such as converting TypeScript to JavaScript, Handlebars strings to compiled functions, or images to Base64.
- A highly modular plugin system that can handle any additional tasks your application requires.
- Support for many different static assets, including images, fonts, and stylesheets.
- Focus on performance and loading time optimization.
- Asynchronous loading of chunks, prefetching, and tree-shaking.
Reference:
# Vite
Vite is an emerging front-end build tool, with its core philosophy centered around unbundled development builds, significantly enhancing the front-end development experience. Vite consists of two main parts:
- A development server: Built on native ES Modules, it offers a wealth of built-in features, such as incredibly fast Hot Module Replacement (HMR).
- A set of build commands: It uses Rollup to bundle the code and comes pre-configured to output highly optimized static assets for production environments.
Reference:
# Package Managers
Package managers enable developers to more easily share code across different projects and use others' code in their own projects.
# npm
npm is currently the largest software registry in the world, used for sharing and borrowing software packages. Many organizations also use npm to manage private development. npm is also the default package manager for Node.js.
npm consists of three distinct components:
- Website: Use the website to discover packages, set up profiles, and manage other aspects of the npm experience. For example, you can set up organizations to manage access to public or private packages.
- Command Line Interface (CLI): The CLI runs from the terminal and is how most developers interact with npm.
- Registry: A large public database of JavaScript software and its associated metadata.
npm can be used to:
- Adapt code packages for your application or merge packages as-is.
- Download standalone tools that you can use immediately.
- Run packages without downloading them using npx.
- Share code with any npm user, anywhere.
- Restrict code access to specific developers.
- Create organizations to coordinate package maintenance, coding, and development.
- Form virtual teams using organizations.
- Manage multiple versions of code and code dependencies.
- Easily update applications when underlying code is updated.
- Discover multiple solutions to the same problem.
- Find other developers working on similar issues and projects.
Reference:
# Yarn
Yarn was created to address some of the shortcomings of npm and has now matured into a robust open-source package manager. Unlike most other package managers (which typically follow npm for non-installation-related commands), Yarn has reimplemented all commands to gain full control over its developer experience and stability. It is faster, more secure, and more reliable. Yarn has the following features:
- Plugin support: Yarn supports plugins and provides an easy way to add them.
- Language support: While it natively supports Node, it can also support other languages through plugins.
- Yarn natively supports workspaces.
- Yarn uses a bash-like portable shell, enabling package scripts to work across Windows, Linux, and macOS.
- Yarn is the first package manager to offer a programmable Node API (via @yarnpkg/core).
- Yarn is written in TypeScript and is fully type-checked.
Reference:
# PNPM
Using the PNPM package manager can effectively save disk space and enable faster installations. For example, when using npm, if you have 100 projects and all of them depend on the same package, the disk will store 100 copies of that package. However, with pnpm, dependencies are stored in a centralized location, so:
- If different versions of the same dependency are needed, only the files that differ between versions are stored. For instance, if a dependency contains 100 files and a new version is released with only one file modified, running
pnpm updatewill add just the new file to the storage, rather than saving all files of the dependency due to a single change. - All files are stored in a centralized location on the disk. When installing packages, all their files are hard-linked from this location, avoiding additional disk space usage. This allows for easy sharing of the same version of dependencies across projects. In summary, in terms of the ratio of projects to dependencies, pnpm saves significant disk space and greatly speeds up installations.
In terms of installation speed, pnpm performs installations in three stages:
- Dependency resolution: Identifies all necessary dependencies and fetches them into the store.
- Directory structure calculation: The
node_modulesdirectory structure is calculated based on dependencies. - Linking dependencies: All remaining dependencies are fetched from the store and hard-linked into
node_modules. This approach is much faster than the traditional three-stage installation process of resolving, fetching, and writing all dependencies tonode_modules.
When using npm or Yarn Classic to install dependencies, all packages are hoisted to the root of node_modules. As a result, source code can access dependencies that are not explicitly defined for the current project. By default, pnpm uses symbolic links to add only the project's direct dependencies to the root of node_modules.
Overall, pnpm has the following characteristics:
- Fast: Up to 2 times faster than alternatives.
- Efficient: Files in
node_modulesare cloned or hard-linked from a single content-addressable store. - Well-suited for single repositories with multiple packages.
- Strict: Packages can only access dependencies specified in their
package.json. - Deterministic: Uses a lock file named
pnpm-lock.yaml. - It can manage Node.js versions.
- Supports Windows, Linux, and macOS.
More and more component libraries are choosing to use pnpm. If you are working with a monorepo (single repository with multiple packages), pnpm is a great choice.
Reference:
# Language
# JavaScript
JavaScript (JS) is a programming language and is one of the core technologies of the World Wide Web along with HTML and CSS. As of 2023, 98.7% of websites use JavaScript on the client side for webpage behavior. All major web browsers have dedicated JavaScript engines to execute code on users' devices.
JavaScript is a high-level, often just-in-time compiled language that conforms to the ECMAScript standard. It features dynamic typing, prototype-based object orientation, and first-class functions. It is multi-paradigm, supporting event-driven, functional, and imperative programming styles. It includes application programming interfaces (APIs) for working with text, dates, regular expressions, standard data structures, and the Document Object Model (DOM).
The ECMAScript standard does not include any input/output (I/O) functionality, such as networking, storage, or graphics. In practice, web browsers or other runtime systems provide JavaScript APIs for I/O.
JavaScript engines were initially used only in web browsers but have now become core components of some servers and various applications. The most popular runtime system for this purpose is Node.js.
Reference:
# TypeScript
TypeScript is a superset of JavaScript that extends JavaScript's syntax by adding an explicit type system, which performs type checking during transpilation. For example, while JavaScript provides language primitives like strings and numbers, it does not check whether you consistently assign these primitives. TypeScript, on the other hand, can. The main benefit of TypeScript is that it highlights unexpected behavior in your code, thereby reducing errors.
Type Inference
TypeScript automatically generates types in many cases. For instance, when creating a variable and assigning it a value, TypeScript will use the type of that value as the type of the variable. TypeScript builds a type system that accepts JavaScript code but includes types, without requiring additional characters to explicitly define types in the code.

Defining Types
For some design patterns where types are not easily inferred automatically, such as those involving dynamic programming, TypeScript supports extensions to the JavaScript language that allow you to specify types explicitly.
Building Types
TypeScript enables the creation of complex types by combining simpler types. There are two main ways to do this:
- Unions: You can declare that a type can be one of multiple types.
- Generics: Generics provide variables for types. A common example is arrays. An array without generics can contain anything, while an array with generics can describe the types of values it contains.
Structural Type System
One of the core principles of TypeScript is to check the shape of values in two objects. This is sometimes referred to as 'duck typing' or 'structural typing'. In a structural type system, if two objects have the same shape, they are considered to be of the same type. Reference:
# WebAssembly
WebAssembly (Wasm) is a portable, compact, fast-loading, and web-compatible format. It has the following characteristics:
- Efficient: WebAssembly has a complete set of semantics. In practice, Wasm is a compact and fast-loading binary format designed to fully utilize hardware capabilities to achieve native execution efficiency.
- Secure: WebAssembly runs in a sandboxed execution environment and can even be implemented within existing JavaScript virtual machines. In web environments, WebAssembly strictly adheres to the same-origin policy and browser security policies.
- Open: WebAssembly is designed with a well-structured text format for debugging, testing, experimenting, optimizing, learning, teaching, or writing programs. This text format allows viewing the source code of Wasm modules on web pages.
- Standard: WebAssembly is designed to be versionless, feature-testable, and backward-compatible on the web. WebAssembly can be used by JavaScript, integrated into JavaScript contexts, and can also invoke browser functionalities like Web APIs. Additionally, WebAssembly can run not only in browsers but also in non-web environments. WebAssembly aims to complement JavaScript and run alongside it, rather than replace JavaScript.
Reference:
# Onther languages
# CoffeeScript
CoffeeScript is a small language that can be compiled into JavaScript. It serves as syntactic sugar for JavaScript, introducing a shorter syntax that enables the writing of cleaner and more precise code. It is particularly popular among Ruby developers.
# Dart
Dart is an independent programming language with its own engine, capable of running in non-browser environments, such as mobile applications, but it can also be transpiled to JavaScript. It is developed by Google.
# Kotlin
Kotlin is a modern, concise, safe, and mature programming language that is interoperable with Java and other languages. It offers various methods for reusing code across multiple platforms to enable efficient programming.
# Front-end framework
A framework refers to a set of software tools or platforms available to web developers. Developers can use frameworks to build scalable websites and web applications. One of the main features of most frameworks is the use of reusable components or code, which, along with other functionalities of the framework, accelerates the development process. Frameworks can include code libraries, compilers, APIs, and more. This article will primarily focus on front-end frameworks, which are software platforms or tools used to visualize backend instructions in the user interface.
With the rapid development of front-end technologies, developers have many frameworks to choose from, each with its unique features. Therefore, when selecting a framework, developers need to consider the goals they aim to achieve with their business and choose the most suitable option.
Here we introduce some of the most widely used front-end frameworks:
# React
React is a JavaScript library for building user interfaces.
Declarative: React makes it easy to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render the right components when your data changes. Declarative views make your code more predictable, easier to understand, and simpler to debug.
Component-Based: React allows you to build components that manage their own state, and then compose these components to create complex UIs. Since component logic is written in JavaScript rather than templates, you can easily pass rich data through your application and keep state out of the DOM.
Learn Once, Write Anywhere: You can develop new features in React without rewriting existing code. React can also render on the server using Node and power mobile apps using React Native.
Reference:
# Vue
Vue.js is a progressive JavaScript framework that has quickly become one of the top web frameworks, often used for developing single-page applications. The framework combines the strengths of other frameworks, such as React's component system and Angular's data binding capabilities.
Vue.js utilizes two-way data binding, making it easier for developers to keep data and the UI in sync. Additionally, Vue.js features a high-performance virtual DOM implementation and offers server-side rendering support.
One of the advantages of using Vue.js is its simple syntax, which makes it easy to learn and use. Furthermore, Vue.js provides two-way data binding, allowing the user interface and the underlying data model to stay synchronized. Currently, Vue.js enjoys high usage in China.
Reference:
# Web Components
Web Components are a set of web platform APIs that enable the creation of new custom, reusable, and encapsulated HTML tags for use in web pages and applications. Custom components and widgets built on the Web Components standards can work across modern browsers and are compatible with any JavaScript library or framework that supports HTML. Web Components are based on the following four main technologies:
Custom Elements
A set of JavaScript APIs that allow you to define custom elements and their behavior, which can then be used in the user interface as needed.
Shadow DOM
A set of JavaScript APIs for attaching an encapsulated 'shadow' DOM tree to an element (rendered separately from the main document DOM) and controlling its associated functionality. This way, you can keep the element's functionality private, allowing it to be scripted and styled without worrying about conflicts with other parts of the document.
ES Modules
The ES Modules specification defines how to include and reuse JavaScript documents in a standardized, modular, and high-performance manner.
HTML Templates
The HTML template element specification defines how to declare markup fragments that are not used when the page loads but can be instantiated later during runtime.
Reference: