mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
feat: support auto import of plugins (#169)
This commit is contained in:
parent
498a234039
commit
bece3b85ab
@ -1,9 +1,12 @@
|
||||
import '@nuxt/nitro/dist/runtime/app/nitro.client'
|
||||
import logs from 'nuxt/app/plugins/logs.client.dev'
|
||||
import progress from 'nuxt/app/plugins/progress.client'
|
||||
<% const plugins = app.plugins.filter(p => p.mode === 'client').map(p => p.src) %>
|
||||
<%= nxt.importSources(plugins) %>
|
||||
|
||||
const plugins = [
|
||||
progress
|
||||
progress,
|
||||
<%= plugins.map(nxt.importName).join(',\n\t') %>
|
||||
]
|
||||
|
||||
if (process.dev) {
|
||||
|
@ -3,9 +3,13 @@ import router from 'nuxt/app/plugins/router'
|
||||
import vuex from 'nuxt/app/plugins/vuex'
|
||||
import legacy from 'nuxt/app/plugins/legacy'
|
||||
|
||||
<% const plugins = app.plugins.filter(p => p.mode === 'all').map(p => p.src) %>
|
||||
<%= nxt.importSources(plugins) %>
|
||||
|
||||
export default [
|
||||
head,
|
||||
router,
|
||||
vuex,
|
||||
legacy
|
||||
legacy,
|
||||
<%= plugins.map(nxt.importName).join(',\n\t') %>
|
||||
]
|
||||
|
@ -1,5 +1,8 @@
|
||||
import preload from 'nuxt/app/plugins/preload.server'
|
||||
<% const plugins = app.plugins.filter(p => p.mode === 'server').map(p => p.src) %>
|
||||
<%= nxt.importSources(plugins) %>
|
||||
|
||||
export default [
|
||||
preload
|
||||
<%= plugins.map(nxt.importName).join(',\n\t') %>
|
||||
]
|
||||
|
@ -1,2 +1,2 @@
|
||||
// TODO: Use webpack-virtual-modules
|
||||
export default <%= app.templates.routes || '[]' %>
|
||||
export default <%= nxt.serialize(app.routes.map(nxt.serializeRoute)) %>
|
||||
|
@ -81,6 +81,7 @@ export function createNuxt (options: CreateOptions) {
|
||||
}
|
||||
|
||||
export function applyPlugin (nuxt: Nuxt, plugin: Plugin) {
|
||||
if (typeof plugin !== 'function') { return }
|
||||
return callWithNuxt(nuxt, () => plugin(nuxt))
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ export default <Plugin> function router (nuxt) {
|
||||
routes
|
||||
})
|
||||
app.use(router)
|
||||
nuxt.provide('router', router)
|
||||
|
||||
const previousRoute = shallowRef(router.currentRoute.value)
|
||||
router.afterEach((_to, from) => {
|
||||
@ -35,7 +36,7 @@ export default <Plugin> function router (nuxt) {
|
||||
get: () => previousRoute.value
|
||||
})
|
||||
|
||||
nuxt.hooks.hook('app:created', async () => {
|
||||
nuxt.hook('app:created', async () => {
|
||||
if (process.server) {
|
||||
router.push(nuxt.ssrContext.url)
|
||||
}
|
||||
|
@ -2,12 +2,13 @@ import { resolve } from 'path'
|
||||
import defu from 'defu'
|
||||
import { Builder } from './builder'
|
||||
import { NuxtRoute, resolvePagesRoutes } from './pages'
|
||||
|
||||
import { NuxtPlugin, resolvePlugins } from './plugins'
|
||||
export interface NuxtApp {
|
||||
main: string
|
||||
routes: NuxtRoute[]
|
||||
dir: string
|
||||
extensions: string[]
|
||||
plugins: NuxtPlugin[]
|
||||
templates: Record<string, string>
|
||||
pages?: {
|
||||
dir: string
|
||||
@ -26,6 +27,7 @@ export async function createApp (
|
||||
dir: nuxt.options.srcDir,
|
||||
extensions: nuxt.options.extensions,
|
||||
routes: [],
|
||||
plugins: [],
|
||||
templates: {},
|
||||
pages: {
|
||||
dir: 'pages'
|
||||
@ -54,8 +56,6 @@ export async function createApp (
|
||||
children: []
|
||||
})
|
||||
}
|
||||
// TODO: Hook to extend routes
|
||||
app.templates.routes = serializeRoutes(app.routes)
|
||||
}
|
||||
|
||||
// Fallback app.main
|
||||
@ -65,24 +65,8 @@ export async function createApp (
|
||||
app.main = resolve(nuxt.options.appDir, 'app.tutorial.vue')
|
||||
}
|
||||
|
||||
// Resolve plugins/
|
||||
app.plugins = await resolvePlugins(builder, app)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
function serializeRoutes (routes: NuxtRoute[]) {
|
||||
return JSON.stringify(
|
||||
routes.map(formatRoute),
|
||||
null,
|
||||
2
|
||||
).replace(/"{(.+)}"/g, '$1')
|
||||
}
|
||||
|
||||
function formatRoute (route: NuxtRoute) {
|
||||
return {
|
||||
name: route.name,
|
||||
path: route.path,
|
||||
children: route.children.map(formatRoute),
|
||||
// TODO: avoid exposing to prod, using process.env.NODE_ENV ?
|
||||
__file: route.file,
|
||||
component: `{() => import('${route.file}' /* webpackChunkName: '${route.name}' */)}`
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ function watch (builder: Builder) {
|
||||
nuxtAppWatcher.watchAll(debounce(() => compileTemplates(builder.templates, nuxt.options.buildDir), 100))
|
||||
|
||||
// Watch user app
|
||||
// TODO: handle multiples app dirs
|
||||
const appPattern = `${builder.app.dir}/**/*.{${nuxt.options.extensions.join(',')}}`
|
||||
const appWatcher = createWatcher(appPattern, { ...options, cwd: builder.app.dir }, ignore)
|
||||
// appWatcher.debug('srcDir')
|
||||
@ -73,6 +74,8 @@ function watch (builder: Builder) {
|
||||
appWatcher.watch(/^(A|a)pp\.[a-z]{2,3}/, refreshTemplates, ['add', 'unlink'])
|
||||
// Watch for page changes
|
||||
appWatcher.watch(new RegExp(`^${nuxt.options.dir.pages}/`), refreshTemplates, ['add', 'unlink'])
|
||||
// Watch for plugins changes
|
||||
appWatcher.watch(/^plugins/, refreshTemplates, ['add', 'unlink'])
|
||||
|
||||
// Shared Watcher
|
||||
const watchHookDebounced = debounce((event, file) => builder.nuxt.callHook('builder:watch', event, file), 100)
|
||||
@ -84,9 +87,11 @@ export async function generate (builder: Builder) {
|
||||
const { nuxt } = builder
|
||||
|
||||
builder.app = await createApp(builder)
|
||||
// Todo: Call app:created hook
|
||||
|
||||
const templatesDir = join(builder.nuxt.options.appDir, '_templates')
|
||||
const appTemplates = await scanTemplates(templatesDir, templateData(builder))
|
||||
// Todo: Call app:templates hook
|
||||
|
||||
builder.templates = [...appTemplates]
|
||||
|
||||
|
32
packages/nuxt3/src/builder/nxt.ts
Normal file
32
packages/nuxt3/src/builder/nxt.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { basename, extname } from 'path'
|
||||
import hash from 'hash-sum'
|
||||
import { camelCase } from 'scule'
|
||||
import { NuxtRoute } from './pages'
|
||||
// NXT is a set of utils for serializing JavaScript data to JS code
|
||||
|
||||
export const serialize = data => JSON.stringify(data, null, 2).replace(/"{(.+)}"/g, '$1')
|
||||
|
||||
export const importName = (src: string) => `${camelCase(basename(src, extname(src))).replace(/[^a-zA-Z?\d\s:]/g, '')}_${hash(src)}`
|
||||
|
||||
export const importSources = (sources: string | string[], { lazy = false } = {}) => {
|
||||
if (!Array.isArray(sources)) {
|
||||
sources = [sources]
|
||||
}
|
||||
return sources.map((src) => {
|
||||
if (lazy) {
|
||||
return `const ${importName(src)} = () => import('${src}' /* webpackChunkName: '${src}' */)`
|
||||
}
|
||||
return `import ${importName(src)} from '${src}'`
|
||||
}).join('\n')
|
||||
}
|
||||
|
||||
export const serializeRoute = (route: NuxtRoute) => {
|
||||
return {
|
||||
name: route.name,
|
||||
path: route.path,
|
||||
children: route.children.map(serializeRoute),
|
||||
// TODO: avoid exposing to prod, using process.env.NODE_ENV ?
|
||||
__file: route.file,
|
||||
component: `{() => import('${route.file}' /* webpackChunkName: '${route.name}' */)}`
|
||||
}
|
||||
}
|
26
packages/nuxt3/src/builder/plugins.ts
Normal file
26
packages/nuxt3/src/builder/plugins.ts
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
import { NuxtApp } from './app'
|
||||
import { Builder } from './builder'
|
||||
import { resolveFiles } from './utils'
|
||||
|
||||
export interface NuxtPlugin {
|
||||
src: string
|
||||
mode: 'server' | 'client' | 'all'
|
||||
}
|
||||
|
||||
const MODES_REGEX = /\.(server|client)(\.\w+)*$/
|
||||
const getPluginMode = (src) => {
|
||||
const [, mode = 'all'] = src.match(MODES_REGEX) || []
|
||||
|
||||
return mode
|
||||
}
|
||||
|
||||
export function resolvePlugins (builder: Builder, app: NuxtApp) {
|
||||
return resolveFiles(builder, 'plugins/**/*.{js,ts}', app.dir)
|
||||
.then(plugins => plugins.map((src) => {
|
||||
return {
|
||||
src,
|
||||
mode: getPluginMode(src)
|
||||
}
|
||||
}))
|
||||
}
|
@ -2,6 +2,7 @@ import { join, relative, dirname } from 'path'
|
||||
import fsExtra from 'fs-extra'
|
||||
import globby from 'globby'
|
||||
import lodashTemplate from 'lodash/template'
|
||||
import * as nxt from './nxt'
|
||||
|
||||
export interface NuxtTemplate {
|
||||
src: string // Absolute path to source file
|
||||
@ -13,7 +14,8 @@ export function templateData (builder) {
|
||||
return {
|
||||
globals: builder.globals,
|
||||
app: builder.app,
|
||||
nuxtOptions: builder.nuxt.options
|
||||
nuxtOptions: builder.nuxt.options,
|
||||
nxt
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user