import 在线引包——ESM CDN

1,814 阅读1分钟

前言:

了解 deno 的朋友应该熟悉下面的语法:

import { serve } from "https://deno.land/std@0.160.0/http/server.ts";
serve(req => new Response("Hello World\n"));

现在这样的语法也可以在前端浏览器环境里使用了,直接以 CDN 的形式 import 一个 npm 包。用过 vite 的朋友可能觉得非常熟悉,就是把 vite dev 模式的包从本地路径换成了 CDN 地址。

ESM CDN:

介绍一个神奇的网站:esm.sh/

简单的用法介绍:

我们可以在 html 文件的 <script type="module"> 标签里直接使用这样的代码:

import React from "https://esm.sh/react" // 18.2.0

可以用这样的方式指定包的版本:

import React from "https://esm.sh/react@17.0.2"

指定引用包的依赖:

可以使用 ?deps=PACKAGE@VERSION 的查询参数语法指定npm包所依赖的子npm包的版本,多个子npm包,用,分开, 比如:?deps=react@17.0.2,react-dom@17.0.2

import useSWR from "https://esm.sh/swr?deps=react@17.0.2"

举个例子:

笔者是在学习 react-three-fiber (rf3) 时,在 rf3 的文档中发现的 esm 这种 cdn 的用法:

docs.pmnd.rs/react-three…

下述代码是简单修改了 r3f 文档中的例子,粘贴下面代码到你的本地,保存成 .html 文件就可以直接食用啦~(就像你刚接触前端,使用记事本写代码时一样^_^

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        #root {
            width: 100%;
            height: 500px;
        }
    </style>
</head>
<body>
    <div id="root"></div>
    <script type="module">
        import ReactDOM from 'https://esm.sh/react-dom'
        import React, { useRef, useState } from 'https://esm.sh/react'
        import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber'
        import htm from 'https://esm.sh/htm'

        const html = htm.bind(React.createElement)

        function Box(props) {
            const mesh = useRef()
            const [hovered, setHover] = useState(false)
            const [active, setActive] = useState(false)
            useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01))
            return html`
            <mesh
                ...${props}
                ref=${mesh}
                scale=${active ? 1.5 : 1}
                rotation=${[Math.PI / 2, 0, 0]}
                onClick=${() => setActive(!active)}
                onPointerOver=${() => setHover(true)}
                onPointerOut=${() => setHover(false)}
            >
                <boxGeometry args=${[2, 1, 1]} />
                <meshStandardMaterial color=${'#6DF2E6'} />
            </mesh>`
        }

        ReactDOM.render(
        html`
        <${Canvas}>
            <ambientLight />
            <pointLight position=${[10, 10, 10]} />
            <${Box} position=${[-1.2, 0, 0]} />
        <//>`,
        document.getElementById('root'),
        )
    </script>
</body>
</html>

总结:

本文介绍了使用 cdn 方式引用 ESM的方法。

笔者能想到的一种应用场景:可以更快地在本地尝试一些 demo 而不必等待 create-react-app 或者 npm install 去下载 node-modules 的漫长时间……(当然你也可以使用 codepen.io/)