Skip to content

Commit

Permalink
feat(vite): add ssrLoadModule method
Browse files Browse the repository at this point in the history
  • Loading branch information
jlenon7 committed Jan 15, 2025
1 parent 60a57dd commit 1e5f357
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 11 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@athenna/vite",
"version": "5.8.0",
"version": "5.9.0",
"description": "Vite plugin for Athenna Framework.",
"license": "MIT",
"author": "João Lenon <[email protected]>",
Expand Down
17 changes: 13 additions & 4 deletions src/fastify/FastifyVite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import type { FastifyViteOptions } from '#src/types'

export class FastifyVite {
public scope: FastifyInstance
public vite: Vite
public devServer: ViteDevServer
public options: FastifyViteOptions

Expand All @@ -38,7 +39,7 @@ export class FastifyVite {
this.options = Options.create(options, {
root: Path.pwd(),
assetsUrl: '/public/assets',
buildDirectory: 'public/assets',
buildDirectory: Path.public('assets'),
dev: Config.is('app.environment', 'production'),
manifestFile: this.options?.buildDirectory
? path.join(this.options.buildDirectory, '.vite/manifest.json')
Expand All @@ -54,6 +55,14 @@ export class FastifyVite {
return this.devServer
}

/**
* Return vite helper instance. Only available
* after calling `ready()` method.
*/
public getVite() {
return this.vite
}

/**
* Load vite configuration file and start the dev server.
* Will not start the dev server if in production.
Expand Down Expand Up @@ -99,10 +108,10 @@ export class FastifyVite {
debug('vite server creation bypassed because app is in production mode.')
}

const vite = new Vite(this.options, this.devServer)
this.vite = new Vite(this.options, this.devServer)

View.edge.global('vite', vite)
View.edge.global('asset', vite.assetPath.bind(vite))
View.edge.global('vite', this.vite)
View.edge.global('asset', this.vite.assetPath.bind(this.vite))
View.edge.registerTag({
tagName: 'viteReactRefresh',
seekable: true,
Expand Down
31 changes: 27 additions & 4 deletions src/types/fastify/FastifyViteOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ export type FastifyViteOptions = {
*/
dev?: boolean

/**
* The URL to prefix when generating assets URLs. For example: This
* could the CDN URL when generating the production build.
*
* @default '/public/assets'
*/
assetsUrl?: string

/**
* Public directory where the assets will be compiled.
*
Expand All @@ -54,12 +62,27 @@ export type FastifyViteOptions = {
manifestFile?: string

/**
* The URL to prefix when generating assets URLs. For example: This
* could the CDN URL when generating the production build.
* Path to the SSR entrypoint file that will be used to compile
* using `--ssr` option.
*
* @default '/public/assets'
* @default 'src/resources/app/app.tsx'
*/
assetsUrl?: string
ssrEntrypoint?: string

/**
* Public directory where the SSR assets will be compiled.
*
* @default Path.public('assets/server')
*/
ssrBuildDirectory?: string

/**
* Path to the SSR manifest file relative from the root of
* the application.
*
* @default Path.public('assets/server/.vite/manifest.json')
*/
ssrManifestFile?: string

/**
* A custom set of attributes to apply on all
Expand Down
40 changes: 40 additions & 0 deletions src/vite/Vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export class Vite {
*/
public manifestCache?: Manifest

/**
* We cache the SSR manifest file content in production
* to avoid reading the file multiple times.
*/
public ssrManifestCache?: Manifest

/**
* Vite dev server instance.
*/
Expand Down Expand Up @@ -471,6 +477,25 @@ export class Vite {
return this.manifestCache!
}

/**
* Returns the SSR manifest file contents.
*
* @throws Will throw an exception when running in dev.
*/
public ssrManifest(): Manifest {
if (this.devServer) {
throw new Error(
'Cannot read the SSR manifest file when running in dev mode'
)
}

if (!this.ssrManifestCache) {
this.ssrManifestCache = this.readFileAsJSON(this.options.ssrManifestFile)
}

return this.ssrManifestCache!
}

/**
* Returns the script needed for the HMR working with React.
*/
Expand All @@ -496,4 +521,19 @@ export class Vite {
]
})
}

/**
* Safely load an SSR module by looking to the dev
* server or the SSR manifest file.
*/
public async ssrLoadModule(modulePath: string) {
if (this.devServer) {
return this.devServer.ssrLoadModule(modulePath)
}

const ssrManifest = this.ssrManifest()
const chunk = this.chunk(ssrManifest, modulePath)

return import(`${this.options.ssrBuildDirectory}${path.sep}${chunk.file}`)
}
}

0 comments on commit 1e5f357

Please sign in to comment.