Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't override default plugins #1212

Closed
imlautaro opened this issue Jun 4, 2022 · 6 comments · Fixed by #1226
Closed

Can't override default plugins #1212

imlautaro opened this issue Jun 4, 2022 · 6 comments · Fixed by #1226

Comments

@imlautaro
Copy link

Environment

  • Operating System: Linux
  • Node Version: v14.17.3
  • Nuxt Version: 3.0.0-rc.3
  • Package Manager: [email protected]
  • Builder: vite
  • User Config: content, modules
  • Runtime Modules: @nuxt/[email protected]
  • Build Modules: -

Reproduction

https://github.com/imlautaro/content-app

Describe the bug

When you try to override the remark plugins (following the instructions in the documentation), it returns an error.

export default defineNuxtConfig({
  content: {
    markdown: {
      remarkPlugins: () => ['remark-emoji']
    }
  }
})
ERROR  Cannot start nuxt:  (options.remarkPlugins || []).map is not a function   

Additional context

No response

Logs

ERROR  Cannot start nuxt:  (options.remarkPlugins || []).map is not a function                                                                           17:05:30

  at processMarkdownOptions (node_modules/@nuxt/content/dist/module.mjs:82:57)
  at setup (node_modules/@nuxt/content/dist/module.mjs:264:31)
  at async Object.normalizedModule (node_modules/@nuxt/kit/dist/index.mjs:583:5)
  at async installModule (node_modules/@nuxt/kit/dist/index.mjs:398:3)
  at async initNuxt (node_modules/nuxt/dist/index.mjs:1336:7)
  at async load (node_modules/nuxi/dist/chunks/dev.mjs:6734:9)
  at async Object.invoke (node_modules/nuxi/dist/chunks/dev.mjs:6777:5)
  at async _main (node_modules/nuxi/dist/cli.mjs:46:20)
@harlan-zw
Copy link
Contributor

harlan-zw commented Jun 5, 2022

Looks like the doc is incorrect, you should provide an array of strings only

export default defineNuxtConfig({
  content: {
    markdown: {
      remarkPlugins: ['remark-emoji']
    }
  }
})

@imlautaro
Copy link
Author

But in Content v1 you use a string array when you want to add plugins and a function when you want to override the default ones. I think that way makes more sense 🤔

@harlan-zw
Copy link
Contributor

harlan-zw commented Jun 6, 2022

I don't disagree, just telling you how the code is setup in case you want to unblock yourself.

This issue should be closed only if the doc is updated or the functionality is supported

@pavlexander
Copy link

pavlexander commented Jun 7, 2022

thank you for bringing this topic up! I have struggled with the similar problem, description is here : https://github.com/nuxt/framework/discussions/5163

Not able to override routes using the function because it expects an array.. Seems like this issue not specific to nuxt content per se, but a general problem in nuxt itself. I might be wrong though.

After 11 days my question is not answered yet, so I will try to follow up on this problem in your topic instead :)

@nozomuikuta
Copy link
Collaborator

nozomuikuta commented Jun 7, 2022

If I'm correct, the current situation is like the following:

While Nuxt Content v1 uses its own module option resolution logic (i.e. defu.arrayFn()), Nuxt Content v2 relies on Nuxt Kit's built-in module resolution logic (i.e. defu()).

const options = defu.arrayFn(content, defaults)

// https://github.com/nuxt/framework/blob/643641d4891e2dc0ca261b594acefe3d4c4ac5c7/packages/kit/src/module/define.ts#L33-L41
// `applyDefaults` would not be called in case of Nuxt Content v2
function getOptions (inlineOptions?: OptionsT, nuxt: Nuxt = useNuxt()) {
  const configKey = definition.meta.configKey || definition.meta.name
  const _defaults = definition.defaults instanceof Function ? definition.defaults(nuxt) : definition.defaults
  let _options = defu(inlineOptions, nuxt.options[configKey], _defaults) as OptionsT
  if (definition.schema) {
    _options = applyDefaults(definition.schema, _options) as OptionsT
  }
  return Promise.resolve(_options)
}

What @imlautaro wants to do can be achieved with defu.arrayFn(), so Nuxt Kit seems to have to be changed, which would be a breaking change in Nuxt 3 Release Candidate. Another approach is, as @harlan-zw says, dropping the feature support and update the Nuxt Content documentation.

@atinux
Sorry, you might be taking a break after the big conference, but I guess only authors will be able to give us an answer and/or make a decision on this issue.

Or, it's appreciated if someone points out that I don't understand the situation correctly and there is a way to achieve the goal.


IMHO, defu.arrayFn() is worth introducing to Nuxt Kit even if it's a breaking change, because it's more flexible than defu(), although alignment with applyDefaults()'s behavior might be an issue.

@pi0
Copy link
Member

pi0 commented Jun 7, 2022

@nozomuikuta In general for Nuxt, we cannot use arrayFn for merging config since it only evaluates the function if the default value is an Array and if it is, it force evaluates the function which is not always the intended behavior. Also makes issue for Type support. (See *)

However, modules like content can support this explicitly and apply defaults in the module body. This experience for module authors would be simpler later using schema and untyped support in the module definition. We can also add an option to opt-in for this per module defenition but IMO just makes module spec more complex while we have simpler ways to achieve the same both for module authors and end-users.

(*) As a related note to the content module and related use cases, if the intended defaults behavior is overriding and not extending, instead of adding function complexity, they could add only when user options are not provided conditionally. So that users don't need a function to override and can simply pass an array. Another pattern would be using a KV object so that users can explicitly disable on of the built-in plugins. We use this for postcsss plugins options for example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants