Skip to content

Commit 9a6f1b1

Browse files
Johannes KadakKarlMae
andauthored
feat: compile as ES Module (#431)
* feat: compile as ES Module * update CI workflows to newer node * release workflow to newer node * update yarn version to 3.3.1 * explicitly set yarnPath * fix: frozen-lockfile to immutable * replace isomorphic-fetch with cross-fetch * fix: done() called only once * update jest + fix a few tests * Add .js to local imports as per https://github.com/microsoft/TypeScript/issues/16577\#issuecomment-754941937 * prettier write * example for adding it in the browser * github workflows to one version (hashes may change when changing node version, due to yarn patches) * update package.json * Update yarn lock * fix: graphql subscription tests don't leak handles * Node tests for graphql subscriptions are now working * Don't try to make WebSocket tests work in two environments After struggling for a long while with trying to "shim" isomorphic-ws to work normally in a jest environment, it is easier to just run this test only in a Node environment. Here are the issues why this test fails in JSDOM: 1. Imports fail The statement `import WebSocket from 'isomorphic-ws';` is passed to the Jest module resolver, which utilises `ts-jest-resolver` (in our case) to find the right file to load. Sadly, it will always load the "main" module of a node package. 2. isomorphic-ws "browser" option is ESM for some reason If we use jest.config.cjs "resolver" field [1] to define a custom script, we will be able to modify the "main" field by patching package.json in memory. This works fine, however isomorphic-ws's browser version is an ES Module for some reason, even if the package.json > "type" is "commonjs". 3. Something inside jest doesn't want me to hack it to support ESM If I override the package.json even harder to also change the "type" to "module" just for isomorphic-ws, Jest doesn't respect it 4. ts-jest doesn't want to change the ESM imports to CJS imports Since... we told it to not change ESM imports to CJS imports, it will not. [1]: https://jestjs.io/docs/configuration#resolver-string * prettier write * follow flags in tsconfig --------- Co-authored-by: karl <[email protected]>
1 parent 1484a11 commit 9a6f1b1

29 files changed

+9901
-6384
lines changed

.eslintrc.json

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,34 @@
22
"env": {
33
"browser": true
44
},
5-
"extends": ["eslint:recommended", "@qminder", "prettier"],
5+
"plugins": ["import", "@typescript-eslint"],
6+
"extends": [
7+
"eslint:recommended",
8+
"prettier",
9+
"plugin:import/recommended",
10+
"plugin:import/typescript"
11+
],
12+
"parser": "@typescript-eslint/parser",
613
"parserOptions": {
14+
"ecmaVersion": 2020,
715
"sourceType": "module"
816
},
17+
"settings": {
18+
"import/resolver": {
19+
"typescript": {}
20+
}
21+
},
22+
"rules": {
23+
"import/namespace": "off",
24+
"no-unused-vars": "off",
25+
"import/no-named-as-default": "off"
26+
},
927
"overrides": [
1028
{
11-
"files": ["*.test.ts"],
29+
"files": ["*.test.ts", "test/unit/jestSetupFile.ts"],
1230
"env": {
13-
"jest": true
31+
"jest": true,
32+
"node": true
1433
},
1534
"rules": {
1635
"func-names": "off"

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.yarn/releases/*.cjs binary
2+
.yarn/plugins/@yarnpkg/*.cjs binary

.github/workflows/code-coverage.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ jobs:
1010
- uses: actions/checkout@master
1111
- uses: actions/setup-node@v3
1212
with:
13-
node-version: 14.x
14-
- run: yarn install --frozen-lockfile
13+
node-version: 16.x
14+
cache: 'yarn'
15+
- run: yarn install --immutable
1516
- run: yarn jest --coverage
1617
- uses: codecov/codecov-action@v3
1718
with:

.github/workflows/push.yml

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,71 @@ on: push
22
name: Test on push
33
jobs:
44
test:
5-
strategy:
6-
matrix:
7-
node-version: [12.x, 14.x, 15.x, 16.x]
8-
name: Test on NodeJS ${{ matrix.node-version }}
5+
name: Test (JSDOM)
96
runs-on: ubuntu-latest
107
steps:
118
- uses: actions/checkout@master
129
- uses: actions/setup-node@v3
1310
with:
14-
node-version: ${{ matrix.node-version }}
11+
node-version: 16.x
12+
cache: 'yarn'
1513
- name: Install Deps
16-
run: yarn install --frozen-lockfile
14+
run: yarn install --immutable
1715
- name: Run tests (browser)
1816
run: yarn test
17+
test_node:
18+
name: Test (Node.js)
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@master
22+
- uses: actions/setup-node@v3
23+
with:
24+
node-version: 16.x
25+
cache: 'yarn'
26+
- name: Install Deps
27+
run: yarn install --immutable
1928
- name: Run tests (node)
2029
run: yarn test-node
30+
test_pack:
31+
name: Build
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@master
35+
- uses: actions/setup-node@v3
36+
with:
37+
node-version: 16.x
38+
cache: 'yarn'
39+
- name: Install Deps
40+
run: yarn install --immutable
2141
- name: Build the package
2242
run: yarn pack
2343
prettier:
2444
name: Check prettier
25-
runs-on: ubuntu-18.04
45+
runs-on: ubuntu-latest
2646
steps:
2747
- uses: actions/checkout@master
48+
- uses: actions/setup-node@v3
49+
with:
50+
node-version: 16.x
51+
cache: 'yarn'
2852
- name: Install Deps
2953
run: |
30-
yarn install --frozen-lockfile
54+
yarn install --immutable
3155
- name: Prettier check
3256
run: |
3357
yarn run lint-prettier
3458
eslint:
3559
name: Check eslint
36-
runs-on: ubuntu-18.04
60+
runs-on: ubuntu-latest
3761
steps:
3862
- uses: actions/checkout@master
63+
- uses: actions/setup-node@v3
64+
with:
65+
node-version: 16.x
66+
cache: 'yarn'
3967
- name: Install Deps
4068
run: |
41-
yarn install --frozen-lockfile
69+
yarn install --immutable
4270
- name: Eslint check
4371
run: |
4472
yarn run lint-eslint

.github/workflows/release.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ jobs:
1212
- uses: actions/checkout@master
1313
- uses: actions/setup-node@v3
1414
with:
15-
node-version: 12.x
15+
node-version: 16.x
16+
cache: 'yarn'
1617
always-auth: true
1718
registry-url: https://registry.npmjs.org
1819
- name: Install Deps
19-
run: yarn install --frozen-lockfile --ignore-scripts
20+
run: yarn install --immutable --ignore-scripts
2021
env:
2122
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2223
- name: Build Library

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ graphql.config.json
3434
.idea
3535

3636
build
37+
38+
.yarn/*
39+
!.yarn/releases
40+
!.yarn/plugins
41+
!.yarn/sdks
42+
!.yarn/versions
43+
.pnp.*

.yarn/releases/yarn-3.3.1.cjs

Lines changed: 823 additions & 0 deletions
Large diffs are not rendered by default.

.yarnrc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
nodeLinker: node-modules
2+
yarnPath: .yarn/releases/yarn-3.3.1.cjs

examples/browser/index.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Qminder API in browser</title>
8+
</head>
9+
<body>
10+
<label for="apikey">API key:</label><input type="password" id="apikey" />
11+
<button id="load-button">Load locations</button>
12+
<div id="output"></div>
13+
<script type="module" src="dist/main.out.js"></script>
14+
</body>
15+
</html>

examples/browser/main.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as Qminder from '../../build/qminder-api.js';
2+
3+
const buttonEl = document.getElementById('load-button');
4+
const outputEl = document.getElementById('output');
5+
const apiKeyEl = document.getElementById('apikey');
6+
7+
buttonEl.addEventListener('click', async () => {
8+
Qminder.setKey(apiKeyEl.value);
9+
const locations = await Qminder.locations.list();
10+
for (const location of locations) {
11+
const div = document.createElement('div');
12+
div.textContent = location.name;
13+
outputEl.appendChild(div);
14+
}
15+
});

0 commit comments

Comments
 (0)