refactor: react fast refresh
This commit is contained in:
parent
c3cc989aa5
commit
9404d73c00
8
lerna.json
Normal file
8
lerna.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"useNx": true,
|
||||
"version": "2.0.3"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'} : {}),
|
||||
},
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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',
|
||||
],
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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(
|
||||
const RootComponent = React.createElement(
|
||||
React.StrictMode,
|
||||
{},
|
||||
[React.createElement(await root(flecks), {key: 'root'})],
|
||||
),
|
||||
window.document.getElementById(appMountId),
|
||||
);
|
||||
if (ssr) {
|
||||
hydrateRoot(container, RootComponent);
|
||||
}
|
||||
else {
|
||||
createRoot(container).render(RootComponent);
|
||||
}
|
||||
debug('rendered');
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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'});
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
module.exports = {
|
||||
aliases: {
|
||||
'react-dom': '@hot-loader/react-dom',
|
||||
},
|
||||
};
|
|
@ -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",
|
||||
|
|
|
@ -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 <p>hello world (from React)</p>;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user