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

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

D79a0829d09a325462fc9a1462ec503b?s=47 shimataro
October 25, 2019

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

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

D79a0829d09a325462fc9a1462ec503b?s=128

shimataro

October 25, 2019
Tweet

Transcript

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

    ⼩⽥島 太郎 / @shimataro 関⻄NODE 学園 8 時限⽬ 関⻄NODE 学園 8 時限⽬
  2. ⾃⼰紹介 ⾃⼰紹介 ⼩⽥島 太郎 Web エンジニア(最近はインフラ寄り) 趣味は⼿品 ⼿品業界→Web 業界 実は関⻄Node

    学園の⽴ち上げにも関わ ってます https://shimataro.me
  3. この発表について(1) この発表について(1) 対象者 ES Modules って何? Node.js v12 で何か変わったの? ⾮対象者

    Node.js を触ったことないよ v12 の変更点もちゃんとフォローしてるよ
  4. この発表について(2) この発表について(2) ゴール ES Modules について理解し、使えるようになる Node.js v12 で有効なコードを書けるようになる ↓スライドはこちら↓

    https://speakerdeck.com/shimataro https://shimataro.me/slides/
  5. ⽬次 ⽬次 きっかけ CommonJS ES Modules 相互運⽤ v12 での変更点 対応⽅法

    まとめ
  6. それでは始めます それでは始めます

  7. きっかけ きっかけ ⾃作のnpm パッケージを公開中 CommonJS / ES Modules どちらでも使える CI

    を導⼊ Node.js v12 のES Modules 版でコケていた v12 以外では問題なし CommonJS 版では問題なし どういうこと?
  8. COMMONJS COMMONJS

  9. COMMONJS おさらい COMMONJS おさらい ECMA 標準ではない(後に⼀部取り込まれた) モジュール管理 ←今回話すやつ ⾮同期処理 ファイル⼊出⼒

    etc CommonJS とは、サーバーサイドなどのウェブブラウザ環境 外におけるJavaScript の各種仕様を定めることを⽬標とした プロジェクトである。 (Wikipedia より)
  10. NODE.JS とCOMMONJS NODE.JS とCOMMONJS Node.js ではCommonJS 形式のモジュールをサポート 最近は使うことは少なくなった(※個⼈の感想です) // import

    const fs = require("fs"); // export module.exports = () => { console.log("hell,word"); // 地獄の⾔葉 };
  11. ES MODULES ES MODULES

  12. ES MODULES おさらい ES MODULES おさらい ECMAScript6(ES2015) で策定されたモジュール仕 様 関数や変数ではなく構⽂として導⼊

    Babel やTypeScript を使うとCommonJS 形式に変換 してくれる 今はこの⽅法が主流?(※個⼈の感想です) import fs from "fs"; export default () => { console.log("hell,word"); // 地獄の⾔葉 };
  13. 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";
  14. 相互運⽤ 相互運⽤ module.exports したものを import する場合 export したものを require() する場合

  15. 相互運⽤ 相互運⽤ できんことないけどやめたほうがいい Native ES Modules - something almost, but

    not quite entirely unlike CommonJS by Gil Tayor
  16. ここから本題 ここから本題 ここの記事の内容です。 Announcing a new --experimental-modules https://medium.com/@nodejs/announcing-a-new- experimental-modules-1be8d2d6c2ff

  17. V12 での変更点 V12 での変更点 破壊的変更がいろいろ。

  18. NODE.JS 開発チーム内での議論 NODE.JS 開発チーム内での議論 1. ブラウザと挙動あわせようず ブラウザ(script タグ)では拡張⼦必須 Node.js では拡張⼦省略可

    さらに foo/index.js は foo だけでimport 可 2. いつまでも .mjs はイヤだ 今後ES Modules 形式が⼀般的になっていくはず 10 年後も .js=CommonJS 形式でいいのか? 3. 現状との互換性も確保したい
  19. ブラウザと挙動あわせようず ブラウザと挙動あわせようず 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
  20. いつまでも いつまでも .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.
  21. 現状との互換性も確保したい(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.
  22. 現状との互換性も確保したい(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.
  23. 対応⽅法 対応⽅法 Node.js v12 に対応したコードの書き⽅

  24. 対応⽅法: 基本 対応⽅法: 基本 import 対象のファイルに拡張⼦をつける package.json に以下を追加 { ...

    "type": "module", ... }
  25. 対応⽅法: BABEL (1) 対応⽅法: BABEL (1) を使うとよさげ import の拡張⼦を⾃動付与してくれるプラグイン 相対パス(

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

    --es-module-specifier- resolution=node でやり過ごしましょう Issue #10548 PR #10549
  27. 対応⽅法: 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.
  28. 対応⽅法: パッケージ作成 対応⽅法: パッケージ作成 新しい仕様でCommonJS とES Modules の両⽅に対応 したパッケージはどうやって作るの?

  29. 対応⽅法: パッケージ作成 対応⽅法: パッケージ作成 無理 パッケージの汎⽤性にこだわりたい場合は、従来仕様 の "type": "commonjs" を設定しましょう

    Currently, it is not possible to create a package that can be used via both require(‘pkg’) and import ‘pkg’.
  30. まとめ(1) まとめ(1) ES Modules の挙動はv12 から変わったよ .js はES Modules 形式だよ

    import 時に拡張⼦必須だよ CommonJS とES Modules の両⽅に対応したパッケ ージは作れないよ ⼿品が好きな⼈はお話しましょう
  31. まとめ(2) まとめ(2) ゴール(再掲) ES Modules について理解し、使えるようになる Node.js v12 で有効なコードを書けるようになる ⼿品に興味を持つ

  32. ありがとうございました ありがとうございました