0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【js】ESModules使用してみたメモ

Last updated at Posted at 2022-05-27

モジュールとは

ソースコードを機能毎に分割してメンテナンスしやすくする仕組み。
代表的なものとして下記二つがある

  • CJS(CommonJS)
  • ESM(ES Modules)

CommonJSとは

Node.js上でモジュールを管理する仕組み。
require / exportsというキーワードを使ってモジュールの読み込みや外部ファイルへの露出を行う。

ES Modulesとは

ECMAScriptの仕様に基づくモジュール管理システム。主にブラウザ側で使用。
import / exportというキーワードを使ってモジュールの読み込みや外部ファイルへの露出を行う。
ES Modulesの規格でexportされたものはES Modulesの規格でimportする必要があり、CommonJSの規格でexportsされたものはCommonJSの規格でrequireする必要がある。この二つのモジュールシステムを跨いでそれぞれのキーワードを使うことはできない。
ES Modulesの読み込みにはscriptタグのtype属性をmoduleにする

比較

ES Modules CommonJS 備考
読み込み / 露出キーワード import / export require / exports -
使用される場所 Browser Node.js ES ModulesはNode.js上でも動かせるが有効にするための条件がある
拡張子 .mjs .cjs js拡張子で問題ないが、どちらの仕組みで動いているのか明示的に分かるように、拡張子を分けている場合がある

ES Modulesの基本的なimport / export

exportしたいファイルmodulaA.js

modulaA.js
/**
 * exportしたい変数、関数の前にexportを記述
 */
export let publicVal = 0;
export function publicFn() {
   console.log('publicFn called: ')
}
//もうひとつ、exportする方法としてdefaultキーワードを使用したものがある
export default 1; //このdefaultに続く値が、このモジュールのデフォルトでexportされる値になる。

importしたいファイルmodulaB.js こちらを読み込ませる 例)<script type="module" src="moduleB.js"></script>

modulaB.js
/**
 * importする方法として、
 * import { exportされている変数名や関数名 } from "読み込む先のファイルを指定"
 * exportだけのものは必ず上記のように{}をつけて、importを行う。
 * defaultキーワードでexportされているものは任意の名前で定義してimportする。{}はいらない。
 * defaultキーワードを使ってexportされたものとそれ以外をimportするときはカンマ区切りで記述できる
 * 例)import defaultVal, { publicVal as val, publicFn as fn } from "./moduleA.js";
 */
//import { publicVal, publicFn } from "./moduleA.js";  //webpackなどモジュールを一つのファイルにまとめてくれるソフトを使うと.jsは省略できる場合がある。使っていない場合は拡張子まで必ずかく。
import defaultVal, { publicVal as val, publicFn as fn } from "./moduleA.js"; //このように as 変更後の名前 の形で、このファイル内でのみ使用できる名前を定義することができる
console.log(val);
fn();
console.log(defaultVal);
/**
 * 下記のように*を使った記述をするとオブジェクトの形で格納される
 * import defaultVal, * as moduleA from './moduleA.js';
 * console.log(moduleA.publicVal);
 */

モジュールコンテキストとモジュールスコープ

ES Modulesを使用した場合、グローバルコンテキストがモジュールコンテキストに切り替わる。
基本的にグローバルコンテキスト、モジュールコンテキストも挙動は似ている。
グローバルコンテキストでthisを使用した場合、グローバルオブジェクト(window)が参照できるが、モジュールコンテキストの場合は、thisが使用できない。
ES Modulesを使用した場合、スクリプトスコープがモジュールスコープに切り替わる。

modulaB.js
console.log(this);// -> undefined
function fn() {
   console.log(this);
}
fn();// -> undefined
const obj = {
   fn
}
obj.fn();// -> オブジェクトのメソッドとして呼び出す場合など、モジュールコンテキスト以外であればthisは使用できる。

モジュールの特徴

type属性'module'はデフォルトでdefar属性が付与され、
htmlの構文解析が終わったタイミングでscriptが実行される非同期的な処理となる。
一度読み込まれると、同じものは読み込まれない。
nomodule属性を付与するとモジュールに対応していないブラウザにのみ、そのscriptタグが読み込まれる。

モジュールの場合は常にstrictモード

strictモードとは
通常のJavaScriptで許容されている一部の書き方を制限する方法。従来のjs記法ではバグにならなかったものもエラー表示してくれることで、意図しないバクの混入、予約語の確保、コードのセキュア化などのメリットがある。
ファイルの先頭、もしくは関数内の先頭行にuse strictの記述するとStrictモードが有効化される。
そのstrictモードがモジュールの場合では常に有効化されていて、上記記述をする必要がない。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?