mirror of
https://github.com/usebruno/bruno.git
synced 2025-05-05 23:42:58 +00:00
feat: replace nextjs with rsbuild (#3617)
* poc: bruno app rsbuild * fix: updates --------- Co-authored-by: Anoop M D <anoop.md1421@gmail.com>
This commit is contained in:
parent
3efcdf254e
commit
33e86a9097
2
packages/bruno-app/.gitignore
vendored
2
packages/bruno-app/.gitignore
vendored
@ -31,6 +31,6 @@ yarn-error.log*
|
|||||||
|
|
||||||
# next.js
|
# next.js
|
||||||
.next/
|
.next/
|
||||||
out/
|
dist/
|
||||||
|
|
||||||
.env
|
.env
|
@ -1,22 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
output: 'export',
|
|
||||||
reactStrictMode: false,
|
|
||||||
publicRuntimeConfig: {
|
|
||||||
CI: process.env.CI,
|
|
||||||
PLAYWRIGHT: process.env.PLAYWRIGHT,
|
|
||||||
ENV: process.env.ENV
|
|
||||||
},
|
|
||||||
webpack: (config, { isServer }) => {
|
|
||||||
// Fixes npm packages that depend on `fs` module
|
|
||||||
if (!isServer) {
|
|
||||||
config.resolve.fallback.fs = false;
|
|
||||||
}
|
|
||||||
Object.defineProperty(config, 'devtool', {
|
|
||||||
get() {
|
|
||||||
return 'source-map';
|
|
||||||
},
|
|
||||||
set() {},
|
|
||||||
});
|
|
||||||
return config;
|
|
||||||
},
|
|
||||||
};
|
|
@ -3,10 +3,9 @@
|
|||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "cross-env ENV=dev next dev -p 3000",
|
"dev": "rsbuild dev --open",
|
||||||
"build": "next build",
|
"build": "rsbuild build -m production",
|
||||||
"start": "next start",
|
"preview": "rsbuild preview",
|
||||||
"lint": "next lint",
|
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:prettier": "prettier --check \"./src/**/*.{js,jsx,json,ts,tsx}\"",
|
"test:prettier": "prettier --check \"./src/**/*.{js,jsx,json,ts,tsx}\"",
|
||||||
"prettier": "prettier --write \"./src/**/*.{js,jsx,json,ts,tsx}\""
|
"prettier": "prettier --write \"./src/**/*.{js,jsx,json,ts,tsx}\""
|
||||||
@ -49,7 +48,6 @@
|
|||||||
"markdown-it-replace-link": "^1.2.0",
|
"markdown-it-replace-link": "^1.2.0",
|
||||||
"mousetrap": "^1.6.5",
|
"mousetrap": "^1.6.5",
|
||||||
"nanoid": "3.3.4",
|
"nanoid": "3.3.4",
|
||||||
"next": "14.2.16",
|
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"pdfjs-dist": "4.4.168",
|
"pdfjs-dist": "4.4.168",
|
||||||
"platform": "^1.3.6",
|
"platform": "^1.3.6",
|
||||||
@ -57,17 +55,17 @@
|
|||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"qs": "^6.11.0",
|
"qs": "^6.11.0",
|
||||||
"query-string": "^7.0.1",
|
"query-string": "^7.0.1",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-copy-to-clipboard": "^5.1.0",
|
"react-copy-to-clipboard": "^5.1.0",
|
||||||
"react-dnd": "^16.0.1",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^16.0.1",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"react-hot-toast": "^2.4.0",
|
"react-hot-toast": "^2.4.0",
|
||||||
"react-i18next": "^15.0.1",
|
"react-i18next": "^15.0.1",
|
||||||
"react-inspector": "^6.0.2",
|
"react-inspector": "^6.0.2",
|
||||||
"react-pdf": "9.1.1",
|
"react-pdf": "9.1.1",
|
||||||
"react-player": "^2.16.0",
|
"react-player": "^2.16.0",
|
||||||
"react-redux": "^7.2.6",
|
"react-redux": "^7.2.9",
|
||||||
"react-tooltip": "^5.5.2",
|
"react-tooltip": "^5.5.2",
|
||||||
"sass": "^1.46.0",
|
"sass": "^1.46.0",
|
||||||
"strip-json-comments": "^5.0.1",
|
"strip-json-comments": "^5.0.1",
|
||||||
@ -79,13 +77,14 @@
|
|||||||
"yup": "^0.32.11"
|
"yup": "^0.32.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.16.0",
|
"@rsbuild/core": "^1.1.2",
|
||||||
"@babel/plugin-transform-spread": "^7.16.7",
|
"@rsbuild/plugin-babel": "^1.0.3",
|
||||||
"@babel/preset-env": "^7.16.4",
|
"@rsbuild/plugin-node-polyfill": "^1.2.0",
|
||||||
"@babel/preset-react": "^7.16.0",
|
"@rsbuild/plugin-react": "^1.0.7",
|
||||||
"@babel/runtime": "^7.16.3",
|
"@rsbuild/plugin-sass": "^1.1.0",
|
||||||
|
"@rsbuild/plugin-styled-components": "1.1.0",
|
||||||
"autoprefixer": "10.4.20",
|
"autoprefixer": "10.4.20",
|
||||||
"babel-loader": "^8.2.3",
|
"babel-plugin-react-compiler": "19.0.0-beta-a7bf2bd-20241110",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "7.1.2",
|
"css-loader": "7.1.2",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
|
27
packages/bruno-app/rsbuild.config.mjs
Normal file
27
packages/bruno-app/rsbuild.config.mjs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { defineConfig } from '@rsbuild/core';
|
||||||
|
import { pluginReact } from '@rsbuild/plugin-react';
|
||||||
|
import { pluginBabel } from '@rsbuild/plugin-babel';
|
||||||
|
import { pluginStyledComponents } from '@rsbuild/plugin-styled-components';
|
||||||
|
import { pluginSass } from '@rsbuild/plugin-sass';
|
||||||
|
import { pluginNodePolyfill } from '@rsbuild/plugin-node-polyfill'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
pluginNodePolyfill(),
|
||||||
|
pluginReact(),
|
||||||
|
pluginStyledComponents(),
|
||||||
|
pluginSass(),
|
||||||
|
pluginBabel({
|
||||||
|
include: /\.(?:js|jsx|tsx)$/,
|
||||||
|
babelLoaderOptions(opts) {
|
||||||
|
opts.plugins?.unshift('babel-plugin-react-compiler');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
source: {
|
||||||
|
tsconfigPath: './jsconfig.json', // Specifies the path to the JavaScript/TypeScript configuration file
|
||||||
|
},
|
||||||
|
html: {
|
||||||
|
title: 'Bruno'
|
||||||
|
},
|
||||||
|
});
|
@ -1,8 +1,6 @@
|
|||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
|
|
||||||
function Portal({ children, wrapperId }) {
|
function Portal({ children }) {
|
||||||
wrapperId = wrapperId || 'bruno-app-body';
|
return createPortal(children, document.body);
|
||||||
|
|
||||||
return createPortal(children, document.getElementById(wrapperId));
|
|
||||||
}
|
}
|
||||||
export default Portal;
|
export default Portal;
|
||||||
|
@ -70,7 +70,7 @@ const QueryUrl = ({ item, collection, handleRun }) => {
|
|||||||
|
|
||||||
const handleGenerateCode = (e) => {
|
const handleGenerateCode = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (item.request.url !== '' || (item.draft?.request.url !== undefined && item.draft?.request.url !== '')) {
|
if (item?.request?.url !== '' || (item.draft?.request?.url !== undefined && item.draft?.request?.url !== '')) {
|
||||||
setGenerateCodeItemModalOpen(true);
|
setGenerateCodeItemModalOpen(true);
|
||||||
} else {
|
} else {
|
||||||
toast.error('URL is required');
|
toast.error('URL is required');
|
||||||
|
@ -183,7 +183,7 @@ const CollectionItem = ({ item, collection, searchText }) => {
|
|||||||
const handleGenerateCode = (e) => {
|
const handleGenerateCode = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
dropdownTippyRef.current.hide();
|
dropdownTippyRef.current.hide();
|
||||||
if (item.request.url !== '' || (item.draft?.request.url !== undefined && item.draft?.request.url !== '')) {
|
if (item?.request?.url !== '' || (item?.draft?.request?.url !== undefined && item?.draft?.request?.url !== '')) {
|
||||||
setGenerateCodeItemModalOpen(true);
|
setGenerateCodeItemModalOpen(true);
|
||||||
} else {
|
} else {
|
||||||
toast.error('URL is required');
|
toast.error('URL is required');
|
||||||
|
@ -63,16 +63,16 @@ const Table = ({ minColumnWidth = 1, headers = [], children }) => {
|
|||||||
[activeColumnIndex, columns, minColumnWidth]
|
[activeColumnIndex, columns, minColumnWidth]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleMouseUp = useCallback(() => {
|
|
||||||
setActiveColumnIndex(null);
|
|
||||||
removeListeners();
|
|
||||||
}, [removeListeners]);
|
|
||||||
|
|
||||||
const removeListeners = useCallback(() => {
|
const removeListeners = useCallback(() => {
|
||||||
window.removeEventListener('mousemove', handleMouseMove);
|
window.removeEventListener('mousemove', handleMouseMove);
|
||||||
window.removeEventListener('mouseup', removeListeners);
|
window.removeEventListener('mouseup', removeListeners);
|
||||||
}, [handleMouseMove]);
|
}, [handleMouseMove]);
|
||||||
|
|
||||||
|
const handleMouseUp = useCallback(() => {
|
||||||
|
setActiveColumnIndex(null);
|
||||||
|
removeListeners?.();
|
||||||
|
}, [removeListeners]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeColumnIndex !== null) {
|
if (activeColumnIndex !== null) {
|
||||||
window.addEventListener('mousemove', handleMouseMove);
|
window.addEventListener('mousemove', handleMouseMove);
|
||||||
|
14
packages/bruno-app/src/index.js
Normal file
14
packages/bruno-app/src/index.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom/client';
|
||||||
|
import App from './pages/index';
|
||||||
|
|
||||||
|
const rootElement = document.getElementById('root');
|
||||||
|
|
||||||
|
if (rootElement) {
|
||||||
|
const root = ReactDOM.createRoot(rootElement);
|
||||||
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
|
}
|
@ -25,31 +25,7 @@ import '@fontsource/inter/900.css';
|
|||||||
import { setupPolyfills } from 'utils/common/setupPolyfills';
|
import { setupPolyfills } from 'utils/common/setupPolyfills';
|
||||||
setupPolyfills();
|
setupPolyfills();
|
||||||
|
|
||||||
function SafeHydrate({ children }) {
|
function Main({ children }) {
|
||||||
return <div suppressHydrationWarning>{typeof window === 'undefined' ? null : children}</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function NoSsr({ children }) {
|
|
||||||
const SERVER_RENDERED = typeof window === 'undefined';
|
|
||||||
|
|
||||||
if (SERVER_RENDERED) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <>{children}</>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }) {
|
|
||||||
const [domLoaded, setDomLoaded] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setDomLoaded(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!domLoaded) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!window.ipcRenderer) {
|
if (!window.ipcRenderer) {
|
||||||
return (
|
return (
|
||||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 mx-10 my-10 rounded relative" role="alert">
|
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 mx-10 my-10 rounded relative" role="alert">
|
||||||
@ -65,23 +41,21 @@ function MyApp({ Component, pageProps }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<SafeHydrate>
|
<Provider store={ReduxStore}>
|
||||||
<NoSsr>
|
<ThemeProvider>
|
||||||
<Provider store={ReduxStore}>
|
<ToastProvider>
|
||||||
<ThemeProvider>
|
<AppProvider>
|
||||||
<ToastProvider>
|
<HotkeysProvider>
|
||||||
<AppProvider>
|
{children}
|
||||||
<HotkeysProvider>
|
</HotkeysProvider>
|
||||||
<Component {...pageProps} />
|
</AppProvider>
|
||||||
</HotkeysProvider>
|
</ToastProvider>
|
||||||
</AppProvider>
|
</ThemeProvider>
|
||||||
</ToastProvider>
|
</Provider>
|
||||||
</ThemeProvider>
|
|
||||||
</Provider>
|
|
||||||
</NoSsr>
|
|
||||||
</SafeHydrate>
|
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MyApp;
|
export default Main;
|
||||||
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
import Document, { Html, Head, Main, NextScript } from 'next/document';
|
|
||||||
import { ServerStyleSheet } from 'styled-components';
|
|
||||||
|
|
||||||
export default class MyDocument extends Document {
|
|
||||||
static async getInitialProps(ctx) {
|
|
||||||
const sheet = new ServerStyleSheet();
|
|
||||||
const originalRenderPage = ctx.renderPage;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ctx.renderPage = () =>
|
|
||||||
originalRenderPage({
|
|
||||||
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />)
|
|
||||||
});
|
|
||||||
|
|
||||||
const initialProps = await Document.getInitialProps(ctx);
|
|
||||||
return {
|
|
||||||
...initialProps,
|
|
||||||
styles: (
|
|
||||||
<>
|
|
||||||
{initialProps.styles}
|
|
||||||
{sheet.getStyleElement()}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
} finally {
|
|
||||||
sheet.seal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Html>
|
|
||||||
<Head />
|
|
||||||
<body id="bruno-app-body">
|
|
||||||
<Main />
|
|
||||||
<NextScript />
|
|
||||||
</body>
|
|
||||||
</Html>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +1,16 @@
|
|||||||
import Head from 'next/head';
|
|
||||||
import Bruno from './Bruno';
|
import Bruno from './Bruno';
|
||||||
import GlobalStyle from '../globalStyles';
|
import GlobalStyle from '../globalStyles';
|
||||||
import '../i18n';
|
import '../i18n';
|
||||||
|
import Main from './Main';
|
||||||
|
|
||||||
export default function Home() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Head>
|
|
||||||
<title>Bruno</title>
|
|
||||||
<link rel="icon" href="/favicon.ico" />
|
|
||||||
</Head>
|
|
||||||
|
|
||||||
<GlobalStyle />
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<Bruno />
|
<Main>
|
||||||
|
<GlobalStyle />
|
||||||
|
<Bruno />
|
||||||
|
</Main>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -7,21 +7,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import getConfig from 'next/config';
|
|
||||||
import { PostHog } from 'posthog-node';
|
import { PostHog } from 'posthog-node';
|
||||||
import platformLib from 'platform';
|
import platformLib from 'platform';
|
||||||
import { uuid } from 'utils/common';
|
import { uuid } from 'utils/common';
|
||||||
|
|
||||||
const { publicRuntimeConfig } = getConfig();
|
|
||||||
const posthogApiKey = process.env.NEXT_PUBLIC_POSTHOG_API_KEY;
|
const posthogApiKey = process.env.NEXT_PUBLIC_POSTHOG_API_KEY;
|
||||||
let posthogClient = null;
|
let posthogClient = null;
|
||||||
|
|
||||||
const isPlaywrightTestRunning = () => {
|
const isPlaywrightTestRunning = () => {
|
||||||
return publicRuntimeConfig.PLAYWRIGHT ? true : false;
|
return process.env.PLAYWRIGHT ? true : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDevEnv = () => {
|
const isDevEnv = () => {
|
||||||
return publicRuntimeConfig.ENV === 'dev';
|
return import.meta.env.MODE === 'development';
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPosthogClient = () => {
|
const getPosthogClient = () => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import getConfig from 'next/config';
|
|
||||||
import { configureStore } from '@reduxjs/toolkit';
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
import tasksMiddleware from './middlewares/tasks/middleware';
|
import tasksMiddleware from './middlewares/tasks/middleware';
|
||||||
import debugMiddleware from './middlewares/debug/middleware';
|
import debugMiddleware from './middlewares/debug/middleware';
|
||||||
@ -8,9 +7,8 @@ import tabsReducer from './slices/tabs';
|
|||||||
import notificationsReducer from './slices/notifications';
|
import notificationsReducer from './slices/notifications';
|
||||||
import globalEnvironmentsReducer from './slices/global-environments';
|
import globalEnvironmentsReducer from './slices/global-environments';
|
||||||
|
|
||||||
const { publicRuntimeConfig } = getConfig();
|
|
||||||
const isDevEnv = () => {
|
const isDevEnv = () => {
|
||||||
return publicRuntimeConfig.ENV === 'dev';
|
return import.meta.env.MODE === 'development';
|
||||||
};
|
};
|
||||||
|
|
||||||
let middleware = [tasksMiddleware.middleware];
|
let middleware = [tasksMiddleware.middleware];
|
||||||
|
@ -35,7 +35,6 @@ export const notificationSlice = createSlice({
|
|||||||
state.loading = action.payload.fetching;
|
state.loading = action.payload.fetching;
|
||||||
},
|
},
|
||||||
setNotifications: (state, action) => {
|
setNotifications: (state, action) => {
|
||||||
console.log('notifications', notifications);
|
|
||||||
let notifications = action.payload.notifications || [];
|
let notifications = action.payload.notifications || [];
|
||||||
let readNotificationIds = state.readNotificationIds;
|
let readNotificationIds = state.readNotificationIds;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
"graphql": "^16.6.0",
|
"graphql": "^16.6.0",
|
||||||
"markdown-it": "^13.0.1",
|
"markdown-it": "^13.0.1",
|
||||||
"postcss": "8.4.47",
|
"postcss": "8.4.47",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"rollup":"3.29.5",
|
"rollup":"3.29.5",
|
||||||
"rollup-plugin-dts": "^5.0.0",
|
"rollup-plugin-dts": "^5.0.0",
|
||||||
|
@ -10,11 +10,11 @@ rm -rf packages/bruno-electron/web
|
|||||||
mkdir packages/bruno-electron/web
|
mkdir packages/bruno-electron/web
|
||||||
|
|
||||||
# Copy build
|
# Copy build
|
||||||
cp -r packages/bruno-app/out/* packages/bruno-electron/web
|
cp -r packages/bruno-app/dist/* packages/bruno-electron/web
|
||||||
|
|
||||||
|
|
||||||
# Change paths in next
|
# Change paths in next
|
||||||
sed -i'' -e 's@/_next/@_next/@g' packages/bruno-electron/web/**.html
|
sed -i'' -e 's@/static/@static/@g' packages/bruno-electron/web/**.html
|
||||||
|
|
||||||
# Remove sourcemaps
|
# Remove sourcemaps
|
||||||
find packages/bruno-electron/web -name '*.map' -type f -delete
|
find packages/bruno-electron/web -name '*.map' -type f -delete
|
||||||
|
Loading…
x
Reference in New Issue
Block a user