2021-08-11 20:28:38 +00:00
|
|
|
import { addVitePlugin, addWebpackPlugin, defineNuxtModule, addTemplate, resolveAlias, addPluginTemplate } from '@nuxt/kit'
|
2021-10-05 20:47:19 +00:00
|
|
|
import { isAbsolute, relative, resolve } from 'pathe'
|
2021-08-10 00:27:23 +00:00
|
|
|
import type { Identifiers, GlobalImportsOptions } from './types'
|
2021-08-24 07:49:03 +00:00
|
|
|
import { TransformPlugin } from './transform'
|
2021-08-10 00:27:23 +00:00
|
|
|
import { defaultIdentifiers } from './identifiers'
|
|
|
|
|
|
|
|
export default defineNuxtModule<GlobalImportsOptions>({
|
|
|
|
name: 'global-imports',
|
|
|
|
configKey: 'globalImports',
|
|
|
|
defaults: { identifiers: defaultIdentifiers },
|
2021-10-02 16:59:32 +00:00
|
|
|
setup ({ disabled = [], identifiers }, nuxt) {
|
|
|
|
for (const key of disabled) {
|
|
|
|
delete identifiers[key]
|
|
|
|
}
|
2021-08-10 00:27:23 +00:00
|
|
|
if (nuxt.options.dev) {
|
|
|
|
// Add all imports to globalThis in development mode
|
|
|
|
addPluginTemplate({
|
|
|
|
filename: 'global-imports.mjs',
|
|
|
|
src: '',
|
|
|
|
getContents: () => {
|
|
|
|
const imports = toImports(Object.entries(identifiers))
|
|
|
|
const globalThisSet = Object.keys(identifiers).map(name => `globalThis.${name} = ${name};`).join('\n')
|
|
|
|
return `${imports}\n\n${globalThisSet}\n\nexport default () => {};`
|
|
|
|
}
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
// Transform to inject imports in production mode
|
2021-08-24 07:49:03 +00:00
|
|
|
addVitePlugin(TransformPlugin.vite(identifiers))
|
|
|
|
addWebpackPlugin(TransformPlugin.webpack(identifiers))
|
2021-08-10 00:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add types
|
2021-08-11 20:28:38 +00:00
|
|
|
const resolved = {}
|
2021-10-05 20:47:19 +00:00
|
|
|
const r = (id: string) => {
|
|
|
|
if (resolved[id]) { return resolved[id] }
|
|
|
|
let path = resolveAlias(id, nuxt.options.alias)
|
|
|
|
if (isAbsolute(path)) {
|
|
|
|
path = relative(nuxt.options.buildDir, path)
|
|
|
|
}
|
|
|
|
// Remove file extension for benefit of TypeScript
|
|
|
|
path = path.replace(/\.[a-z]+$/, '')
|
|
|
|
resolved[id] = path
|
|
|
|
return path
|
|
|
|
}
|
2021-08-11 20:28:38 +00:00
|
|
|
|
2021-08-10 00:27:23 +00:00
|
|
|
addTemplate({
|
|
|
|
filename: 'global-imports.d.ts',
|
|
|
|
write: true,
|
|
|
|
getContents: () => `// Generated by global imports
|
|
|
|
declare global {
|
2021-08-11 20:28:38 +00:00
|
|
|
${Object.entries(identifiers).map(([api, moduleName]) => ` const ${api}: typeof import('${r(moduleName)}')['${api}']`).join('\n')}
|
2021-08-10 00:27:23 +00:00
|
|
|
}\nexport {}`
|
|
|
|
})
|
|
|
|
nuxt.hook('prepare:types', ({ references }) => {
|
|
|
|
references.push({ path: resolve(nuxt.options.buildDir, 'global-imports.d.ts') })
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
function toImports (identifiers: Identifiers) {
|
|
|
|
const map: Record<string, Set<string>> = {}
|
|
|
|
|
|
|
|
identifiers.forEach(([name, moduleName]) => {
|
|
|
|
if (!map[moduleName]) {
|
|
|
|
map[moduleName] = new Set()
|
|
|
|
}
|
|
|
|
map[moduleName].add(name)
|
|
|
|
})
|
|
|
|
|
|
|
|
return Object.entries(map)
|
|
|
|
.map(([name, imports]) => `import { ${Array.from(imports).join(', ')} } from '${name}';`)
|
|
|
|
.join('\n')
|
|
|
|
}
|