[[JavaScript]]章では最後のLessonになります。[[JavaScript]]、そして[[TypeScript]]を実利用するうえで大きな障壁となりうる[[モジュール (JavaScript)|モジュール]]について理解しましょう。 ## Reference - [ECMAScriptモジュール · JavaScript Primer \#jsprimer](https://jsprimer.net/basic/module/) ## Lesson [[モジュール (JavaScript)|モジュール]]とは、プログラムを機能ごとに分割し、再利用性を高めるためにそれらをexport/importできるようにする仕組みのことです。 [[JavaScript]]で扱うことのできる[[モジュール (JavaScript)|モジュール]]にはいくつか種類があります。ここでは、モダンかつ[[Deno]]でも利用できる[[ESモジュール (JavaScript)|ESモジュール]]についてのみピックアップします。 > [!attention] > これから説明する内容は、各単元において完全な説明ではありません。重要な点のみを理解しやすくするため、**敢えて説明を省いて**います。正式な定義や説明は一次情報をご覧ください。 ### ESモジュール 正式名称は[[ESモジュール (JavaScript)|ECMAScript modules]]ですが、呼びやすさから[[ESモジュール (JavaScript)|ESモジュール]]や[[ESモジュール (JavaScript)|ESM]]と呼ばれることが多いです。 `import` でインポート、`export` でエクスポートを行います。[[import (ESM)|import]]と[[export (ESM)|export]]にはいくつか種類がありますが、特に知っておいた方がいいのは以下3つです。 - [[名前付きexport (ESM)|名前付きexport]] - [[名前付きimport (ESM)|名前付きimport]] - [[名前空間import (ESM)|名前空間import]] ### 名前付きexport 頭に `export` キーワードを追加することで、[[名前付きimport (ESM)|名前付きimport]]や[[名前空間import (ESM)|名前空間import]]でそれらをインポートできるようになります。 ```js // libs.js export const name = "tatsuwo"; export function hello() { console.log("hello"); } ``` ### 名前付きimport [[名前付きexport (ESM)|名前付きexport]]でエクスポートした変数や関数などをインポートして使用できます。 ```js import { hello, name } from "./libs.js"; console.log(name); hello(); ``` ### 名前空間import [[名前付きexport (ESM)|名前付きexport]]で指定した変数や関数などを**1つの[[namespace (JavaScript)|名前空間]]として**インポートできます。 ```js import * as libs from "./libs.js"; console.log(libs.name); libs.hello(); ``` ### その他 使用するライブラリによっては、[[デフォルトexport (ESM)|デフォルトexport]]を使っています。[[デフォルトimport (ESM)|デフォルトimport]]とセットで認知はしておきましょう。 ## Mission 1 #😁EASY 以下のファイルから `sum3` の定義を別ファイル `./libs.js` に切り出すようにリファクタリングしてください。 ```js function sum3(x, y, z) { return x + y + z; } const r = sum3(1, 10, 100); console.log(r); ``` %% 解答例 ```js import { sum3 } from "./libs.js"; const r = sum3(1, 10, 100); console.log(r); ``` `libs.js` ```js export function sum3(x, y, z) { return x + y + z; } ``` %% ## Mission 2 #🙂NORMAL `./libs` 配下に以下2つのファイルがあります。 ```js // ./libs/dog.js export function getAsJapanese() { return "犬"; } ``` ```js // ./libs/cat.js export function getAsJapanese() { return "猫"; } ``` 以下のコードをFIXMEコメントの要件を満たすように書き換えてください。 ```js // FIXME:"犬" と "猫" を libs配下のgetAsJapaneseから取得する console.log(`私は犬と猫が好きです`); ``` %% 解答例 ```js import * as dog from "./libs/dog.js"; import * as cat from "./libs/cat.js"; console.log(`私は${dog.getAsJapanese()}と${cat.getAsJapanese()}が好きです`); ``` または ```js import { getAsJapanese as dogAsJapanese } from "./libs/dog.js"; import { getAsJapanese as catAsJapanese } from "./libs/cat.js"; console.log(`私は${dogAsJapanese()}と${catAsJapanese()}が好きです`); ``` %% ## Mission 3 #😵HARD 次の説明の中で正しいものを1つ選び、他の選択肢がなぜ間違っているかも説明してください。 A. [[TypeScript]]のimport/exportに関する仕様は[[ESモジュール (JavaScript)|ESモジュール]]の仕様と同一である B. [[Node.js]]のv22では、[[ESモジュール (JavaScript)|ESモジュール]]か[[CommonJS]]かの判定をファイルに記載されたコードから自動で判別することもできる C. [[Deno]]は[[ESモジュール (JavaScript)|ESM]]のみをサポートしており、[[CommonJS]]には対応していない D. ブラウザでは[[ESモジュール (JavaScript)|ESM]]によるimportは利用できないので[[バンドラー]]を使う必要がある %% 解答例 正解はB. A. [[TypeScript]]は[[ESモジュール (JavaScript)|ESモジュール]]の仕様を踏襲しているが、同じではない C. [[Deno]]は[[CommonJS]]も可能な限りサポートしている D. ブラウザは `<script type="module">` で [[ESモジュール (JavaScript)|ESM]]をサポートしている %% > [!hint]- Hint 1 > - [TypeScript: Documentation \- Modules](https://www.typescriptlang.org/docs/handbook/2/modules.html) > [!hint]- Hint 2 > - [Modules: ECMAScript modules \| Node\.js v22\.14\.0 Documentation](https://nodejs.org/download/release/latest-v22.x/docs/api/esm.html#enabling) > [!hint]- Hint 3 > - [Deno 2\.1: Wasm Imports and other enhancements](https://deno.com/blog/v2.1#better-commonjs-support) ## Mission 4 #😵HARD [[#Mission 2]]のコードを[[CommonJS]]に変換してください。 %% 解答例 ```js // ./libs/cat.js exports.getAsJapanese = () => "猫"; ``` ```js // ./libs/dog.js exports.getAsJapanese = () => "犬"; ``` ```js const dog = require("./libs/dog.js"); const cat = require("./libs/cat.js"); console.log(`私は${dog.getAsJapanese()}と${cat.getAsJapanese()}が好きです`); ``` ```json // package.json { "type": "commonjs" } ``` %% > [!hint]- Hint 1 > - [Deno 2\.1: Wasm Imports and other enhancements](https://deno.com/blog/v2.1#better-commonjs-support) > - [Modules: CommonJS modules \| Node\.js v22\.14\.0 Documentation](https://nodejs.org/download/release/latest-v22.x/docs/api/modules.html) --- *NEXT* >> [[📗TDQ-BOSS3 さらばJavaScriptの世界よ]]