diff --git a/examples/preact/babel.config.js b/examples/preact/babel.config.js new file mode 100644 index 00000000..dfa51264 --- /dev/null +++ b/examples/preact/babel.config.js @@ -0,0 +1,8 @@ +module.exports = { + presets: [ + ['@babel/preset-env', { targets: { node: 'current' } }], + ], + plugins: [ + ['@babel/plugin-transform-react-jsx', { pragma: 'h' }] + ] +} \ No newline at end of file diff --git a/examples/preact/package.json b/examples/preact/package.json index aaaa533a..dc5d9b28 100644 --- a/examples/preact/package.json +++ b/examples/preact/package.json @@ -10,36 +10,59 @@ "build": "preact build", "serve": "preact build && preact serve", "dev": "preact watch", - "lint": "eslint src", + "lint": "eslint src --ext .js,.jsx", "deploy": "netlify deploy --dir build --prod", "test": "jest" }, "eslintConfig": { - "extends": "eslint-config-synacor" + "extends": [ + "eslint:recommended", + "@eslint/js/recommended" + ], + "parserOptions": { + "ecmaVersion": 2022, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } + }, + "env": { + "browser": true, + "es6": true, + "node": true + }, + "rules": { + "no-unused-vars": "warn" + } }, "eslintIgnore": [ "build/*" ], "devDependencies": { - "eslint": "^4.9.0", - "eslint-config-synacor": "^2.0.2", + "@babel/core": "^7.26.0", + "@babel/preset-env": "^7.26.0", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@eslint/js": "^9.16.0", + "babel-jest": "^29.7.0", + "eslint": "^9.16.0", "identity-obj-proxy": "^3.0.0", "per-env": "^1.0.2", - "jest": "^21.2.1", - "preact-cli": "^2.1.0", - "preact-render-spy": "^1.2.1" + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "preact-cli": "^3.5.1", + "preact-render-spy": "^1.3.0" }, "dependencies": { "@analytics/google-analytics": "^0.2.0", "analytics": "^0.1.20", - "preact": "^8.2.6", + "preact": "^10.26.9", "preact-async-route": "^2.2.1", - "preact-compat": "^3.17.0", - "preact-render-to-string": "^4.1.0", - "preact-router": "^2.5.7" + "preact-render-to-string": "^6.5.14", + "preact-router": "^4.1.2" }, "jest": { "verbose": true, + "testEnvironment": "jsdom", "setupFiles": [ "/tests/__mocks__/browserMocks.js" ], @@ -48,7 +71,6 @@ "/node_modules/", "/tests/__mocks__/*" ], - "testURL": "http://localhost:8080", "moduleFileExtensions": [ "js", "jsx" @@ -57,14 +79,12 @@ "node_modules" ], "moduleNameMapper": { - "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/tests/__mocks__/fileMock.js", + "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/tests/__mocks__/fileMocks.js", "\\.(css|less|scss)$": "identity-obj-proxy", - "^./style$": "identity-obj-proxy", - "^preact$": "/node_modules/preact/dist/preact.min.js", - "^react$": "preact-compat", - "^react-dom$": "preact-compat", - "^create-react-class$": "preact-compat/lib/create-react-class", - "^react-addons-css-transition-group$": "preact-css-transition-group" + "^./style$": "identity-obj-proxy" + }, + "transform": { + "^.+\\.(js|jsx)$": "babel-jest" } } -} +} \ No newline at end of file diff --git a/examples/preact/src/app.js b/examples/preact/src/app.js index fce799b8..751f20a3 100644 --- a/examples/preact/src/app.js +++ b/examples/preact/src/app.js @@ -1,5 +1,6 @@ -import { h, Component } from 'preact' +import { h } from 'preact' import { Router } from 'preact-router' +import { useEffect } from 'preact/hooks' import analytics from './analytics' import Header from './components/header' @@ -21,50 +22,46 @@ if (inBrowser) { window.isLoggedIn = false } -export default class App extends Component { - - componentDidMount() { +export default function App() { + useEffect(() => { analytics.on('pageEnd', ({ payload }) => { console.log('pageView fired from analytics', payload.properties) }) - } + }, []) + /** Gets fired when the route changes. * @param {Object} event "change" event from [preact-router](http://git.io/preact-router) * @param {string} event.url The newly routed URL */ - handleRoute = e => { - this.currentUrl = e.url - this.previousUrl = e.previous + const handleRoute = e => { if (inBrowser) { analytics.page() } - }; + } - render() { - return ( -
-
- - - - + return ( +
+
+ + + + - } - /> - } - /> - } - /> + } + /> + } + /> + } + /> - - -
- ) - } -} + +
+
+ ) +} \ No newline at end of file diff --git a/examples/preact/src/routes/PrivateRoute.js b/examples/preact/src/routes/PrivateRoute.js index 2d32d9a2..872b5acc 100644 --- a/examples/preact/src/routes/PrivateRoute.js +++ b/examples/preact/src/routes/PrivateRoute.js @@ -1,4 +1,4 @@ -import { h, Component } from 'preact' +import { h } from 'preact' import AsyncRoute from 'preact-async-route' import { route } from 'preact-router' @@ -11,24 +11,22 @@ function authenticate() { }) } -class PrivateRoute extends Component { - render() { - return ( - { - return authenticate() - .then(() => () => { - return this.props.component(this.props) - }) - .catch(reason => { - route(`/login#rurl=${this.props.url}`, true) - return null - }) - }} - /> - ) - } +const PrivateRoute = (props) => { + return ( + { + return authenticate() + .then(() => () => { + return props.component(props) + }) + .catch(reason => { + route(`/login#rurl=${props.url}`, true) + return null + }) + }} + /> + ) } -export default PrivateRoute +export default PrivateRoute \ No newline at end of file diff --git a/examples/preact/tests/header.test.js b/examples/preact/tests/header.test.js index 1f43c204..ea90104a 100644 --- a/examples/preact/tests/header.test.js +++ b/examples/preact/tests/header.test.js @@ -1,3 +1,4 @@ +import { h } from 'preact'; import Header from '../src/components/header'; import { Link } from 'preact-router/match'; // See: https://github.com/mzgoddard/preact-render-spy