diff --git a/lerna.json b/lerna.json new file mode 100644 index 0000000..0fc05f6 --- /dev/null +++ b/lerna.json @@ -0,0 +1,8 @@ +{ + "packages": [ + "packages/*" + ], + "useNx": true, + "version": "2.0.3" +} + diff --git a/package.json b/package.json index b3b3590..664ab73 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "@flecks/monorepo", + "private": true, "repository": { "type": "git", "url": "https://github.com/cha0s/flecks.git" @@ -26,10 +27,10 @@ "@flecks/server": "*", "@flecks/socket": "*", "@flecks/user": "*", - "@flecks/web": "*", - "nx": "^17.2.8" + "@flecks/web": "*" }, "dependencies": { - "@docusaurus/theme-mermaid": "3.0.1" + "@docusaurus/theme-mermaid": "3.0.1", + "lerna": "^8.0.2" } } diff --git a/packages/core/src/server/commands.js b/packages/core/src/server/commands.js index 79678a8..6061e8f 100644 --- a/packages/core/src/server/commands.js +++ b/packages/core/src/server/commands.js @@ -113,6 +113,7 @@ export default (program, flecks) => { cmd, { env: { + FLECKS_CORE_IS_PRODUCTION: production, ...(target ? {FLECKS_CORE_BUILD_LIST: target} : {}), ...(hot ? {FLECKS_ENV__flecks_server__hot: 'true'} : {}), }, diff --git a/packages/core/src/server/flecks.js b/packages/core/src/server/flecks.js index 25ae261..8a09dbf 100644 --- a/packages/core/src/server/flecks.js +++ b/packages/core/src/server/flecks.js @@ -331,7 +331,7 @@ export default class ServerFlecks extends Flecks { ignore: [ignore], only: [only], }; - debugSilly('compiling %O with %j', compiling, config); + debugSilly('compiling %O with %j at %s', compiling, config, only); compilations.push({ ignore, only, @@ -395,7 +395,8 @@ export default class ServerFlecks extends Flecks { const roots = Array.from(new Set( Object.keys(resolver) .map((path) => this.root(resolver, path)) - .filter((e) => !!e), + .filter((e) => !!e) + .concat(FLECKS_CORE_ROOT), )); for (let i = 0; i < roots.length; ++i) { const root = roots[i]; diff --git a/packages/react/build/.flecksrc.js b/packages/react/build/.flecksrc.js index 4630eb7..3073077 100644 --- a/packages/react/build/.flecksrc.js +++ b/packages/react/build/.flecksrc.js @@ -1,8 +1,16 @@ +const plugins = []; + +const { + FLECKS_CORE_IS_PRODUCTION, +} = process.env; + +if ('true' !== FLECKS_CORE_IS_PRODUCTION) { + plugins.push('react-refresh/babel'); +} + module.exports = { - aliases: { - 'react-dom': '@hot-loader/react-dom', - }, babel: { + plugins, presets: [ '@babel/preset-react', ], diff --git a/packages/react/package.json b/packages/react/package.json index 6483adc..10daf5d 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -44,13 +44,14 @@ "@babel/preset-react": "^7.23.3", "@flecks/core": "^2.0.3", "@flecks/web": "^2.0.3", - "@hot-loader/react-dom": "^17.0.2", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "babel-merge": "^3.0.0", "classnames": "^2.3.1", "history": "^5.3.0", "prop-types": "^15.7.2", "react": "^18.2.0", - "react-hot-loader": "^4.13.1", + "react-dom": "^18.2.0", + "react-refresh": "^0.14.0", "react-router-dom": "6.20.0", "redux-first-history": "5.1.1" }, diff --git a/packages/react/src/client.js b/packages/react/src/client.js index 9d31990..eef1176 100644 --- a/packages/react/src/client.js +++ b/packages/react/src/client.js @@ -1,6 +1,6 @@ import {D} from '@flecks/core'; -import {hydrate, render} from '@hot-loader/react-dom'; import React from 'react'; +import {createRoot, hydrateRoot} from 'react-dom/client'; // eslint-disable-next-line import/no-extraneous-dependencies import FlecksContext from '@flecks/react/context'; @@ -14,15 +14,19 @@ export const hooks = { '@flecks/web/client.up': async (flecks) => { const {ssr} = flecks.get('@flecks/react'); const {appMountId} = flecks.get('@flecks/web/client'); + const container = window.document.getElementById(appMountId); debug('%sing...', ssr ? 'hydrat' : 'render'); - (ssr ? hydrate : render)( - React.createElement( - React.StrictMode, - {}, - [React.createElement(await root(flecks), {key: 'root'})], - ), - window.document.getElementById(appMountId), + const RootComponent = React.createElement( + React.StrictMode, + {}, + [React.createElement(await root(flecks), {key: 'root'})], ); + if (ssr) { + hydrateRoot(container, RootComponent); + } + else { + createRoot(container).render(RootComponent); + } debug('rendered'); }, }; diff --git a/packages/react/src/index.js b/packages/react/src/index.js index 97599c1..47caa83 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -1,9 +1,8 @@ -export {default as ReactDom} from '@hot-loader/react-dom'; export {default as classnames} from 'classnames'; export {default as PropTypes} from 'prop-types'; export {default as React} from 'react'; +export {default as ReactDom} from 'react-dom'; export * from 'react'; -export {hot} from 'react-hot-loader'; // eslint-disable-next-line import/no-extraneous-dependencies, import/no-unresolved export {default as FlecksContext} from '@flecks/react/context'; diff --git a/packages/react/src/server.js b/packages/react/src/server.js index 43165b5..0e228cb 100644 --- a/packages/react/src/server.js +++ b/packages/react/src/server.js @@ -1,16 +1,15 @@ import {Flecks} from '@flecks/core'; import {augmentBuild} from '@flecks/web/server'; +import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; import ssr from './ssr'; export const hooks = { '@flecks/core.build': (target, config, env, argv, flecks) => { const isProduction = 'production' === argv.mode; - config.resolve.alias['react-native'] = 'react-native-web'; - config.resolve.alias['react-hot-loader'] = isProduction - ? 'react-hot-loader/dist/react-hot-loader.production.min' - : 'react-hot-loader/dist/react-hot-loader.development'; - config.resolve.extensions.unshift(...['.web.js', '.web.jsx']); + if (!isProduction) { + config.plugins.push(new ReactRefreshWebpackPlugin()); + } // Augment the build on behalf of a missing `@flecks/web`. if (!flecks.fleck('@flecks/web/server')) { flecks.registerBuildConfig('postcss.config.js', {fleck: '@flecks/web/server'}); diff --git a/packages/react/src/ssr.js b/packages/react/src/ssr.js index c52149e..4ad5d27 100644 --- a/packages/react/src/ssr.js +++ b/packages/react/src/ssr.js @@ -2,7 +2,7 @@ import {Transform} from 'stream'; import {D} from '@flecks/core'; import React from 'react'; -import ReactDOMServer from '@hot-loader/react-dom/server'; +import ReactDOMServer from 'react-dom/server'; import root from './root'; diff --git a/packages/redux/build/.flecksrc.js b/packages/redux/build/.flecksrc.js deleted file mode 100644 index 80c431d..0000000 --- a/packages/redux/build/.flecksrc.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - aliases: { - 'react-dom': '@hot-loader/react-dom', - }, -}; diff --git a/packages/redux/package.json b/packages/redux/package.json index 76de1f2..9ec1669 100644 --- a/packages/redux/package.json +++ b/packages/redux/package.json @@ -29,7 +29,6 @@ ], "dependencies": { "@flecks/core": "^2.0.3", - "@hot-loader/react-dom": "^17.0.1", "@reduxjs/toolkit": "^1.5.0", "debug": "^4.3.3", "lodash.throttle": "^4.1.1", diff --git a/website/docs/react.mdx b/website/docs/react.mdx index ef0de48..8940924 100644 --- a/website/docs/react.mdx +++ b/website/docs/react.mdx @@ -86,33 +86,8 @@ Now if you visit the page with JavaScript disabled, you will get a white page. ### Hot module reloading -This is cool, but you'll notice that if you edit your component, the changes are not immediately -reflected on the page. This is because we have to add HMR support to our root component: - -```jsx title="packages/root/src/component.jsx" -import {hot, React} from '@flecks/react'; - -function Component() { - return

hello world (from React)

; -} - -export default hot(module)(Component); -``` - -Now you can edit and your changes will be reflected on the page! - -:::tip - -Any components your root component uses will automatically be reloaded: only your root component -requires the `hot` call. - -:::note[Help wanted] - -It is admittedly not so ergonomic to remember the `hot` call for your root components. React fast -refresh would probably make this unnecessary, but it hasn't been implemented in flecks yet. We -would very much appreciate a [pull request](https://github.com/cha0s/flecks/compare)! - -::: +You'll notice that if you edit your component, the changes are immediately reflected on the page. +This is because we have HMR support in our application! ## Hooks