この記事は筆者のソロ Advent Calendar 2022 16日目の記事です。
Denoの公式ドキュメントの内容を実際に動かしてみてDenoに入門してみたのでその備忘録の続きです。
今回はDenoでnpmモジュールを使用する方法について試してみたいと思います。
Deno入門[インストール、環境構築、ファイル実行、標準ライブラリ]
Deno入門[CLIコマンド、モジュール、環境変数、Webフレームワーク]
Deno入門[npmモジュールの使用] <- 今ここ
Deno入門[prisma + oakで作るAPI]
Deno入門[テスト編]
Denoのnpm対応について
Denoは最初npmの対応はしていなかったようですが、Bunのようなnodeよりも速く、npmにも対応したランタイムの登場の影響かはわかりませんがnpm対応がされました。
執筆時点(v1.28.2)でDenoでnpmを使用するにはnpm specifiersまたはCDNを利用することで利用が可能となるようです。
npm specifiersでnpmモジュールを使用する
Denoのnpm specifiersはまだ完全に安定したものではないためCDNでの利用の方が安定していたようですがDeno 1.28よりnpmのサポートは安定してきたようです。とはいえ、まだnpm specifiersのみでnpmモジュールの利用が不完全な時はCDNを利用する必要があるようです。
Denoでexpressを使用してみる
import express from "npm:express@^4.18";
const app = express();
app.get("/", function (_: any, res: any) {
res.send("Hello World");
});
app.listen(3000);
console.log("listening on http://localhost:3000/");
deno run --allow-read --allow-env --allow-net npm/express.ts
listening on http://localhost:3000/
% curl localhost:3000
Hello World
上記のようにnpm:<パッケージ名>[@バージョン][/サブパス]
の形式でimportして使用することが可能。
CDNでnpmモジュールを使用する
CDNはUNPKGのようによく知られたものからいくつか選択肢があり、選べるようだがDenoで利用することを想定したDenoフレンドリーのCDNがあるためそれを使うといいかもしれない。
DenoフレンドリーなCDNには例えばesm.shがあり使用は以下のようになる。
import React from "https://esm.sh/react";
export default class A extends React.Component {
render() {
return <div></div>
}
}
DenoでReactを使ってみる
公式ドキュメントに代表的なnpmモジュールの使用ガイドが記載されていますが、今回はせっかくなのでReactをガイドに従って使用してみたいと思います。
create vite extra
DenoでReactアプリをscaffoldするのにcreate-vite-extraを利用することができる。
deno run --allow-env --allow-read --allow-write npm:create-vite-extra
reactを選択し起動してみる。
deno task dev
動いた!
react-router-dom
を追加してページ遷移も試してみる。
import { defineConfig } from "npm:vite@^3.1.3";
import react from "npm:@vitejs/plugin-react@^2.1";
import "npm:react@^18.2";
import "npm:react-dom/client@^18.2";
+ import "npm:react-router-dom@^6.4"; // Add this line
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
});
import React from 'react'
import ReactDOM from 'react-dom/client'
import {
BrowserRouter as Router,
Route,
Routes,
} from "react-router-dom";
import App from './App'
import './index.css'
import Hello from './pages/Hello.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<Router>
<Routes>
<Route exact path="/" element={<App />} />
<Route exact path="/hello" element={<Hello message="Deno!!" />} />
</Routes>
</Router>
</React.StrictMode>
)
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import './App.css'
function App() {
const [count, setCount] = useState(0)
return (
<div className="App">
<img src="/vite-deno.svg" alt="Vite with Deno" />
<div>
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" className="logo" alt="Vite logo" />
</a>
<a href="https://reactjs.org" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.jsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
+ <a href="/hello">To Hello Deno!!</a>
</div>
)
}
export default App
まとめ
まだDenoでのnpmモジュールの対応は開発段階のため、実プロジェクトでの採用は難しいかもしれませんが触った感じ普通に使えて、フロントエンドのの開発に慣れていない筆者にとってはかなり快適に開発できました。npmに対応したことでJS周辺のライブラリを利用する時にDenoでの利用が選択できるため個人的に手元で何かやる時は積極的にDenoを使っていきたいなと思います!