3

在浏览器中通过 importmap 使用 ES 模块

 2 years ago
source link: https://beginor.github.io/2021/08/16/using-es-modules-in-borwser-with-importmaps.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在浏览器中通过 importmap 使用 ES 模块

ES 模块简介

ES Module 是 JavaScript 模块化的官方标准, 目前主流的浏览器已经实现,不依赖任何第三方加载器 (Loader) 即可使用。

image-20210816080029432

点击此链接查看最新的浏览器支持情况

在浏览器中, 可以这样使用原生 ES 模块化的 JavaScript 脚本:

// my_func.js
export function my_func() {
  /* function content goes here */
}
<script type="module">
import { my_func } from './my_func.js';
my_func();
</script>

浏览器中只支持相对路径或者绝对路径下的 ES 模块 (./, ../, /, http://, https://) , 同时也受服务器跨域请求策略、 HTTPS 策略的约束。

import-maps 简介

在 Node.js 环境下, 可以这样导入全局模块:

import * as _loadash from 'loadash';

Node.js 会自动从 node_modules 目录中去加载对应的模块, 但是浏览器默认不会这样做,因为不知道从哪里加载全局模块。

import-maps 就是为了解决浏览器中的全局模块而出现的, 目前浏览器的支持情况如下图所示, 基于 Chromium 的浏览器已经实现这个功能。

image-20210816091336420

点击此链接查看浏览器的最新支持情况

对于不支持 import-maps 的浏览器, 可以使用 es-module-shims 进行处理。

import-maps 使用 Json 的形式来定义浏览器中的全局模块:

<script type="importmap">
{
  "imports": {
    "loadash": "/libs/loadash/index.js",
    "jquery": "/libs/jquery/index.js",
    "three": "/libs/three.js/three.js",
    "three/examples/": "/libs/three.js/examples/"
  }
}
</script>

全局 ES 模块的定义分两种形式:

  • 通过别名指定模块的地址, 适用于只有一个 js 文件的模块;
  • 通过路径指定模块的目录,适用于多个js文件组成的模块;

有了上面的 importmap 定义, 可以在浏览器环境中这样使用全局模块:

import * as _loadash from 'loadash'; // 自动加载 /libs/loadash/index.js
import $ from 'jquery'; // 自动加载 /libs/jquery/index.js
import { Scene, WebGLRenderer } from 'three'; // 自动加载 /libs/three.js/three.js
import { CinematicCamera } from 'three/examples/jsm/cameras/CinematicCamera.js' // 自动加载 /libs/three.js/examples/jsm/cameras/CinematicCamera.js

在浏览器中使用 import-maps 和 ES 模块

下面以两个具体的示例, 来说明怎么在浏览器中使用 import-maps 和 ES 模块。

  1. 在浏览器中直接使用 Vue3 提供的 ES 模块

    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Vue</title>
    </head>
    <body>
      <div id="root">
      </div>
      <script type="importmap">
      {
        "importmap": {
          "vue": "https://unpkg.com/browse/[email protected]/dist/vue.runtime.esm-browser.js",
          "vue-router": "https://unpkg.com/browse/[email protected]/dist/vue-router.esm-browser.js"
        }
      }
      </script>
      <script type="module">
      import { createApp } from 'vue';
         
      const app = createApp({
        template: '<div></div>',
        data(): { counter: number; } {
          return { counter: 0 };
        },
        mounted(): void {
          setInterval(() => { this.counter ++; }, 1000 );
        }
      });
       
      app.mount('#root');
      </script>
    </body>
    </html>
    
  2. 在浏览器中直接使用 ArcGIS JS API 4.20 提供的 ES 模块

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>ArcGIS JS API ES Module Demo</title>
      <link id="mapstyle-link" rel="stylesheet" href="https://js.arcgis.com/4.20/@arcgis/core/assets/esri/themes/dark/main.css">
      <style>
      html,body,#mapview {
        width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
      }
      </style>
    </head>
    <body>
      <div id="mapview"></div>
      <script type="importmap">
      {
        "imports": {
          "@arcgis/": "https://js.arcgis.com/4.20/@arcgis/"
        }
      }
      </script>
      <script type="module">
      import Map from '@arcgis/core/Map.js';
      import MapView from '@arcgis/core/views/MapView.js';
      import * as intl from "@arcgis/core/intl.js";
       
      intl.setLocale('zh-CN');
       
      const map = new Map({
        basemap: 'dark-gray-vector',
        ground: 'world-elevation',
      });
       
      const view = new MapView({
        container: 'mapview',
        map: map,
        zoom: 7,
        center: [113.2, 23.4],
        viewingMode: 'global'
      });
      </script>
    </body>
    </html>
    

上面的示例都是使用互联网上的 ES 模块, 也可以将这些模块下载到本地来使用, 只需要更改 importmap 中映射的地址即可。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK