Skip to content

Commit

Permalink
feat: introduce local module entry
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Feb 23, 2023
1 parent 8a62d1f commit 0b42fde
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 52 deletions.
65 changes: 65 additions & 0 deletions local.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Local developement module entry
*
* Change `@nuxt/devtools` to the absolute path of this module in any of your Nuxt projects,
* allows you to try Nuxt Devtools locally directly from the source code. HMR is supported
* for the front-end client.
*
* For example, if you clone this repo to `/users/me/nuxt-devtools`, update your nuxt config:
*
* ```diff
* // nuxt.config.ts
* export default defineNuxtConfig({
* modules: [
* - '@nuxt/devtools',
* + '/users/me/nuxt-devtools/local',
* ]
* })
* ```
*/
import { defineNuxtModule, logger } from '@nuxt/kit'
import { execa } from 'execa'
import { resolve } from 'pathe'
import { getPort } from 'get-port-please'
import { ROUTE_CLIENT, defaultOptions } from './packages/devtools/src/constant'
import type { ModuleOptions } from './packages/devtools/src/types'
import { packageDir } from './packages/devtools/src/dirs'
import { enableModule } from './packages/devtools/src/module-main'

export type { ModuleOptions }

export default defineNuxtModule<ModuleOptions>({
meta: {
name: '@nuxt/devtools',
configKey: 'devtools',
},
defaults: defaultOptions,
async setup(options, nuxt) {
const clientDir = resolve(packageDir, 'client')
const workspaceRoot = resolve(packageDir, '../..')
const PORT = await getPort({ port: 12442 })

// TODO: add embedded terminal and forward logs to it
const subprocess = execa('npx', ['nuxi', 'dev', '--port', PORT.toString()], { cwd: clientDir, stdio: 'pipe' })
subprocess.stderr?.pipe(process.stderr)

nuxt.hook('vite:extendConfig', (config) => {
config.server ||= {}
// add proxy to client
config.server.proxy ||= {}
config.server.proxy[ROUTE_CLIENT] = {
target: `http://localhost:${PORT}`,
changeOrigin: true,
followRedirects: true,
}
// add fs allow for local modules
config.server.fs ||= {}
config.server.fs.allow ||= []
config.server.fs.allow.push(workspaceRoot)
})

logger.info(`Nuxt Devtools is using local client from \`${clientDir}\``)

return enableModule(options, nuxt)
},
})
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
"bumpp": "^8.2.1",
"conventional-changelog-cli": "^2.2.2",
"eslint": "^8.34.0",
"execa": "^7.0.0",
"get-port-please": "^3.0.1",
"nuxt": "^3.2.2",
"pathe": "^1.1.0",
"typescript": "^4.9.5",
"vue-tsc": "^1.1.7"
}
Expand Down
15 changes: 15 additions & 0 deletions packages/devtools/src/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { ModuleOptions } from '@nuxt/schema'

export const ROUTE_PATH = '/__nuxt_devtools__'
export const ROUTE_ENTRY = `${ROUTE_PATH}/entry`
export const ROUTE_CLIENT = `${ROUTE_PATH}/client`

export const defaultOptions: ModuleOptions = {
enabled: undefined,
vscode: {
enabled: true,
startOnBoot: false,
port: 3080,
reuseExistingServer: true,
},
}
25 changes: 25 additions & 0 deletions packages/devtools/src/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { ModuleCustomTab } from './types'

declare module '@nuxt/schema' {
interface NuxtHooks {
/**
* Called before devtools starts. Useful to detect if devtools is enabled.
*/
'devtools:before': () => void

/**
* Called after devtools is initialized.
*/
'devtools:initialized': () => void

/**
* Hooks to extend devtools tabs.
*/
'devtools:customTabs': (tabs: ModuleCustomTab[]) => void

/**
* Retrigger update for custom tabs, `devtools:customTabs` will be called again.
*/
'devtools:customTabs:refresh': () => void
}
}
11 changes: 4 additions & 7 deletions packages/devtools/src/module-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import { version } from '../package.json'
import type { ModuleOptions } from './types'
import { setupRPC } from './rpc'
import { clientDir, packageDir, runtimeDir } from './dirs'

const PATH = '/__nuxt_devtools__'
const PATH_ENTRY = `${PATH}/entry`
const PATH_CLIENT = `${PATH}/client`
import { ROUTE_CLIENT, ROUTE_ENTRY } from './constant'

export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
// Disable in test mode
Expand Down Expand Up @@ -58,11 +55,11 @@ export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {

// TODO: Use WS from nitro server when possible
nuxt.hook('vite:serverCreated', (server: ViteDevServer) => {
server.middlewares.use(PATH_ENTRY, tinyws() as any)
server.middlewares.use(PATH_ENTRY, rpcMiddleware as any)
server.middlewares.use(ROUTE_ENTRY, tinyws() as any)
server.middlewares.use(ROUTE_ENTRY, rpcMiddleware as any)
// serve the front end in production
if (clientDirExists)
server.middlewares.use(PATH_CLIENT, sirv(clientDir, { single: true, dev: true }))
server.middlewares.use(ROUTE_CLIENT, sirv(clientDir, { single: true, dev: true }))
})

const integrations = [
Expand Down
40 changes: 5 additions & 35 deletions packages/devtools/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,17 @@
import { defineNuxtModule } from '@nuxt/kit'
import isInstalledGlobally from 'is-installed-globally'
import type { ModuleCustomTab, ModuleGlobalOptions, ModuleOptions } from './types'
import { defaultOptions } from './constant'
import type { ModuleGlobalOptions, ModuleOptions } from './types'
import './hooks'

export type { ModuleOptions }

declare module '@nuxt/schema' {
interface NuxtHooks {
/**
* Called before devtools starts. Useful to detect if devtools is enabled.
*/
'devtools:before': () => void

/**
* Called after devtools is initialized.
*/
'devtools:initialized': () => void

/**
* Hooks to extend devtools tabs.
*/
'devtools:customTabs': (tabs: ModuleCustomTab[]) => void

/**
* Retrigger update for custom tabs, `devtools:customTabs` will be called again.
*/
'devtools:customTabs:refresh': () => void
}
}

export default defineNuxtModule<ModuleOptions>({
meta: {
name: '@nuxt/devtools',
configKey: 'devtools',
},
defaults: {
enabled: undefined,
vscode: {
enabled: true,
startOnBoot: false,
port: 3080,
reuseExistingServer: true,
},
},
defaults: defaultOptions,
setup(options, nuxt) {
// Explicitly disabled
if (options.enabled === false)
Expand All @@ -57,7 +27,7 @@ export default defineNuxtModule<ModuleOptions>({
/**
* Enable conditions:
*
* - `enabled` is not explicitly set to false
* - `enabled` is NOT explicitly set to false
* - Installed locally
* - Installed globally, and enabled via `nuxi enable devtools`, or `enabled` is explicitly set to true
*/
Expand Down
18 changes: 8 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0b42fde

Please sign in to comment.