Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(devtools): ability to change ports and domains in devtools server #6185

Merged
merged 22 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
12e1687
chore(cli): remove unused env vars
aliemir Jul 24, 2024
d09cde9
fix(cli): prevent polluting process.env with dotenv read
aliemir Jul 24, 2024
b4a1791
chore(cli): add ability to pass env to running script
aliemir Jul 24, 2024
adac05f
feat(devtools-server): ability to change ports via REFINE_DEVTOOLS_PO…
aliemir Jul 24, 2024
9dc09a4
feat(devtools): use devtools url from env variable and accept fallbac…
aliemir Jul 24, 2024
f34378f
chore(devtools-shared): allow url and remove unused context values
aliemir Jul 24, 2024
8e2916d
feat(devtools-ui): register to devtools with own url
aliemir Jul 24, 2024
f24dc6c
chore(devtools-server): add dotenv dependency
aliemir Jul 24, 2024
2264a42
feat(cli): pass refine devtools port to dev server script with proper…
aliemir Jul 24, 2024
f7c4ce5
chore(devtools-ui): send message to parent frame when loaded
aliemir Jul 24, 2024
dc2c254
feat(devtools): handle unreachable server error
aliemir Jul 24, 2024
c1254e9
chore: add changesets
aliemir Jul 24, 2024
3589bb6
docs(devtools): add port change
aliemir Jul 24, 2024
314d294
docs(devtools): add enterprise devtools docs
aliemir Jul 24, 2024
30cea97
chore(typos): ignore runner command typo
aliemir Jul 25, 2024
606201e
chore: update pnpm lock
aliemir Jul 25, 2024
6c3535a
Merge branch 'releases/august' into feat/devtools-port-change-ability
BatuhanW Jul 25, 2024
dbe7be7
docs(devtools): update docker config in devtools with custom domain s…
aliemir Jul 29, 2024
0cb78d8
docs(devtools): fix runner command
aliemir Jul 30, 2024
bbfca35
docs(devtools): fix comment in dockerfile
aliemir Jul 30, 2024
dd75fb1
chore: update changeset version
aliemir Jul 30, 2024
d143f0e
Merge branch 'releases/august' into feat/devtools-port-change-ability
aliemir Jul 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/bright-dryers-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@refinedev/core": patch
---

Bump `@refinedev/devtools-internal` dependency to reflect the latest changes in the Refine Devtools.
11 changes: 11 additions & 0 deletions .changeset/shiny-planes-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@refinedev/cli": patch
---

fix(cli): avoid polluting `process.env` with unwanted environment variables

Previously, the `@refinedev/cli` used `dotenv` to load environment variables from `.env` files and populate `process.env`. This caused issues when the users app has a different convention for environment variables, e.g. `.env.development`, `.env.production`, etc.

Now, the `@refinedev/cli` will read the file but avoid populating `process.env` with the variables and keep the values in its scope without passing them to the child processes. This will prevent unwanted environment variables from being passed to the child processes and avoid conflicts with the user's environment variables.

[Resolves #5803](https://github.com/refinedev/refine/issues/5803)
26 changes: 26 additions & 0 deletions .changeset/twenty-months-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
"@refinedev/cli": patch
"@refinedev/devtools-server": minor
"@refinedev/devtools-shared": minor
"@refinedev/devtools-ui": minor
"@refinedev/devtools": minor
"@refinedev/devtools-internal": minor
---

feat(devtools): ability to change the port of the devtools server

Now users can change the port of the devtools server by setting the `REFINE_DEVTOOLS_PORT` environment variable. Previously, the port was hardcoded to "5001" and could not be changed.

If you're using `@refinedev/cli`'s runner commands to start your development server, `REFINE_DEVTOOLS_PORT` will be propagated to your app with appropriate prefix. E.g. if you're using Vite, the environment variable will be `VITE_REFINE_DEVTOOLS_PORT` and it will be used by the `@refinedev/devtools`'s `<DevtoolsProvider />` component to connect to the devtools server.

- In Next.js apps, it will be prefixed with `NEXT_PUBLIC_`
- In Craco and Create React App apps, it will be prefixed with `REACT_APP_`
- In Remix apps and other custom setups, the environment variable will be used as is.

In some scenarios where the environment variables are not passed to the browser, you may need to manually set the Refine Devtools URL in the `<DevtoolsProvider />` component via the `url` prop. Remix apps do not automatically pass environment variables to the browser, so you will need to set the URL manually. If not set, the default URL will be used.

While the port can be changed, this feature also allows users to host the devtools server on a different machine or domain and provide the `<DevtoolsProvider />` with the custom domain URL. This such case will be useful if you're dockerizing your app and devtools server separately.

**Enterprise Edition**: Refine Devtools running on ports other than "5001" is only available in the Enterprise Edition. If you're using the Community Edition, Refine Devtools will not work if the port is changed.

[Resolves #5111](https://github.com/refinedev/refine/issues/5111)
203 changes: 203 additions & 0 deletions documentation/docs/enterprise-edition/devtools/docker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import React from "react";
import { Sandpack } from "@site/src/components/sandpack";

export default function DockerExample() {
return (
<Sandpack
showNavigator={false}
showLineNumbers
showFiles
hidePreview
showOpenInCodeSandbox={false}
dependencies={{
"@refinedev/core": "latest",
"@refinedev/simple-rest": "latest",
"@refinedev/react-router-v6": "latest",
"react-router-dom": "latest",
"react-router": "latest",
}}
files={{
"/App.tsx": {
code: AppTsxCode,
},
"/package.json": {
code: PackageJsonCode,
},
"/Dockerfile.dev": {
code: DockerfileDevCode,
},
"/Dockerfile.devtools": {
code: DockerfileDevtoolsCode,
},
"/docker-compose.yml": {
code: DockerComposeYmlCode,
},
"/nginx.conf": {
code: NginxConfCode,
},
"/style.css": {
code: "",
hidden: true,
},
}}
/>
);
}

const AppTsxCode = /* jsx */ `
import { Refine } from "@refinedev/core";
import { DevtoolsProvider, DevtoolsPanel } from "@refinedev/devtools";

export default function App() {
return (
<DevtolsProvider
url="http://devtools.local"
>
<Refine
// ...
>
{/* ... */}
<DevtoolsPanel />
</Refine>
</DevtolsProvider>
)
}
`.trim();

const PackageJsonCode = /* json */ `
{
"name": "my-app",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "refine dev --devtools false -- --host",
"devtools": "refine devtools",
"refine": "refine"
},
"dependencies": {
"@refinedev/cli": "^2.16.36",
"@refinedev/core": "^4.53.0",
"@refinedev/devtools": "^1.2.6"
}
}
`.trim();

const DockerfileDevCode = /* dockerfile */ `
# We're setting up our development server and running it on port 5173.
# We'll then use Nginx to reverse proxy the requests to the correct services.
# We're running the application at port 5173 and we'll access it via http://my-app.local.

# Use the official Node.js image as a parent image
FROM refinedev/node

# Copy the package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application
COPY . .

# Expose the port the app runs on
EXPOSE 5173

# Command to run the development server
CMD ["npm", "run", "dev"]
`.trim();

const DockerfileDevtoolsCode = /* dockerfile */ `
# We're setting up our Devtools server and running it on port 5001.
# We'll then use Nginx to reverse proxy the requests to the correct services.
# We're running devtools at port 5001 and we'll access it via http://devtools.local.

# Use the Refine's Node.js image as a parent image
FROM refinedev/node

# Copy the package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application
COPY . .

# Expose the port the devtools server runs on
EXPOSE 5001

# Command to run the devtools server
CMD ["npm", "run", "devtools"]
`.trim();

const DockerComposeYmlCode = /* yaml */ `
# We're setting up a development environment with two services: dev and devtools.
# The dev service is the main service that runs the application.
# The devtools service is the service that runs the Refine Devtools.
version: "3"
services:
dev:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- app:/app/refine
- /app/refine/node_modules
networks:
- dev-network
devtools:
build:
context: .
dockerfile: Dockerfile.devtools
volumes:
- app:/app/refine
- /app/refine/node_modules
networks:
- dev-network
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
- dev-network
networks:
dev-network:
driver: bridge
volumes:
app:
`.trim();

const NginxConfCode = /* nginx */ `
# We're setting up a reverse proxy to map the requests to the correct services.
# Then we'll add the necessary aliases to the /etc/hosts file to make the services accessible via the domain names.
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name my-app.local;
location / {
proxy_pass http://dev:5173;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name devtools.local;
location / {
proxy_pass http://devtools:5001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
`.trim();
52 changes: 52 additions & 0 deletions documentation/docs/enterprise-edition/devtools/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Devtools
---

import DockerUsage from "./docker.tsx";

# Refine Devtools

In addition to the features provided by the [Refine Devtools](/docs/guides-concepts/development/#using-devtools), Enterprise Edition allows you to change the port of the devtools server or use a custom domain for the devtools server. This is useful if you're dockerizing your app and devtools server separately or using multiple Refine apps and want to use Refine Devtools for multiple apps.

## Specifying the Port

You can be using `@refinedev/cli` or `@refinedev/devtools-server` to start the devtools server. Both of these tools will respect the `REFINE_DEVTOOLS_PORT` environment variable. Changing the port is as simple as setting the `REFINE_DEVTOOLS_PORT` environment variable to the desired port number.

```bash
REFINE_DEVTOOLS_PORT=5002 refine dev
```

When `REFINE_DEVTOOLS_PORT` is set in `refine dev` command, it will be automatically propagated to your App and made available as an environment variable. The environment variable will automatically be used by the `<DevtoolsProvider />` component of the `@refinedev/devtools` to connect to the devtools server. If the environment variable is not working in the browser or you want to use a custom domain, you can manually set the URL in the `<DevtoolsProvider />` component via the `url` prop.

```tsx title="App.tsx"
import Refine from "@refinedev/core";
import { DevtoolsProvider, DevtoolsPanel } from "@refinedev/devtools";

const App = () => {
return (
<DevtoolsProvider
// highlight-next-line
url="http://refine-devtools.local"
>
<Refine>
{/* ... */}
<DevtoolsPanel />
</Refine>
);
};
```

## Using Custom Domains with Docker

In this example, we'll dockerize a Refine app and Refine Devtools separately and serve them on `http://my-app.local` and `http://devtools.local` respectively. After our setup is complete, we'll use the `url` prop of the `<DevtoolsProvider />` component to connect to the devtools server.

<DockerUsage />

Then, we'll need to update our `/etc/hosts` file to point `my-app.local` and `devtools.local` to `127.0.0.1`,

```txt
127.0.0.1 my-app.local
127.0.0.1 devtools.local
```

That's it! Now you can run your Refine app and Refine Devtools separately in Docker containers and connect to the devtools server using the custom domain. Notice that we're only changing one line in our `App.tsx` file to use the custom domain, rest will be handled by the `@refinedev/devtools` package.
17 changes: 14 additions & 3 deletions documentation/docs/guides-concepts/development/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,13 @@ import { DevtoolsPanel, DevtoolsProvider } from "@refinedev/devtools";

const App = () => {
return (
// highlight-next-line
<DevtoolsProvider>
{/* highlight-start */}
<DevtoolsProvider
// If you're running devtools server on a different port or a domain, you can set the URL manually.
// Note that, custom domains and ports are only available in the Enterprise Edition.
// url="http://localhost:5001"
>
{/* highlight-end */}
<Refine
// ...
>
Expand Down Expand Up @@ -277,7 +282,13 @@ As an alternative, you can also install the `@refinedev/devtools-server` package

**Required Ports**

Devtools server will run on port `5001`. Devtools will serve HTTP and WebSocket connections on this port. Make sure the port is available on your machine.
Devtools server will run on port `5001` by default. Devtools will serve HTTP and WebSocket connections on this port. If you want to change the port, you can set the `REFINE_DEVTOOLS_PORT` environment variable to the desired port number.

:::simple Enterprise Edition

Refine Devtools running on ports other than "5001" is only available in the Enterprise Edition. If you're using the Community Edition, Refine Devtools will not work if the port is changed. Checkout [Refine Devtools in Enterprise Edition](/docs/enterprise-edition/devtools) for more information.

:::

## Using Inferencer

Expand Down
5 changes: 4 additions & 1 deletion documentation/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,10 @@ module.exports = {
type: "category",
label: "Enterprise Edition",
className: "category-as-header",
items: ["enterprise-edition/okta/index"],
items: [
"enterprise-edition/okta/index",
"enterprise-edition/devtools/index",
],
},
// Migration Guide
{
Expand Down
14 changes: 11 additions & 3 deletions packages/cli/src/commands/runner/dev/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ProjectTypes } from "@definitions/projectTypes";
import { getProjectType } from "@utils/project";
import { getDevtoolsEnvKeyByProjectType, getProjectType } from "@utils/project";
import { type Command, Option } from "commander";
import { updateNotifier } from "src/update-notifier";
import { devtoolsRunner } from "src/commands/devtools";
import { projectScripts } from "../projectScripts";
import { runScript } from "../runScript";
import { getPlatformOptionDescription, getRunnerDescription } from "../utils";
import { isDevtoolsInstalled } from "@utils/package";
import { isDevtoolsInstalled } from "src/utils/package";
import { ENV } from "src/utils/env";

const dev = (program: Command) => {
return program
Expand Down Expand Up @@ -44,6 +45,8 @@ const action = async (

await updateNotifier();

const devtoolsPortEnvKey = getDevtoolsEnvKeyByProjectType(projectType);

const devtoolsDefault = await isDevtoolsInstalled();

const devtools = params.devtools === "false" ? false : devtoolsDefault;
Expand All @@ -52,7 +55,12 @@ const action = async (
devtoolsRunner({ exitOnError: false });
}

runScript(binPath, command);
const envWithDevtoolsPort =
devtools && ENV.REFINE_DEVTOOLS_PORT
? { [devtoolsPortEnvKey]: ENV.REFINE_DEVTOOLS_PORT }
: undefined;

runScript(binPath, command, envWithDevtoolsPort);
};

export default dev;
Loading
Loading