question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Editable runtime config with HMR

See original GitHub issue

Currently, providing runtimeconfig from nuxt.config, .env and environment variables is possible but DX is not great because for each change, we need to restart Nuxt instance and there is no browser HMR.

We can introduce new app.config.[ext] (2) file that basically extends runtimeConfig.app namespace but is directly loaded by bundler (vite/webpack/nitro) and accepts hot module replacements and exposed as useAppConfig() / $appConfig (1). This file can also have more JS native types (non POJO).

import { defineAppConfig } from 'nuxt/app'

export default defineAppConfig ({
  title: 'My Website',
  seo: {
    ogImage: '/og/card.png'
  },
  theme: {
    primaryColor: '#ababab'
  }
})

Typing:

Same as RuntimeConfig, types can be inferred directly from config and extended from NuxtAppConfig interface from @nuxt/schema by modules and theme layers

HMR support:

Since the idea is to add a virtual template and dependency to the bundlers, HMR is expected to work out of the box. But we can make it even better to toggle reactivity for useRuntimeConfig() ref in app.


  1. Discussing with @Tahul, alongside with this feature, we might also introduce injected $appConfig for easier usage and access within templates.

  2. Alongside with this feature, discussing with and by experience @nuxt/content-module team, there is a very common pattern to have a theme configuration. I personally vote for the simplicity of having one app.config and $appConfig interface with theme subkey. But we can also introduce theme.config and useThemeConfig()/$themeConfig namespaced shortcuts from app config.

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:2
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

4reactions
danielroecommented, Jul 19, 2022

Stepping back from the particular question about theming and thinking more about the infrastructure Nuxt can provide to modules, what about a hybrid approach?

  • built-in support for modules ‘registering’ config files - these get automatically watched and merged across layers. Maybe a hook gets called that lets modules decide what to do when these get updated - of course this could be runtime config but it might also be direct module config (e.g. tailwindcss, windi, prisma, etc.). By using this hook the module would opting out of the whole nuxt lifecycle and indicating that it could handle all updates required within the hook itself. Nuxt could handle extensions, etc., even schema. API could be something like:

    interface RegisterConfigFileOptions {
      // ... options from https://github.com/unjs/c12
      configName
      defaults
      rcFile
      dotenv
      overrides
    }
    
    function registerConfigFile(name: string, options: RegisterConfigFileOptions) {}
    
    nuxt.hook('config:{name}', config => {
      // name is the name passed to registerConfigFile
    })
    
  • built-in support for modules initiating a hmr of app config - modules can inject their own config into this and initiate an update when something happens on module side, e.g. update from their own config file, or possibly a WS update or something else.

    nuxt.hooks.callHook('app:config', '{namespace}', config)
    
2reactions
BracketJohncommented, Jul 20, 2022

Same as RuntimeConfig, types can be inferred directly from config and extended from NuxtAppConfig interface from @nuxt/schema by modules and theme layers

One pattern that I would love to see applied here is strong data validation for the runtime config: In the python + fastapi ecosystem it is common to have a root settings.py file with runtime config definition like so ([1]):

from pydantic import BaseSettings

class Settings(BaseSettings):
    app_name: str = "Awesome API"
    admin_email: str
    items_per_user: int = 50
    database_dsn: PostgresDsn

The main point about this is that pydantic is used to validate the data to avoid a lot of trouble for developers, devops, … down the road:

  • the database_dsn will be a valid, non-empty PostgreSQL DSN,
  • the items_per_user will be a valid number
  • … and so on

For me this has been a huge boost in productivity and DX when working with fastapi: I could be sure that my configuration at least contained correctly formed data and could debug in other places when stuff was not working.

In TypeScript it would probably be possible to add similar validation via:

  • reflect-metadata (deriving automatically from native typescript, cleanest solution but probably also requires most overhead / leads to potential compability / dep errors) ([2])
  • joi and yup ([3], [4])

For me a feature like this would be a huge differentiator + I can see further use-cases like server / API data validation derived from regular typescript classes.


sources: [1]: https://fastapi.tiangolo.com/advanced/settings/#create-the-settings-object [2]: https://www.npmjs.com/package/reflect-metadata [3]: https://www.npmjs.com/package/joi [4]: https://www.npmjs.com/package/yup

Read more comments on GitHub >

github_iconTop Results From Across the Web

Hot Module Replacement - webpack
Hot Module Replacement (or HMR) is one of the most useful features offered by webpack. It allows all kinds of modules to be...
Read more >
Hot Module Replacement - webpack 3 documentation
Hot Module Replacement (or HMR) is one of the most useful features offered by webpack. It allows all kinds of modules to be...
Read more >
Hot module replacement with webpack - doc_webpack
If Webpack detects a source file change, it rebuilds only the changed module(s). Depending on the settings, Webpack will either send a signal...
Read more >
What exactly is Hot Module Replacement in Webpack?
The app code asks the HMR runtime to check for updates. The HMR runtime downloads the updates (async) and tells the app code...
Read more >
HMR: See Changes without Reloading - SymfonyCasts
HMR isn't working for styles. This is easy to fix by disabling a feature in Encore. Let me show you. Open up webpack.config.js...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found