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
    時限⽬

    View full-size slide

  2. ⾃⼰紹介
    ⾃⼰紹介
    ⼩⽥島 太郎
    Web
    エンジニア(最近はインフラ寄り)
    趣味は⼿品
    ⼿品業界→Web
    業界
    実は関⻄Node
    学園の⽴ち上げにも関わ
    ってます
    https://shimataro.me

    View full-size slide

  3. この発表について(1)
    この発表について(1)
    対象者
    ES Modules
    って何?
    Node.js v12
    で何か変わったの?
    ⾮対象者
    Node.js
    を触ったことないよ
    v12
    の変更点もちゃんとフォローしてるよ

    View full-size slide

  4. この発表について(2)
    この発表について(2)
    ゴール
    ES Modules
    について理解し、使えるようになる
    Node.js v12
    で有効なコードを書けるようになる
    ↓スライドはこちら↓
    https://speakerdeck.com/shimataro
    https://shimataro.me/slides/

    View full-size slide

  5. ⽬次
    ⽬次
    きっかけ
    CommonJS
    ES Modules
    相互運⽤
    v12
    での変更点
    対応⽅法
    まとめ

    View full-size slide

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

    View full-size slide

  7. きっかけ
    きっかけ
    ⾃作のnpm
    パッケージを公開中
    CommonJS / ES Modules
    どちらでも使える
    CI
    を導⼊
    Node.js v12
    のES Modules
    版でコケていた
    v12
    以外では問題なし
    CommonJS
    版では問題なし
    どういうこと?

    View full-size slide

  8. COMMONJS
    COMMONJS

    View full-size slide

  9. COMMONJS
    おさらい
    COMMONJS
    おさらい
    ECMA
    標準ではない(後に⼀部取り込まれた)
    モジュール管理 ←今回話すやつ
    ⾮同期処理
    ファイル⼊出⼒ etc
    CommonJS
    とは、サーバーサイドなどのウェブブラウザ環境
    外におけるJavaScript
    の各種仕様を定めることを⽬標とした
    プロジェクトである。 (Wikipedia
    より)

    View full-size slide

  10. NODE.JS
    とCOMMONJS
    NODE.JS
    とCOMMONJS
    Node.js
    ではCommonJS
    形式のモジュールをサポート
    最近は使うことは少なくなった(※個⼈の感想です)
    // import
    const fs = require("fs");
    // export
    module.exports = () => {
    console.log("hell,word"); //
    地獄の⾔葉
    };

    View full-size slide

  11. ES MODULES
    ES MODULES

    View full-size slide

  12. ES MODULES
    おさらい
    ES MODULES
    おさらい
    ECMAScript6(ES2015)
    で策定されたモジュール仕

    関数や変数ではなく構⽂として導⼊
    Babel
    やTypeScript
    を使うとCommonJS
    形式に変換
    してくれる
    今はこの⽅法が主流?(※個⼈の感想です)
    import fs from "fs";
    export default () => {
    console.log("hell,word"); //
    地獄の⾔葉
    };

    View full-size slide

  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";

    View full-size slide

  14. 相互運⽤
    相互運⽤
    module.exports
    したものを
    import
    する場合
    export
    したものを
    require()
    する場合

    View full-size slide

  15. 相互運⽤
    相互運⽤
    できんことないけどやめたほうがいい
    Native ES Modules - something almost, but not quite entirely unlike CommonJS by Gil Tayor

    View full-size slide

  16. ここから本題
    ここから本題
    ここの記事の内容です。
    Announcing a new --experimental-modules
    https://medium.com/@nodejs/announcing-a-new-
    experimental-modules-1be8d2d6c2ff

    View full-size slide

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

    View full-size slide

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

    foo
    だけでimport

    2.
    いつまでも
    .mjs
    はイヤだ
    今後ES Modules
    形式が⼀般的になっていくはず
    10
    年後も
    .js=CommonJS
    形式でいいのか?
    3.
    現状との互換性も確保したい

    View full-size slide

  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

    View full-size slide

  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.

    View full-size slide

  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.

    View full-size slide

  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.

    View full-size slide

  23. 対応⽅法
    対応⽅法
    Node.js v12
    に対応したコードの書き⽅

    View full-size slide

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

    View full-size slide

  25. 対応⽅法: BABEL (1)
    対応⽅法: BABEL (1)
    を使うとよさげ
    import
    の拡張⼦を⾃動付与してくれるプラグイン
    相対パス(
    "."
    で始まるパス)のみ対応
    うまくいかない場合もある
    例)@babel/preset-env
    でPoly ll
    が埋め込まれる場合
    babel-plugin-extension-resolver
    //
    パッケージ内のファイルを直接参照するコードが⽣成される
    // "."
    で始まらないので拡張⼦をつけてくれない
    import "core-js/modules/es.array.iterator";

    View full-size slide

  26. 対応⽅法: BABEL (2)
    対応⽅法: BABEL (2)
    Babel
    に投げた ,
    取り込まれるまで
    --es-module-specifier-
    resolution=node
    でやり過ごしましょう
    Issue #10548 PR #10549

    View full-size slide

  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.

    View full-size slide

  28. 対応⽅法:
    パッケージ作成
    対応⽅法:
    パッケージ作成
    新しい仕様でCommonJS
    とES Modules
    の両⽅に対応
    したパッケージはどうやって作るの?

    View full-size slide

  29. 対応⽅法:
    パッケージ作成
    対応⽅法:
    パッケージ作成
    無理
    パッケージの汎⽤性にこだわりたい場合は、従来仕様

    "type": "commonjs"
    を設定しましょう
    Currently, it is not possible to create a package that can be used
    via both require(‘pkg’) and import ‘pkg’.

    View full-size slide

  30. まとめ(1)
    まとめ(1)
    ES Modules
    の挙動はv12
    から変わったよ
    .js
    はES Modules
    形式だよ
    import
    時に拡張⼦必須だよ
    CommonJS
    とES Modules
    の両⽅に対応したパッケ
    ージは作れないよ
    ⼿品が好きな⼈はお話しましょう

    View full-size slide

  31. まとめ(2)
    まとめ(2)
    ゴール(再掲)
    ES Modules
    について理解し、使えるようになる
    Node.js v12
    で有効なコードを書けるようになる
    ⼿品に興味を持つ

    View full-size slide

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

    View full-size slide