diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 7f9cf4f..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,43 +0,0 @@ -module.exports = { - root: true, - env: { - browser: true, - node: true, - commonjs: true, - es6: true - }, - globals: { - __DEV__: true - }, - plugins: ['prettier'], - extends: ['airbnb', 'airbnb-typescript', 'plugin:compat/recommended', 'eslint-config-prettier'], - rules: { - '@typescript-eslint/naming-convention': ['error', {leadingUnderscore: 'allow', format: ['camelCase', 'PascalCase', 'UPPER_CASE'], selector: 'default'}], - '@typescript-eslint/no-use-before-define': ['error', {functions: false}], - 'prettier/prettier': 'error', - 'react/jsx-props-no-spreading': 'off', - 'react/no-unknown-property': ['error', { ignore: ['x-class', 'x-if', 'x-elseif', 'x-else'] }], - 'no-return-assign': ['error', 'except-parens'], - 'no-sequences': 'off', - 'no-shadow': 'off', - 'no-plusplus': 'off', - 'no-param-reassign': 'off', - 'no-void': 'off', - 'react/require-default-props': 'off', - 'react/react-in-jsx-scope': 'off', - 'no-use-before-define': ['error', {functions: false}], - "import/no-extraneous-dependencies": ["error", {"devDependencies": ["{demos,test}/**/*"]}], - 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn', - 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' - }, - settings: { - 'import/resolver': 'eslint-import-resolver-typescript', - 'polyfills': [ - // App which dependence this lib should pollyfill these methods: - 'Promise', - ] - }, - parserOptions: { - project: './tsconfig.json' - } -}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0d75fe..8da0f87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [18.x, 20.x] + node-version: [22.x] steps: - uses: actions/checkout@v4 @@ -26,8 +26,10 @@ jobs: node-version: ${{ matrix.node-version }} cache: pnpm - name: Install dependencies - run: pnpm install + run: pnpm install --no-frozen-lockfile - name: Lint run: pnpm run lint + - name: Test + run: pnpm run test:run - name: Build run: pnpm run build diff --git a/.mocharc.js b/.mocharc.js deleted file mode 100644 index 36bc653..0000000 --- a/.mocharc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - extension: ['js', 'ts', 'tsx'], - recursive: true, - exclude: ['mock', 'typings', 'fixtures'], - require: ['global-jsdom/register', 'should', 'should-sinon', 'test/babel-register.js'] -} diff --git a/.nycrc.json b/.nycrc.json deleted file mode 100644 index 494bb31..0000000 --- a/.nycrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "include": ["src/"] -} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..57362e7 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,102 @@ +const js = require('@eslint/js'); +const tseslint = require('@typescript-eslint/eslint-plugin'); +const tsparser = require('@typescript-eslint/parser'); +const react = require('eslint-plugin-react'); +const reactHooks = require('eslint-plugin-react-hooks'); +const jsxA11y = require('eslint-plugin-jsx-a11y'); +const importPlugin = require('eslint-plugin-import'); +const prettierPlugin = require('eslint-plugin-prettier'); +const prettierConfig = require('eslint-config-prettier'); +const compat = require('eslint-plugin-compat'); + +module.exports = [ + js.configs.recommended, + { + ignores: ['dist', 'node_modules', 'coverage', '*.min.js', 'babel.config.js', 'eslint.config.js', 'vitest.config.ts'], + }, + { + files: ['**/*.{ts,tsx}'], + languageOptions: { + parser: tsparser, + parserOptions: { + project: './tsconfig.json', + ecmaVersion: 'latest', + sourceType: 'module', + }, + globals: { + __dirname: 'readonly', + __filename: 'readonly', + module: 'readonly', + require: 'readonly', + document: 'readonly', + window: 'readonly', + fetch: 'readonly', + setTimeout: 'readonly', + clearTimeout: 'readonly', + setInterval: 'readonly', + clearInterval: 'readonly', + console: 'readonly', + process: 'readonly', + }, + }, + plugins: { + '@typescript-eslint': tseslint, + react, + 'react-hooks': reactHooks, + 'jsx-a11y': jsxA11y, + import: importPlugin, + prettier: prettierPlugin, + compat, + }, + rules: { + ...react.configs.recommended.rules, + ...reactHooks.configs.recommended.rules, + ...jsxA11y.configs.recommended.rules, + ...prettierConfig.rules, + 'prettier/prettier': 'error', + 'no-unused-vars': 'off', + 'no-undef': 'off', + 'react/jsx-props-no-spreading': 'off', + 'react/no-unknown-property': ['error', { ignore: ['x-class', 'x-if', 'x-elseif', 'x-else'] }], + 'no-return-assign': ['error', 'except-parens'], + 'no-sequences': 'off', + 'no-shadow': 'off', + 'no-plusplus': 'off', + 'no-param-reassign': 'off', + 'no-void': 'off', + 'react/require-default-props': 'off', + 'react/react-in-jsx-scope': 'off', + 'no-use-before-define': ['error', {functions: false}], + 'no-console': 'off', + 'no-debugger': 'off', + }, + settings: { + react: { + version: 'detect', + }, + 'import/resolver': { + typescript: {}, + }, + polyfills: ['Promise'], + }, + }, + { + files: ['**/*.js', '**/*.jsx'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + browser: true, + node: true, + __DEV__: true, + }, + }, + plugins: { + prettier: prettierPlugin, + }, + rules: { + ...prettierConfig.rules, + 'prettier/prettier': 'error', + }, + }, +]; diff --git a/package.json b/package.json index 8bb343b..f5d76f0 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,14 @@ "private": true, "scripts": { "start": "vite", - "build": "vite build && tsc -p tsconfig.production.json && tsc-alias -p tsconfig.production.json", + "build": "vite build", "commit": "lint-staged && git-cz -n", - "coverage": "nyc report --reporter=text-lcov | coveralls", - "lint": "eslint --fix src *.js --ext .js,.jsx,.ts,.tsx", + "coverage": "vitest coverage", + "lint": "eslint --fix .", "deploy": "cross-env BABEL_ENV=development BUILD_DEMO=true vite build && gh-pages -d dist", - "test": "cross-env NODE_ENV=test nyc mocha", - "test:watch": "npm test -- --watch", + "test": "vitest", + "test:ui": "vitest --ui", + "test:run": "vitest run", "prepublishOnly": "npm run build", "postpublish": "git push --follow-tags && npm run deploy", "serve": "vite preview" @@ -30,12 +31,14 @@ "@linaria/babel-preset": "^4.5.4", "@linaria/vite": "^4.5.4", "@testing-library/react": "^14.0.0", - "@types/mocha": "^10.0.1", + "@testing-library/jest-dom": "^6.1.0", + "@vitest/coverage-v8": "^2.0.0", + "@vitest/ui": "^2.0.0", + "jsdom": "^24.0.0", "@types/node": "^20.4.8", "@types/ramda": "^0.29.3", "@types/react": "^18.2.18", "@types/react-dom": "^18.2.7", - "@types/sinon": "^10.0.16", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "@vitejs/plugin-react": "^4.0.4", @@ -44,32 +47,22 @@ "babel-runtime-jsx-plus": "^0.1.5", "commitizen": "^4.3.0", "core-js": "^3.32.0", - "coveralls": "^3.1.1", "cross-env": "^7.0.3", + "@eslint/js": "^9.39.2", "eslint": "^9.39.2", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^9.0.0", - "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-compat": "^4.1.4", "eslint-plugin-import": "^2.28.0", "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-mocha": "^10.1.0", "eslint-plugin-prettier": "^5.0.0", - "eslint-plugin-react": "^7.33.1", - "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^5.0.0", "gh-pages": "^5.0.0", - "global-jsdom": "^9.1.0", "husky": "^8.0.3", - "jsdom": "^22.1.0", "lint-staged": "^13.2.3", - "mocha": "^10.2.0", - "nyc": "^15.1.0", - "prettier": "^4.0.0", + "prettier": "^3.0.0", "rollup-plugin-type-as-json-schema": "^0.2.6", - "should": "^13.2.3", - "should-sinon": "0.0.6", - "sinon": "^15.2.0", + "vitest": "^2.0.0", "terser": "^5.19.2", "tsc-alias": "^1.8.7", "typescript": "^5.9.3", diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..7d21796 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from 'vitest/config'; +import path from 'path'; + +export default defineConfig({ + test: { + environment: 'jsdom', + globals: true, + include: ['src/**/*.test.{ts,tsx}'], + exclude: ['node_modules', 'dist', 'mock', 'typings', 'fixtures'], + passWithNoTests: true + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './src') + } + } +});