2021-10-02 16:01:17 +00:00
import { parse , relative } from 'pathe'
2021-07-28 11:35:24 +00:00
import consola from 'consola'
import type { Nuxt , NuxtPluginTemplate , NuxtTemplate } from '../types/nuxt'
import { chainFn } from '../utils/task'
2021-11-16 16:13:19 +00:00
import { isNuxt2 , addTemplate , addPluginTemplate , addServerMiddleware } from './utils'
2021-05-24 11:14:10 +00:00
import { installModule } from './install'
2021-04-02 11:47:01 +00:00
2021-04-15 18:49:29 +00:00
/** Legacy ModuleContainer for backwards compatibility with existing Nuxt 2 modules. */
2021-06-25 09:37:18 +00:00
export function createModuleContainer ( nuxt : Nuxt ) {
return {
nuxt ,
options : nuxt.options ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/ * *
* Returns a resolved promise immediately .
*
* @deprecated
* /
ready ( ) {
return Promise . resolve ( )
} ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/** @deprecated */
addVendor ( ) {
console . warn ( 'addVendor has been deprecated and has no effect.' )
} ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/ * *
* Renders given template using lodash template during build into the project buildDir ( ` .nuxt ` ) .
*
* If a fileName is not provided or the template is string , target file name defaults to
* [ dirName ] . [ fileName ] . [ pathHash ] . [ ext ] .
* /
2021-08-09 20:54:12 +00:00
addTemplate ( template : string | NuxtTemplate ) {
if ( typeof template === 'string' ) {
template = { src : template }
}
if ( template . write === undefined ) {
template . write = true
}
return addTemplate ( template )
} ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/ * *
2021-07-28 11:35:24 +00:00
* Registers a plugin template and prepends it to the plugins [ ] array .
2021-06-25 09:37:18 +00:00
*
* Note : You can use mode or . client and . server modifiers with fileName option
* to use plugin only in client or server side .
*
* If you choose to specify a fileName , you can configure a custom path for the
* fileName too , so you can choose the folder structure inside . nuxt folder in
* order to prevent name collisioning :
*
* @example
* ` ` ` js
* this . addPlugin ( {
* src : path.resolve ( __dirname , 'templates/foo.js' ) ,
* fileName : 'foo.server.js' // [optional] only include in server bundle
* } )
* ` ` `
* /
2021-07-28 11:35:24 +00:00
addPlugin ( pluginTemplate : NuxtPluginTemplate ) : NuxtPluginTemplate {
return addPluginTemplate ( pluginTemplate )
} ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/** Register a custom layout. If its name is 'error' it will override the default error layout. */
2021-07-28 11:35:24 +00:00
addLayout ( tmpl : NuxtTemplate , name : string ) {
const { filename , src } = addTemplate ( tmpl )
2021-10-02 16:01:17 +00:00
const layoutName = name || parse ( src ) . name
2021-07-28 11:35:24 +00:00
const layout = nuxt . options . layouts [ layoutName ]
if ( layout ) {
consola . warn ( ` Duplicate layout registration, " ${ layoutName } " has been registered as " ${ layout } " ` )
}
// Add to nuxt layouts
nuxt . options . layouts [ layoutName ] = ` ./ ${ filename } `
// If error layout, set ErrorPage
if ( name === 'error' ) {
this . addErrorLayout ( filename )
}
} ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/ * *
* Set the layout that will render Nuxt errors . It should already have been added via addLayout or addTemplate .
*
* @param dst - Path to layout file within the buildDir ( ` .nuxt/<dst>.vue ` )
* /
2021-07-28 11:35:24 +00:00
addErrorLayout ( dst : string ) {
2021-10-02 16:01:17 +00:00
const relativeBuildDir = relative ( nuxt . options . rootDir , nuxt . options . buildDir )
2021-07-28 11:35:24 +00:00
nuxt . options . ErrorPage = ` ~/ ${ relativeBuildDir } / ${ dst } `
} ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/** Adds a new server middleware to the end of the server middleware array. */
addServerMiddleware ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/** Allows extending webpack build config by chaining `options.build.extend` function. */
2021-07-28 11:35:24 +00:00
extendBuild ( fn ) {
// @ts-ignore
nuxt . options . build . extend = chainFn ( nuxt . options . build . extend , fn )
} ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/** Allows extending routes by chaining `options.build.extendRoutes` function. */
2021-07-28 11:35:24 +00:00
extendRoutes ( fn ) {
2021-11-16 16:13:19 +00:00
if ( isNuxt2 ( nuxt ) ) {
nuxt . options . router . extendRoutes = chainFn ( nuxt . options . router . extendRoutes , fn )
} else {
nuxt . hook ( 'pages:extend' , async ( pages , . . . args ) = > {
const maybeRoutes = await fn ( pages , . . . args )
if ( maybeRoutes ) {
console . warn ( '[kit] [compat] Using `extendRoutes` in Nuxt 3 needs to directly modify first argument instead of returning updated routes. Skipping extended routes.' )
}
} )
}
2021-07-28 11:35:24 +00:00
} ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/** `requireModule` is a shortcut for `addModule` */
requireModule : installModule ,
2021-04-02 11:47:01 +00:00
2021-06-25 09:37:18 +00:00
/** Registers a module. moduleOpts can be a string or an array ([src, options]). */
addModule : installModule
2021-04-02 11:47:01 +00:00
}
}
2021-06-25 09:37:18 +00:00
export type ModuleContainer = ReturnType < typeof createModuleContainer >