Skip to content

Instantly share code, notes, and snippets.

@alalonde
Last active October 13, 2022 00:24
Show Gist options
  • Save alalonde/1430bd9b777d88a514c09623cb381443 to your computer and use it in GitHub Desktop.
Save alalonde/1430bd9b777d88a514c09623cb381443 to your computer and use it in GitHub Desktop.
Converting a node.js Typescript monorepo over to ESM modules
  • update package.json of dependent modules (e.g. utils):
      "type": "module",
      "main": "dist/index.mjs",
      "types": "dist/index.d.mts",
    
  • Install new eslint plugins:
      "eslint-plugin-node": "^11.1.0",
      "eslint-import-resolver-typescript": "^3.5.1",
      "eslint-plugin-import": "^2.25.4",
    
  • Update eslint with some new rules / plugins:
    plugins: ['import', ...],
    settings: {
      "import/parsers": {
        "@typescript-eslint/parser": [".ts", ".tsx"]
      },
      "import/resolver": {
        "typescript": {
          "alwaysTryTypes": true, // always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
          // Multiple tsconfigs (Useful for monorepos)
          "project": "packages/*/tsconfig.json"
        }
      }
    },
    rules: {
      'node/file-extension-in-import': ['error', 'always'],
      'node/no-missing-import': 'off',
      "node/no-unsupported-features/es-syntax": [
        "error", {"ignores": ["dynamicImport", "modules"]}
      ],
      'import/no-unresolved': 'error',
      'import/extensions': [
        'error', {'mts': 'never'}
      ],
      ...
    }
    
  • [optional?] rename .ts files to .mts
    • EXCEPT for files containing graphql that you want grahql-codegen to generate types from. It can't seem to read .mts files.
  • Update ALL internal (meaning within the same package) imports to include the suffix, e.g. import { CONFIG } from '../config' -> import { CONFIG } from '../config.mjs'
  • Local root-level imports with typescript (e.g. import {client} from 'lib/hasuraClient.mjs' no longer work, waiting on ts-node to support it natively: TypeStrong/ts-node#1585

Graphql generation updates

  • I had to use the gql-tag-operations-preset preset in order for the generated .ts Queries/Documents to work:
    // codegen.yml
    overwrite: true
    require:
      - ts-node/register
    emitLegacyCommonJSImports: false
    generates:
      src/lib/autogen/hasura-sdk:
        schema: '../../schema.graphql'
        documents:
          - src/graphql/*.graphql
        preset: gql-tag-operations-preset
    
    Then, documents can be explicitly imported and used as such:
    // endpoint.mts
    
    import {
      GetUserByEmailDocument
    } from '../lib/autogen/hasura-sdk/graphql.js';
    ...
    const { user: foundUser } = await client.request(GetUserByEmailDocument, {
      email,
    });
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment