Skip to content

Commit add9187

Browse files
authored
Modernise build tooling (Node 22, ESLint 9, Vitest, Vite) (#271)
* chore: add Node 22 LTS configuration * test: replace Karma with Vitest in browser mode - Add vitest.config.js with Playwright browser mode - Install vitest, @vitest/browser-playwright, @playwright/test - Multi-browser support: Chromium (all), Firefox (CI), Safari (Mac) - Create test/setup.js for test utilities - Migrate tests from chai assertions to Vitest expect - Update test script to run vitest - Fix legacy React API issues in tests BREAKING CHANGE: Tests now run in real browsers instead of jsdom Remove .ryan/ from tracking (already in global gitignore) * build: replace Webpack with Vite for library builds - Add vite.config.js for library builds (ESM + UMD) - Add vite example dev server with react plugin - Update package.json with proper exports (main, module, types) - Update build script to use Vite instead of Babel - Remove legacy webpack.config.js - Update example/app.jsx for React 18 createRoot API * fix: add Playwright browser installation to CI - Fix lint errors: unused imports and eslint-disable directives * fix: install Playwright chromium deps in CI fix: add Firefox to Playwright CI installation fix: use --with-deps flag for Playwright browsers * refactor: split CI into separate lint, test, build jobs
1 parent ff285a1 commit add9187

20 files changed

Lines changed: 12817 additions & 15316 deletions

.babelrc

Lines changed: 0 additions & 4 deletions
This file was deleted.

.eslintrc

Lines changed: 0 additions & 20 deletions
This file was deleted.

.github/workflows/ci.yml

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,36 @@
11
on: [push, pull_request]
2+
23
jobs:
3-
build:
4+
lint:
45
runs-on: ubuntu-latest
56
steps:
6-
- uses: actions/checkout@v2
7-
- uses: actions/setup-node@v1
7+
- uses: actions/checkout@v4
8+
- uses: actions/setup-node@v4
89
with:
9-
node-version: 14
10+
node-version: 22
11+
cache: 'npm'
1012
- run: npm install
13+
- run: npm run lint
1114

12-
- name: Run headless test
13-
uses: GabrielBB/xvfb-action@v1
15+
test:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-node@v4
1420
with:
15-
run: npm test
21+
node-version: 22
22+
cache: 'npm'
23+
- run: npm install
24+
- run: npx playwright install --with-deps chromium firefox
25+
- run: CI=true npm test
26+
27+
build:
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v4
31+
- uses: actions/setup-node@v4
32+
with:
33+
node-version: 22
34+
cache: 'npm'
35+
- run: npm install
36+
- run: npm run build

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22

babel.config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"presets": [
3+
["@babel/preset-env", { "modules": false }],
4+
["@babel/preset-react", { "runtime": "automatic" }]
5+
],
6+
"plugins": ["@babel/plugin-proposal-class-properties"]
7+
}

eslint.config.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import js from '@eslint/js';
2+
import react from 'eslint-plugin-react';
3+
import reactHooks from 'eslint-plugin-react-hooks';
4+
import reactRefresh from 'eslint-plugin-react-refresh';
5+
import globals from 'globals';
6+
7+
export default [
8+
js.configs.recommended,
9+
{
10+
files: ['**/*.{js,jsx}'],
11+
ignores: [
12+
'node_modules/**',
13+
'dist/**',
14+
'lib/**',
15+
'*.config.js',
16+
'karma.conf.js'
17+
],
18+
languageOptions: {
19+
ecmaVersion: 'latest',
20+
sourceType: 'module',
21+
globals: {
22+
...globals.browser
23+
},
24+
parserOptions: {
25+
ecmaFeatures: {
26+
impliedStrict: true,
27+
jsx: true
28+
}
29+
}
30+
},
31+
plugins: {
32+
react,
33+
'react-hooks': reactHooks,
34+
'react-refresh': reactRefresh
35+
},
36+
rules: {
37+
...react.configs.recommended.rules,
38+
...reactHooks.configs.recommended.rules,
39+
'react-refresh/only-export-components': [
40+
'warn',
41+
{ allowConstantExport: true }
42+
],
43+
'react/forbid-prop-types': 'off',
44+
'react/prop-types': 'off',
45+
'no-underscore-dangle': 'off',
46+
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }]
47+
},
48+
settings: {
49+
react: {
50+
version: 'detect'
51+
}
52+
}
53+
},
54+
{
55+
files: ['test/**/*.{js,jsx}'],
56+
languageOptions: {
57+
globals: {
58+
...globals.mocha,
59+
...globals.browser
60+
}
61+
},
62+
rules: {
63+
...react.configs.recommended.rules,
64+
'react/no-find-dom-node': 'off',
65+
'react/no-deprecated': 'off',
66+
'react/no-render-return-value': 'off',
67+
'react-hooks/exhaustive-deps': 'warn'
68+
}
69+
}
70+
];

example/app.jsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import ReactDOM from 'react-dom';
2+
import { createRoot } from 'react-dom/client';
33
import Frame from '../src';
44

55
const styles = {
@@ -21,11 +21,10 @@ const App = () => (
2121
</div>
2222
);
2323

24-
ReactDOM.render(
24+
createRoot(document.querySelector('#example1')).render(
2525
<Frame style={styles}>
2626
<App />
27-
</Frame>,
28-
document.querySelector('#example1')
27+
</Frame>
2928
);
3029

3130
const Foobar = () => {
@@ -43,11 +42,11 @@ const Foobar = () => {
4342
);
4443
};
4544

46-
ReactDOM.render(<Foobar />, document.querySelector('#example2'));
45+
createRoot(document.querySelector('#example2')).render(<Foobar />);
4746

4847
const ExternalResources = () => {
4948
const initialContent = `<!DOCTYPE html><html><head>
50-
<link href="//use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet" />
49+
<link href="///releases/v5.15.1/cssuse.fontawesome.com/all.css" rel="stylesheet" />
5150
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
5251
<base target=_blank>
5352
</head><body style='overflow: hidden'><div></div></body></html>`;
@@ -63,4 +62,4 @@ const ExternalResources = () => {
6362
);
6463
};
6564

66-
ReactDOM.render(<ExternalResources />, document.querySelector('#example3'));
65+
createRoot(document.querySelector('#example3')).render(<ExternalResources />);

karma.conf.js

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)