Coder Social home page Coder Social logo

Comments (19)

clarkdo avatar clarkdo commented on May 10, 2024 2

@kevinmarrec @pi0 Remind: As my comment above, the order of module execution needs to be guaranteed.

from typescript.

kevinmarrec avatar kevinmarrec commented on May 10, 2024

/cc @nuxt/core-team Is object usage for modules is imaginable ?

I really like the idea of being able to define module options' types, nice one @orblazer 👍

from typescript.

clarkdo avatar clarkdo commented on May 10, 2024

It can be done easily with a module or util package to transform object to array, like:

const convertModules = (modules) => {
   const nuxtModules = []
   for(const moduleName of Object.keys(modules)) {
     nuxtModules.push([
       moduleName,
       modules[moduleName]
     ])
   }
   return nuxtModules
}

// nuxt.config.js
modules: convertModules({
  '@nuxtjs/pwa': {},
  '@nuxtjs/eslint': {},
  '@nuxtjs/dotenv': {
    systemvars: true
  }
})

But if we change the core code, it may add more complexity and cannot promise the order of modules' execution, so I suggesting adding a module/util package instead of changing core code and core types.

from typescript.

pi0 avatar pi0 commented on May 10, 2024

Indeed, we can add support for object form. But can't we extend NuxtConfiguration to add new key like dotenv? Supporting both array and object form introduces complexity as @clarkdo mentioned. And for new config/ dir, should one create config/modules/@nuxtjs/dotenv.js file vs creating config/dotenv.js?

As advantages, it can be config/modules/dotenv.js which implies both adding dotenv module (if namespace resolution is automated) and also specify options. Adding module is as simple as adding a single file or key to config.

from typescript.

kevinmarrec avatar kevinmarrec commented on May 10, 2024

I totally agree about complexity if supporting both, but does the object behavior shouldn't fit better on longer term (if we don't argue about complexity right now) ?

The thing is about repetition of the key in modules and then later in config file to define options, the only way to prevent that is giving options directly with the ['moduleName', options] behavior.

Meanwhile with object behavior it would let module options around the modules scope which sounds logic.
EDIT : I think anyway there are drawbacks such as not being able to do easy things like pushing modules in Array depending on process.env.NODE_ENV .
EDIT 2 NVM it's easy with i.e. { ...prodModules }

And yes it's already possible to extend NuxtConfiguration to have autocompletion on module options if using config key behavior.

from typescript.

pi0 avatar pi0 commented on May 10, 2024

Personal opinions about mentioned concerns:

  • Multiple ways of config
    • Can be standardized by Nuxt3 to prefer modules be an object (top level and array being deprecated) which fits better for config/modules/[name].js convention.
  • Namespace complexity
    • Can be handled by resolving x to x ~> @nuxt/x ~> @nuxtjs/x ~> nuxt-x
  • Disable based on env
    • Can be foo: isProd && { } for nuxt.config or for file based: config/modules/foo.prod.js

Somehow both related & unrelated concern: How is typings supposed to be used for config/ ? :D

from typescript.

orblazer avatar orblazer commented on May 10, 2024

I very like folder config way @pi0.

If the support of config/ is planned for 3.0 and that update is planned for less 1 year, we probably can wait that and don't develop support for object because this would lead to a double change in the types declarations on modules.

If i don't abuse we can use this for typings :

export interface ModuleOptions {
  systemvars?: boolean
}

declare module 'config/modules/@nuxtjs/dotenv' {
  export default ModuleOptions
}

And with that, if create file config/modules/@nuxtjs/dotenv and with typings work if is like :

export default {
  systemvars: true
}

For that @clarkdo, we probably can add property priority if the object structure is opted.

from typescript.

kevinmarrec avatar kevinmarrec commented on May 10, 2024

Using object, order is pretty random when looping on keys, right @clarkdo ? We may not able to support object at all then.

@pi0 If you check my changes on nuxt/typescript/packages/types, I removed a lot of stuff around config/index.d.ts.
I think it should work like that :
config/build.ts -> NuxtConfiguration['build'] (directly infers build property type)
config/modules/bar.ts -> directly use options types exported by the module (import { Options } from '@nuxtjs/bar')

from typescript.

pi0 avatar pi0 commented on May 10, 2024

@clarkdo I missed the ordering matter. Indeed that's important which should be considered. @kevinmarrec it is not random and preserved (not by spec but how V8 engine incrementally creates JSObjects). But it is considerable for config dir (FS order is by name!)

config/modules/bar.ts -> directly use options types exported by the module (import { Options } from '@nuxtjs/bar')

Core can resovle it to correct package but not easy for typescript i guess as modules/bar.{j,t}s may refer to either @nuxt/bar or @nuxtjs/bar or nuxt-bar or bar package.

BTW we can keep using array + top-level keys as is until new nuxt/typescript and new config/ dir support are ready to reduce risk of complexities.

from typescript.

kevinmarrec avatar kevinmarrec commented on May 10, 2024

Hum yeah, I think it's better waiting for both things done.
For now it can be achieved like that with Nuxt 2 (typed config/, without nuxt.config.ts) :

// config/index.ts
import NuxtConfiguration from '@nuxt/config'
import modules from './modules'

const config: NuxtConfiguration = {
  modules
}

export default config
// config/modules/index.ts
import myModule from './my-module'

export default [
  myModule
]
// config/module/my-module.ts
import { Options } from 'my-module'

const options: Options = {
  property: 'value'
}

export default ['my-module', options]

And in your package.json replace all nuxt by nuxt -c config

from typescript.

clarkdo avatar clarkdo commented on May 10, 2024

I think each module should have their own type definitions, user can import the specific type, like:

// @nuxt/dotenv/types/index.d.ts
export default interface ModuleOptions {
  [0]: '@nuxtjs/dotenv',
  [1]?: {
    systemvars?: boolean
  }
}

// nuxt.config.js
import NuxtConfig from '@nuxt/config'
import NuxtDotenv from '@nuxtjs/dotenv'

const config: NuxtConfig = {
  modules: [
    [
      '@nuxtjs/dotenv', // allowed
	  // or
      '@nuxtjs/dotenv111', // not allowed
      {
        systemvars: true, // allowed
        unknown: true // not allowed
      }
    ] as NuxtDotenv 
  ]
}

from typescript.

kevinmarrec avatar kevinmarrec commented on May 10, 2024

I think it may be more something like this :

Trying to extend https://github.com/nuxt/nuxt.js/blob/dev/packages/config/types/module.d.ts

I did some tests :

Screenshot from 2019-06-17 17-07-01
Screenshot from 2019-06-17 17-13-45

But :

  1. Seems there a type inference bug that makes option as any type in my example (still give proper autocompletion though)

  2. It's not possible to extend a type, I thought of a hack which consist to create a fake interface that contains the extendable type and make it infered in the type :

interface ExtendableModule {
  extendableType: [string, { [key: string]: any }]
}

export type NuxtConfigurationModule = string | ExtendableModule['extendableType']

And then modules would need to do override ExtendableModule.extendableType, but it's not suitable for more than one module (every module type will override the previous one)

from typescript.

pi0 avatar pi0 commented on May 10, 2024

Le'ts do not forget about config/ structure and top-level keys.

I think currently you create config/modules.ts and import all module configs from separate files. It works as we manually import/export each module inside modules.ts (and import modules.ts from config/index.ts) -- this will be different with built-in config/ dir support.

When nuxt automatically scans config/ dir to construct config object, it has no clues what to do with config/pwa.ts (other than it should be available as options.pwa) -- also only loading config/index.ts by nuxt and require the user to manually import/export all options is not a good DX.

This means the way to register will be adding @nuxt/pwa in config/modules.ts and (if needed) create config/pwa.ts to customize module options which can explicitly define export type to match module.

Exporting [name, value] is not only possible for config dir and if possible, would need extra work by user to include name both in the file name and when exporting array!

from typescript.

clarkdo avatar clarkdo commented on May 10, 2024

@kevinmarrec In your example, the problem is that type-checking is broken and incorrect code hint as well, like:

type NuxtConfigModule =
  string |
  [string, { [key: string]: any }] |
  ['@nuxtjs/dotenv', { options: string } ]

const options: NuxtConfigModule = [
  'nuxtjs/dotenv',
  {
    unknown: 'works fine' // should have type error here
  }
]

const options: NuxtConfigModule = [
  'nuxtjs/foo',
  {
    options: 'with code hint' // should not have code autocompletion hint here
  }
]

from typescript.

kevinmarrec avatar kevinmarrec commented on May 10, 2024

@pi0 @clarkdo I think that this conversation would be more likely better in a RFC, we may even wait for proper Nuxt 3 config/ POC. WDYT ?

@clarkdo Yeah seems there's not really suitable solution, everything gets mixed :l

from typescript.

pi0 avatar pi0 commented on May 10, 2024

@kevinmarrec Sure we should. Just tried to highlight important difference which is mentioned above, as config/ support scans all files inside config dir. (unless we decide sooner to not to do)

from typescript.

kevinmarrec avatar kevinmarrec commented on May 10, 2024

@pi0 Any idea if this issue should be kept open ? or Should I create a specific label ?

from typescript.

orblazer avatar orblazer commented on May 10, 2024

@kevinmarrec i think this could be close instead of RFC for config/ support

from typescript.

kevinmarrec avatar kevinmarrec commented on May 10, 2024

Okay thanks @orblazer

from typescript.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.