Closed glasser closed 5 months ago
At some point I am going to probably pull the trigger and either convert this repo to ESM or create a separate template that is ESM...suffice to say I ran into a lot of the same headaches, especially since a number of the @octokit
packages are converting to ESM lately (e.g. @octokit/graphql-schema
).
Unfortunately all the repos I have that do use TypeScript ESM actions are private, so I put one together quickly as a fork of this repo (https://github.com/ncalteen/typescript-esm-action). If you check the commit diff you can see the following need to be updated.
Set "type": "module"
in package.json
.
Add .js
extensions to relative imports in src/
and __tests__/
Install the TypeScript import resolver for ESLint (this is probably why ESLint was still causing you trouble)
npm i -D eslint-import-resolver-typescript
Add the resolver to .github/linters/eslintrc.yml
settings:
import/resolver:
typescript:
alwaysTryTypes: true
project: './.github/linters/tsconfig.json'
Install the TypeScript import resolver for Jest (similar to above, without this Jest can't find the relative imports)
npm i -D ts-jest-resolver
Add the resolver to the Jest configuration in package.json
{
# ...
"jest": {
# ...
"resolver": "ts-jest-resolver",
# ...
},
# ...
}
After that, npm run all
should run without error. I hope that helps!
Heyo! I'm going to go ahead and close this out now, but if you need anything please feel free to reopen :)
Hi @ncalteen - thanks for providing the example.
I'm trying to use import { graphql } from '@octokit/graphql'
however when I add that import it's still failing in repo templated from https://github.com/ncalteen/typescript-esm-action
Linting and packaging is passing but JEST is failing
Hey @karpikpl, sorry to hear that! I went down a bit of a rabbit hole on this one and think I found a few fixes. Check out the repo again for the changes!
A few highlights on the changes:
Jest needs to be manually imported in tests
import { jest } from '@jest/globals'
Mocks are not automatically hoisted in ESM, so they need to be dynamically imported instead
// Mock the @actions/core library used in main.ts
jest.mock('@actions/core', () => {
const actual: typeof import('@actions/core') = jest.requireActual('@actions/core')
return {
...actual,
getInput: jest.fn(),
setOutput: jest.fn(),
setFailed: jest.fn(),
debug: jest.fn()
}
})
// Imports must be done dynamically to allow the mocks to be applied
// See: https://jestjs.io/docs/ecmascript-modules#module-mocking-in-esm
const core = await import('@actions/core')
Regarding using @octokit/graphql
, that should work fine now. The example in this repo uses the built-in graphql
method from @octokit/rest
.
Running Jest with TypeScript ESM modules requires setting the --experimental-vm-options
flag. I disable the warning in this repo, but just an FYI since Jest's support is still experimental.
Thanks @ncalteen I don't know what I'm doing wrong :/ this seems overly complicated
All I want is to call graph from typescript, run tests and eslint - but because of those ESM modules that seems impossible
I tried your recent changes but tests failed - looks like graphql
is not getting mocked?
https://github.com/karpikpl/typescript-esm-action-sample/actions/runs/9716566623
Yeah not gonna lie, ESM makes things very challenging. I've been tinkering with this in a similar project and found a few other things to update that seem to help. I updated the other ESM example repo and included an API call using the octokit/graphql
client. Hopefully that helps!
Has anybody had success adapting an action created with this template to ESM (
"type": "module"
)? I'm finding that some modules I want to use as dependencies are only shipped as ESM these days, but it's not as simple as just adding"type": "module"
to package.json. When I do that:and run
npm run all
, the bundler fails withIf I then edit the imports in index.ts and main.ts to add
.js
to the end:I find that eslint fails with
While there's probably a real fix for this, I worked around it by disabling the lint rule:
But now Jest fails:
and that's where I get stuck.
Has anyone done this successfully?