Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use native ESM #101

Open
akabekobeko opened this issue Jun 1, 2021 · 5 comments
Open

Use native ESM #101

akabekobeko opened this issue Jun 1, 2021 · 5 comments
Assignees
Labels
Milestone

Comments

@akabekobeko
Copy link
Member

Given that Node.js 12 has become a MAINTENANCE LTS, some npm that VFM depends on is also native ESM. VFM will eventually have to support these.

@akabekobeko akabekobeko added this to the v2.0.0 milestone Jun 1, 2021
@akabekobeko akabekobeko self-assigned this Jun 1, 2021
@akabekobeko
Copy link
Member Author

試しに ESM 化された doctype 3.0.0 だけ更新して npm test してみたらエラーになった。

 FAIL  tests/attr.test.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    .../vfm/node_modules/doctype/index.js:3
    export var doctypes = {
    ^^^^^^

    SyntaxError: Unexpected token 'export'

       7 |  */
       8 |
    >  9 | import doctype from 'doctype';
         | ^
      10 | import { Properties } from 'hast';
      11 | import h from 'hastscript';
      12 | import { Node } from 'unist';

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1479:14)
      at Object.<anonymous> (src/plugins/document.ts:9:1)

Test Suites: 14 failed, 14 total
Tests:       0 total
Snapshots:   0 total
Time:        8.27 s
Ran all test suites.

@akabekobeko
Copy link
Member Author

ts-jest が未対応なので以下の設定を試すもエラーは直らず。

tsconfig.json

allowJs を追加。

{
  "exclude": ["tests", "lib"],
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "outDir": "./lib",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "allowJs": true
  }
}

jest.config.js

globals を追加、preset を変更。

module.exports = {
  globals: {
    'ts-jest': {
      useESM: true,
    },
  },
  preset: 'ts-jest/presets/js-with-ts-esm',
  testEnvironment: 'node',
  testMatch: ['**/?(*.)+(spec|test).ts?(x)'],
  testPathIgnorePatterns: ['lib'],
};

@akabekobeko
Copy link
Member Author

簡単な設定変更で対応可能なら 1.0、難しければ 2.0 へ見送る。現時点では 2.0 としておく。

@akabekobeko
Copy link
Member Author

現状のわかりやすいまとめ。簡単な設定変更では対応できなさそうだ。

@akabekobeko
Copy link
Member Author

remark v13 以降へ対応するための micromark 調査用に作成したプロジェクトで ts-jest による Native ESM を試してみた。

Jest v27 系なら以下の設定でゆける。

  1. npm-scripts のテスト コマンドにおける Jest 実行環境の Node.js を ESM 対応モードにする
  2. Jest 設定で ESM の有効化と JS の EMS 変換用 preset を追加

1 は package.json にて npm-scripts の jest コマンド前にオプションを設定すればよい。

{
  "scripts": {
    "test": "NODE_OPTIONS=--experimental-vm-modules jest",
  }
}

2 は Jest 設定が jest.config.js に定義されているなら以下のように書く。

module.exports = {
  transform: {
    '^.+\\.ts$': 'ts-jest'
  },
  preset: 'ts-jest/presets/js-with-ts-esm',
  globals: {
    'ts-jest': {
      useESM: true
    }
  }
}

この方法では TypeScript から ESM な JS を import する際、拡張子 .js は省略したままでも実行に成功。tsc や webpack ではなく Jest (ts-jest) を通すだけならこれでゆけた。

@akabekobeko akabekobeko modified the milestones: v2.0.0, v3.0 Oct 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant