Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Node.js v12のES Modules / ES Modules on NodeJS v12

shimataro
October 25, 2019

Node.js v12のES Modules / ES Modules on NodeJS v12

関西Node学園 8時限目の発表資料です
https://nodejs.connpass.com/event/147459/

shimataro

October 25, 2019
Tweet

More Decks by shimataro

Other Decks in Technology

Transcript

  1. NODE.JS V12 のES MODULES NODE.JS V12 のES MODULES (2019/10/25) (2019/10/25)

    ⼩⽥島 太郎 / @shimataro 関⻄NODE 学園 8 時限⽬ 関⻄NODE 学園 8 時限⽬
  2. きっかけ きっかけ ⾃作のnpm パッケージを公開中 CommonJS / ES Modules どちらでも使える CI

    を導⼊ Node.js v12 のES Modules 版でコケていた v12 以外では問題なし CommonJS 版では問題なし どういうこと?
  3. COMMONJS おさらい COMMONJS おさらい ECMA 標準ではない(後に⼀部取り込まれた) モジュール管理 ←今回話すやつ ⾮同期処理 ファイル⼊出⼒

    etc CommonJS とは、サーバーサイドなどのウェブブラウザ環境 外におけるJavaScript の各種仕様を定めることを⽬標とした プロジェクトである。 (Wikipedia より)
  4. ES MODULES おさらい ES MODULES おさらい ECMAScript6(ES2015) で策定されたモジュール仕 様 関数や変数ではなく構⽂として導⼊

    Babel やTypeScript を使うとCommonJS 形式に変換 してくれる 今はこの⽅法が主流?(※個⼈の感想です) import fs from "fs"; export default () => { console.log("hell,word"); // 地獄の⾔葉 };
  5. NODE.JS とES MODULES NODE.JS とES MODULES v8.5.0 から実験的サポート Windows では絶対パスでimport

    するとエラーに なるので、v8.6.0 以降を使ってください 拡張⼦は .mjs --experimental-modules フラグが必要 // v8.5.x on Windows // "C" という URI スキームが⾒つからない import foo from "C:/path/to/foo";
  6. NODE.JS 開発チーム内での議論 NODE.JS 開発チーム内での議論 1. ブラウザと挙動あわせようず ブラウザ(script タグ)では拡張⼦必須 Node.js では拡張⼦省略可

    さらに foo/index.js は foo だけでimport 可 2. いつまでも .mjs はイヤだ 今後ES Modules 形式が⼀般的になっていくはず 10 年後も .js=CommonJS 形式でいいのか? 3. 現状との互換性も確保したい
  7. ブラウザと挙動あわせようず ブラウザと挙動あわせようず import ⽂で拡張⼦を必須にした CommonJS 形式には適⽤されない(拡張⼦省略可) By default in the

    new --experimental-modules, le extensions are mandatory in import statements: import ‘./ le.js’, not import ‘./ le’. // ./path/to/foo.mjs というファイルを import したい import foo from "./path/to/foo"; // NG import foo from "./path/to/foo.mjs"; // OK
  8. いつまでも いつまでも .MJS .MJS はイヤだ はイヤだ .mjs と .js をES

    Modules として扱う CommonJS では、新たな拡張⼦ .cjs を使う The .cjs extension provides a way to save CommonJS les in a project where both .mjs and .js les are treated as ES modules.
  9. 現状との互換性も確保したい(1) 現状との互換性も確保したい(1) いきなり .js をES Modules として扱われると困る package.json の設定で挙動を変える module:

    ES Modules 形式とみなす commonjs: CommonJS 形式とみなす (従来挙動& デフォルト) Add “type”: “module” to the package.json for your project, and Node.js will treat all .js les in your project as ES modules.
  10. 現状との互換性も確保したい(2) 現状との互換性も確保したい(2) いきなり拡張⼦を必須にされると困る コマンドラインオプションで挙動を変える node: 拡張⼦や index.js は省略可(従来挙動) explicit: 拡張⼦が必須(デフォルト)

    ※全ファイルに適⽤される(パッケージ単位の指定は 不可) However, the CommonJS-style automatic extension resolution behavior (‘./ le’) can be enabled via a new ag, --es-module- speci er-resolution=node.
  11. 対応⽅法: BABEL (1) 対応⽅法: BABEL (1) を使うとよさげ import の拡張⼦を⾃動付与してくれるプラグイン 相対パス(

    "." で始まるパス)のみ対応 うまくいかない場合もある 例)@babel/preset-env でPoly ll が埋め込まれる場合 babel-plugin-extension-resolver // パッケージ内のファイルを直接参照するコードが⽣成される // "." で始まらないので拡張⼦をつけてくれない import "core-js/modules/es.array.iterator";
  12. 対応⽅法: BABEL (2) 対応⽅法: BABEL (2) Babel に投げた , 取り込まれるまで

    --es-module-specifier- resolution=node でやり過ごしましょう Issue #10548 PR #10549
  13. 対応⽅法: TYPESCRIPT 対応⽅法: TYPESCRIPT TypeScript では対応不可? 「拡張⼦つけてよ」→「TS はJS のコード部分は変更 しないから無理だよ」

    解決⽅法を知っている⼈がいたら教えてください。 Issue #33588 TypeScript always emits JavaScript code as written, and import statements are JavaScript code so aren't changed on emit.
  14. まとめ(1) まとめ(1) ES Modules の挙動はv12 から変わったよ .js はES Modules 形式だよ

    import 時に拡張⼦必須だよ CommonJS とES Modules の両⽅に対応したパッケ ージは作れないよ ⼿品が好きな⼈はお話しましょう