Nuxt/packages/kit/src/module/install.ts

65 lines
2.1 KiB
TypeScript
Raw Normal View History

import { resolveModule, requireModule, importModule } from '../utils/cjs'
import { resolveAlias } from '../utils/resolve'
import type { LegacyNuxtModule, NuxtModule, ModuleMeta, ModuleInstallOptions, ModuleOptions, ModuleSrc } from '../types/module'
import type { Nuxt } from '../types/nuxt'
import { defineNuxtModule } from './define'
import { createModuleContainer } from './container'
2021-04-15 18:49:29 +00:00
/** Installs a module on a Nuxt instance. */
export async function installModule (nuxt: Nuxt, installOpts: ModuleInstallOptions) {
let src: ModuleSrc
let options: ModuleOptions = {}
const meta: ModuleMeta = {}
// Extract src, meta and options
if (typeof installOpts === 'string') {
src = installOpts
} else if (Array.isArray(installOpts)) {
[src, options] = installOpts
} else if (typeof installOpts === 'object') {
if (installOpts.src || installOpts.handler) {
src = installOpts.src || installOpts.handler
options = installOpts.options
Object.assign(meta, installOpts.meta)
} else {
src = installOpts as NuxtModule
}
} else {
src = installOpts
}
// Resolve as legacy handler
let handler: LegacyNuxtModule
if (typeof src === 'string') {
const _src = resolveModule(resolveAlias(src, nuxt.options.alias), { paths: nuxt.options.modulesDir })
// TODO: also check with type: 'module' in closest `package.json`
const isESM = _src.endsWith('.mjs') || meta.isESM
handler = isESM ? await importModule(_src) : requireModule(_src)
if (!meta.name) {
meta.name = src
}
} else if (typeof src === 'function') {
handler = src
} else {
handler = defineNuxtModule(src)
}
// Merge meta
if (handler.meta) {
Object.assign(meta, handler.meta)
}
// Ensure module is required once
if (typeof meta.name === 'string') {
nuxt.options._requiredModules = nuxt.options._requiredModules || {}
if (nuxt.options._requiredModules[meta.name]) {
return
}
nuxt.options._requiredModules[meta.name] = true
}
// Execute in legacy container
const container = createModuleContainer(nuxt)
await handler.call(container, options)
}