@unsetsoft/ryunix-presets 1.0.26-canary.13 → 1.0.26-canary.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unsetsoft/ryunix-presets",
3
3
  "description": "Package with presets for different development environments.",
4
- "version": "1.0.26-canary.13",
4
+ "version": "1.0.26-canary.14",
5
5
  "author": "Neyunse",
6
6
  "type": "module",
7
7
  "repository": "https://github.com/UnSetSoft/Ryunixjs",
@@ -56,16 +56,25 @@ const StartServer = async (cliSettings) => {
56
56
  cleanCacheDir(cacheDir)
57
57
  }
58
58
 
59
- webpackConfig.mode = mode ? 'production' : 'development'
59
+ const clientConfig = Array.isArray(webpackConfig) ? webpackConfig.find(c => c.name === 'client') || webpackConfig[0] : webpackConfig
60
+
61
+ if (Array.isArray(webpackConfig)) {
62
+ webpackConfig.forEach(c => c.mode = mode ? 'production' : 'development')
63
+ } else {
64
+ webpackConfig.mode = mode ? 'production' : 'development'
65
+ }
66
+
60
67
  const compiler = Webpack(webpackConfig)
61
- let port = webpackConfig.devServer.port || 3000
68
+ let port = clientConfig.devServer?.port || 3000
62
69
 
63
70
  // Encontrar un puerto disponible
64
71
  port = await findAvailablePort(port)
65
72
 
66
73
  // Modificamos el puerto en la configuración
67
- webpackConfig.devServer.port = port
68
- const devServerOptions = { ...webpackConfig.devServer, ...cliSettings }
74
+ if (clientConfig.devServer) {
75
+ clientConfig.devServer.port = port
76
+ }
77
+ const devServerOptions = { ...(clientConfig.devServer || {}), ...cliSettings }
69
78
  const server = new WebpackDevServer(devServerOptions, compiler)
70
79
 
71
80
  const devMode = Boolean(!mode)
@@ -1,4 +1,4 @@
1
- #! /usr/bin/env node
1
+ #! /usr/bin/env node
2
2
  import yargs from 'yargs'
3
3
  import { hideBin } from 'yargs/helpers'
4
4
  import { StartDevServer } from './dev.server.mjs'
@@ -660,4 +660,5 @@ export {
660
660
  generateMetaTags,
661
661
  prerenderRoute,
662
662
  buildSSG,
663
+ importEsmFile,
663
664
  }
@@ -0,0 +1,98 @@
1
+ import fs from 'fs'
2
+ import { prerenderRoute } from './ssg.mjs'
3
+ import { resolveApp } from './index.mjs'
4
+
5
+ export async function renderDevRoute(req, res, devServer, dir, config) {
6
+ // We only care about GET requests for HTML documents
7
+ if (req.method !== 'GET' || !req.headers.accept?.includes('text/html')) {
8
+ return false
9
+ }
10
+
11
+ // Find client compiler to read index.html from its memory file system
12
+ const clientCompiler = devServer.compiler.compilers
13
+ ? devServer.compiler.compilers.find((c) => c.name === 'client')
14
+ : devServer.compiler
15
+
16
+ if (!clientCompiler) return false
17
+
18
+ const outputFs = clientCompiler.outputFileSystem
19
+ const buildDir = config.webpack.output.buildDirectory
20
+ const indexPath = resolveApp(dir, `${buildDir}/static/index.html`)
21
+
22
+ let template
23
+ try {
24
+ template = outputFs.readFileSync(indexPath, 'utf-8')
25
+ } catch (err) {
26
+ // index.html not generated yet, let the dev server handle default logic
27
+ return false
28
+ }
29
+
30
+ let AppRouterApp = null
31
+ let ryunixRenderToString = null
32
+ let ryunixCreateElement = null
33
+
34
+ try {
35
+ const serverBundlePath = resolveApp(dir, `${buildDir}/server/app-router-server.bundle.mjs`)
36
+ if (fs.existsSync(serverBundlePath)) {
37
+ if (typeof global.window === 'undefined') {
38
+ global.window = { location: { pathname: req.url } }
39
+ }
40
+ if (typeof global.document === 'undefined') {
41
+ global.document = { querySelector: () => null, getElementById: () => null }
42
+ }
43
+
44
+ const serverModule = await import(`file://${serverBundlePath}?update=${Date.now()}`)
45
+ AppRouterApp = serverModule.default?.default || serverModule.default
46
+
47
+ const ryunixCore = await import('@unsetsoft/ryunixjs')
48
+ const Ryunix = ryunixCore.default || ryunixCore
49
+ global.Ryunix = Ryunix
50
+ ryunixRenderToString = Ryunix.renderToString
51
+ ryunixCreateElement = Ryunix.createElement
52
+ }
53
+ } catch (e) {
54
+ console.warn(`[Ryunix SSR Dev] Failed to load server bundle: ${e.message}`)
55
+ return false // fallback to SPA
56
+ }
57
+
58
+ let renderedString = ''
59
+ if (AppRouterApp && ryunixRenderToString && ryunixCreateElement) {
60
+ global.window = { location: { pathname: req.url } }
61
+ try {
62
+ const element = ryunixCreateElement(AppRouterApp)
63
+ renderedString = ryunixRenderToString(element)
64
+ } catch (err) {
65
+ console.error(`[Ryunix SSR Dev] Render error:`, err)
66
+ }
67
+ }
68
+
69
+ // Generic mock route for prerenderRoute (to inject metadata)
70
+ const mockRoute = { path: req.url, meta: {} }
71
+
72
+ try {
73
+ let html = await prerenderRoute(mockRoute, template, config, renderedString)
74
+
75
+ // In dev mode with SSR, MiniCssExtractPlugin outputs CSS to the virtual filesystem.
76
+ // We need to inject <link> tags for them so there is no FOUC.
77
+ try {
78
+ const cssDir = resolveApp(dir, `${buildDir}/static/css`)
79
+ if (outputFs.existsSync(cssDir)) {
80
+ const cssFiles = outputFs.readdirSync(cssDir).filter(f => f.endsWith('.css'))
81
+ const styleLinks = cssFiles.map(f => `<link rel="stylesheet" href="/css/${f}" />`).join('\n')
82
+
83
+ if (styleLinks) {
84
+ html = html.replace('</head>', `${styleLinks}\n</head>`)
85
+ }
86
+ }
87
+ } catch (e) {
88
+ // Ignore errors reading CSS directory
89
+ }
90
+
91
+ res.setHeader('Content-Type', 'text/html; charset=utf-8')
92
+ res.end(html)
93
+ return true
94
+ } catch (err) {
95
+ console.error(`[Ryunix SSR Dev] Final render error:`, err)
96
+ return false
97
+ }
98
+ }
@@ -23,6 +23,7 @@ import RyunixRoutesPlugin from './utils/ssgPlugin.mjs'
23
23
  import AppRouterPlugin from './utils/appRouterPlugin.mjs'
24
24
  import ApiRouterPlugin from './utils/ApiRouterPlugin.mjs'
25
25
  import { handleApiRequest } from './utils/apiHandler.mjs'
26
+ import { renderDevRoute } from './utils/ssrDevHandler.mjs'
26
27
  import remarkGfm from 'remark-gfm'
27
28
  import remarkFrontmatter from 'remark-frontmatter'
28
29
  import remarkMdxFrontmatter from 'remark-mdx-frontmatter'
@@ -296,7 +297,7 @@ const getPlugins = (isServer = false) => [
296
297
  },
297
298
  }),
298
299
  !isServer &&
299
- config.webpack.production &&
300
+ (config.webpack.production || config.experimental.ssr) &&
300
301
  new MiniCssExtractPlugin({
301
302
  filename: 'css/[name].[contenthash].css',
302
303
  }),
@@ -336,6 +337,11 @@ const clientConfig = {
336
337
  },
337
338
  devServer: {
338
339
  watchFiles: [resolveApp(dir, 'src/**/*'), resolveApp(dir, 'app/**/*')],
340
+ devMiddleware: {
341
+ writeToDisk: (filePath) => {
342
+ try { return filePath.includes('/server/') || filePath.includes('\\server\\') } catch { return false }
343
+ },
344
+ },
339
345
  hot: true,
340
346
  historyApiFallback: {
341
347
  index: '/',
@@ -367,6 +373,18 @@ const clientConfig = {
367
373
  }
368
374
  })
369
375
 
376
+ devServer.app.use(async (req, res, next) => {
377
+ try {
378
+ if (config.experimental.ssr) {
379
+ const handled = await renderDevRoute(req, res, devServer, dir, config)
380
+ if (handled) return
381
+ }
382
+ } catch (err) {
383
+ console.error('[Ryunix Dev SSR]', err)
384
+ }
385
+ next()
386
+ })
387
+
370
388
  return middlewares
371
389
  },
372
390
  },
@@ -379,7 +397,7 @@ const clientConfig = {
379
397
  test: /\.s[ac]ss|css$/i,
380
398
  exclude: /node_modules/,
381
399
  use: [
382
- config.webpack.production
400
+ (config.webpack.production || config.experimental.ssr)
383
401
  ? MiniCssExtractPlugin.loader
384
402
  : ryunixRequire.resolve('style-loader'),
385
403
  ryunixRequire.resolve('css-loader'),
@@ -487,7 +505,8 @@ const serverConfig = {
487
505
  ]
488
506
  }
489
507
 
490
- // Export dual compilers only in production if SSR or SSG prerender is enabled
491
- export default (config.webpack.production && (config.experimental.ssr || config.experimental.ssg?.prerender?.length > 0))
508
+ // Export dual compilers if SSR is enabled, or in production if SSG prerender is enabled
509
+ const enableServerDualCompiler = config.experimental.ssr || (config.webpack.production && config.experimental.ssg?.prerender?.length > 0);
510
+ export default enableServerDualCompiler
492
511
  ? [clientConfig, serverConfig]
493
512
  : clientConfig;