From f5ab7eb4946b52c13109fa504c2f9b86b42c5fb9 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 19 Jun 2024 13:56:54 +0100 Subject: [PATCH] refactor(kit,nuxt)!: drop nuxt 2 + ejs template compile support (#27706) --- packages/kit/build.config.ts | 1 - packages/kit/package.json | 3 -- packages/kit/src/compatibility.ts | 17 ------ packages/kit/src/index.ts | 1 - packages/kit/src/internal/template.ts | 47 ---------------- packages/kit/src/layout.ts | 16 ------ packages/kit/src/module/define.ts | 62 ++-------------------- packages/kit/src/module/install.ts | 8 +-- packages/kit/src/pages.ts | 9 +--- packages/nuxt/src/core/app.ts | 8 ++- packages/schema/src/config/experimental.ts | 27 ---------- packages/ui-templates/lib/dev.ts | 22 +++++--- packages/ui-templates/package.json | 2 - pnpm-lock.yaml | 15 ------ 14 files changed, 24 insertions(+), 214 deletions(-) delete mode 100644 packages/kit/src/internal/template.ts diff --git a/packages/kit/build.config.ts b/packages/kit/build.config.ts index 10db295927..acd2539172 100644 --- a/packages/kit/build.config.ts +++ b/packages/kit/build.config.ts @@ -12,5 +12,4 @@ export default defineBuildConfig({ 'vite', 'h3', ], - failOnWarn: false, }) diff --git a/packages/kit/package.json b/packages/kit/package.json index 2253b46346..2a5934ef29 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -36,7 +36,6 @@ "ignore": "^5.3.1", "jiti": "^1.21.6", "klona": "^2.0.6", - "knitwork": "^1.1.0", "mlly": "^1.7.1", "pathe": "^1.1.2", "pkg-types": "^1.1.1", @@ -49,9 +48,7 @@ }, "devDependencies": { "@types/hash-sum": "1.0.2", - "@types/lodash-es": "4.17.12", "@types/semver": "7.5.8", - "lodash-es": "4.17.21", "nitropack": "2.9.6", "unbuild": "latest", "vite": "5.3.1", diff --git a/packages/kit/src/compatibility.ts b/packages/kit/src/compatibility.ts index b2720f05c9..64f39b9549 100644 --- a/packages/kit/src/compatibility.ts +++ b/packages/kit/src/compatibility.ts @@ -29,23 +29,6 @@ export async function checkNuxtCompatibility (constraints: NuxtCompatibility, nu } } - // Bridge compatibility check - if (isNuxt2(nuxt)) { - const bridgeRequirement = constraints.bridge - const hasBridge = !!(nuxt.options as any).bridge - if (bridgeRequirement === true && !hasBridge) { - issues.push({ - name: 'bridge', - message: 'Nuxt bridge is required', - }) - } else if (bridgeRequirement === false && hasBridge) { - issues.push({ - name: 'bridge', - message: 'Nuxt bridge is not supported', - }) - } - } - // Builder compatibility check if (constraints.builder && typeof nuxt.options.builder === 'string') { const currentBuilder = builderMap[nuxt.options.builder] || nuxt.options.builder diff --git a/packages/kit/src/index.ts b/packages/kit/src/index.ts index 405de8606a..1f70f0a484 100644 --- a/packages/kit/src/index.ts +++ b/packages/kit/src/index.ts @@ -35,4 +35,3 @@ export { } from './internal/cjs' export type { ResolveModuleOptions, RequireModuleOptions } from './internal/cjs' export { tryResolveModule } from './internal/esm' -export * from './internal/template' diff --git a/packages/kit/src/internal/template.ts b/packages/kit/src/internal/template.ts deleted file mode 100644 index 343393e5ec..0000000000 --- a/packages/kit/src/internal/template.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { promises as fsp } from 'node:fs' -// TODO: swap out when https://github.com/lodash/lodash/pull/5649 is merged -import { template as lodashTemplate } from 'lodash-es' -import { genDynamicImport, genImport, genSafeVariableName } from 'knitwork' - -import type { NuxtTemplate } from '@nuxt/schema' -import { logger } from '../logger' -import { toArray } from '../utils' - -/** @deprecated */ -// TODO: Remove support for compiling ejs templates in v4 -export async function compileTemplate (template: NuxtTemplate, ctx: any) { - const data = { ...ctx, options: template.options } - if (template.src) { - try { - const srcContents = await fsp.readFile(template.src, 'utf-8') - return lodashTemplate(srcContents, {})(data) - } catch (err) { - logger.error('Error compiling template: ', template) - throw err - } - } - if (template.getContents) { - return template.getContents(data) - } - throw new Error('Invalid template: ' + JSON.stringify(template)) -} - -/** @deprecated */ -const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"\{(.+)\}"(?=,?$)/gm, r => JSON.parse(r).replace(/^\{(.*)\}$/, '$1')) - -/** @deprecated */ -const importSources = (sources: string | string[], { lazy = false } = {}) => { - return toArray(sources).map((src) => { - const safeVariableName = genSafeVariableName(src) - if (lazy) { - return `const ${safeVariableName} = ${genDynamicImport(src, { comment: `webpackChunkName: ${JSON.stringify(src)}` })}` - } - return genImport(src, safeVariableName) - }).join('\n') -} - -/** @deprecated */ -const importName = genSafeVariableName - -/** @deprecated */ -export const templateUtils = { serialize, importName, importSources } diff --git a/packages/kit/src/layout.ts b/packages/kit/src/layout.ts index bf86c443c9..d1b2656f71 100644 --- a/packages/kit/src/layout.ts +++ b/packages/kit/src/layout.ts @@ -1,7 +1,6 @@ import type { NuxtTemplate } from '@nuxt/schema' import { join, parse, relative } from 'pathe' import { kebabCase } from 'scule' -import { isNuxt2 } from './compatibility' import { useNuxt } from './context' import { logger } from './logger' import { addTemplate } from './template' @@ -11,21 +10,6 @@ export function addLayout (this: any, template: NuxtTemplate | string, name?: st const { filename, src } = addTemplate(template) const layoutName = kebabCase(name || parse(filename).name).replace(/["']/g, '') - if (isNuxt2(nuxt)) { - // Nuxt 2 adds layouts in options - const layout = (nuxt.options as any).layouts[layoutName] - if (layout) { - return logger.warn( - `Not overriding \`${layoutName}\` (provided by \`${layout}\`) with \`${src || filename}\`.`, - ) - } - (nuxt.options as any).layouts[layoutName] = `./${filename}` - if (name === 'error') { - this.addErrorLayout(filename) - } - return - } - // Nuxt 3 adds layouts on app nuxt.hook('app:templates', (app) => { if (layoutName in app.layouts) { diff --git a/packages/kit/src/module/define.ts b/packages/kit/src/module/define.ts index ff2a56d2d4..e0986ef59a 100644 --- a/packages/kit/src/module/define.ts +++ b/packages/kit/src/module/define.ts @@ -1,13 +1,10 @@ -import { promises as fsp } from 'node:fs' import { performance } from 'node:perf_hooks' import { defu } from 'defu' import { applyDefaults } from 'untyped' -import { dirname } from 'pathe' -import type { ModuleDefinition, ModuleOptions, ModuleSetupReturn, Nuxt, NuxtModule, NuxtOptions, ResolvedNuxtTemplate } from '@nuxt/schema' +import type { ModuleDefinition, ModuleOptions, ModuleSetupReturn, Nuxt, NuxtModule, NuxtOptions } from '@nuxt/schema' import { logger } from '../logger' -import { nuxtCtx, tryUseNuxt, useNuxt } from '../context' -import { checkNuxtCompatibility, isNuxt2 } from '../compatibility' -import { compileTemplate, templateUtils } from '../internal/template' +import { tryUseNuxt, useNuxt } from '../context' +import { checkNuxtCompatibility } from '../compatibility' /** * Define a Nuxt module, automatically merging defaults with user provided options, installing @@ -58,9 +55,6 @@ export function defineNuxtModule (definition: Mo } } - // Prepare - nuxt2Shims(nuxt) - // Resolve module and options const _options = await getOptions(inlineOptions, nuxt) @@ -100,53 +94,3 @@ export function defineNuxtModule (definition: Mo return normalizedModule as NuxtModule } - -// -- Nuxt 2 compatibility shims -- -const NUXT2_SHIMS_KEY = '__nuxt2_shims_key__' -function nuxt2Shims (nuxt: Nuxt) { - // Avoid duplicate install and only apply to Nuxt2 - if (!isNuxt2(nuxt) || nuxt[NUXT2_SHIMS_KEY as keyof Nuxt]) { return } - nuxt[NUXT2_SHIMS_KEY as keyof Nuxt] = true - - // Allow using nuxt.hooks - // @ts-expect-error Nuxt 2 extends hookable - nuxt.hooks = nuxt - - // Allow using useNuxt() - if (!nuxtCtx.tryUse()) { - nuxtCtx.set(nuxt) - nuxt.hook('close', () => nuxtCtx.unset()) - } - - // Support virtual templates with getContents() by writing them to .nuxt directory - let virtualTemplates: ResolvedNuxtTemplate[] - // @ts-expect-error Nuxt 2 hook - nuxt.hook('builder:prepared', (_builder, buildOptions) => { - virtualTemplates = buildOptions.templates.filter((t: any) => t.getContents) - for (const template of virtualTemplates) { - buildOptions.templates.splice(buildOptions.templates.indexOf(template), 1) - } - }) - // @ts-expect-error Nuxt 2 hook - nuxt.hook('build:templates', async (templates) => { - const context = { - nuxt, - utils: templateUtils, - app: { - dir: nuxt.options.srcDir, - extensions: nuxt.options.extensions, - plugins: nuxt.options.plugins, - templates: [ - ...templates.templatesFiles, - ...virtualTemplates, - ], - templateVars: templates.templateVars, - }, - } - for await (const template of virtualTemplates) { - const contents = await compileTemplate({ ...template, src: '' }, context) - await fsp.mkdir(dirname(template.dst), { recursive: true }) - await fsp.writeFile(template.dst, contents) - } - }) -} diff --git a/packages/kit/src/module/install.ts b/packages/kit/src/module/install.ts index beecd62aef..6d04cef352 100644 --- a/packages/kit/src/module/install.ts +++ b/packages/kit/src/module/install.ts @@ -2,7 +2,6 @@ import { existsSync, promises as fsp, lstatSync } from 'node:fs' import type { ModuleMeta, Nuxt, NuxtConfig, NuxtModule } from '@nuxt/schema' import { dirname, isAbsolute, join, resolve } from 'pathe' import { defu } from 'defu' -import { isNuxt2 } from '../compatibility' import { useNuxt } from '../context' import { requireModule } from '../internal/cjs' import { importModule } from '../internal/esm' @@ -27,12 +26,7 @@ export async function installModule< } // Call module - const res = ( - isNuxt2() - // @ts-expect-error Nuxt 2 `moduleContainer` is not typed - ? await nuxtModule.call(nuxt.moduleContainer, inlineOptions, nuxt) - : await nuxtModule(inlineOptions, nuxt) - ) ?? {} + const res = await nuxtModule(inlineOptions, nuxt) ?? {} if (res === false /* setup aborted */) { return } diff --git a/packages/kit/src/pages.ts b/packages/kit/src/pages.ts index 04c7592a55..401bf2881b 100644 --- a/packages/kit/src/pages.ts +++ b/packages/kit/src/pages.ts @@ -2,18 +2,11 @@ import type { NuxtHooks, NuxtMiddleware } from '@nuxt/schema' import type { NitroRouteConfig } from 'nitropack' import { defu } from 'defu' import { useNuxt } from './context' -import { isNuxt2 } from './compatibility' import { logger } from './logger' import { toArray } from './utils' export function extendPages (cb: NuxtHooks['pages:extend']) { - const nuxt = useNuxt() - if (isNuxt2(nuxt)) { - // @ts-expect-error TODO: Nuxt 2 hook - nuxt.hook('build:extendRoutes', cb) - } else { - nuxt.hook('pages:extend', cb) - } + useNuxt().hook('pages:extend', cb) } export interface ExtendRouteRulesOptions { diff --git a/packages/nuxt/src/core/app.ts b/packages/nuxt/src/core/app.ts index 4bc7da1e91..8e0e7bc2a0 100644 --- a/packages/nuxt/src/core/app.ts +++ b/packages/nuxt/src/core/app.ts @@ -1,7 +1,7 @@ import { promises as fsp, mkdirSync, writeFileSync } from 'node:fs' import { dirname, join, relative, resolve } from 'pathe' import { defu } from 'defu' -import { compileTemplate as _compileTemplate, findPath, logger, normalizePlugin, normalizeTemplate, resolveAlias, resolveFiles, resolvePath, templateUtils } from '@nuxt/kit' +import { findPath, logger, normalizePlugin, normalizeTemplate, resolveAlias, resolveFiles, resolvePath } from '@nuxt/kit' import type { Nuxt, NuxtApp, NuxtPlugin, NuxtTemplate, ResolvedNuxtTemplate } from 'nuxt/schema' import * as defaultTemplates from './templates' @@ -53,9 +53,7 @@ export async function generateApp (nuxt: Nuxt, app: NuxtApp, options: { filter?: } // Compile templates into vfs - // TODO: remove utils in v4 - const templateContext = { utils: templateUtils, nuxt, app } - const compileTemplate = nuxt.options.experimental.compileTemplate ? _compileTemplate : futureCompileTemplate + const templateContext = { nuxt, app } const writes: Array<() => void> = [] const changedTemplates: Array> = [] @@ -113,7 +111,7 @@ export async function generateApp (nuxt: Nuxt, app: NuxtApp, options: { filter?: } /** @internal */ -async function futureCompileTemplate (template: NuxtTemplate, ctx: { nuxt: Nuxt, app: NuxtApp, utils?: unknown }) { +async function compileTemplate (template: NuxtTemplate, ctx: { nuxt: Nuxt, app: NuxtApp, utils?: unknown }) { delete ctx.utils if (template.src) { diff --git a/packages/schema/src/config/experimental.ts b/packages/schema/src/config/experimental.ts index b80f0beca1..4ce4ed2c52 100644 --- a/packages/schema/src/config/experimental.ts +++ b/packages/schema/src/config/experimental.ts @@ -26,8 +26,6 @@ export default defineUntypedSchema({ * app: 'app' * }, * experimental: { - * compileTemplate: true, - * templateUtils: true, * relativeWatchPaths: true, * resetAsyncDataToUndefined: true, * defaults: { @@ -467,31 +465,6 @@ export default defineUntypedSchema({ */ clientNodeCompat: false, - /** - * Whether to use `lodash.template` to compile Nuxt templates. - * - * This flag will be removed with the release of v4 and exists only for - * advance testing within Nuxt v3.12+ or in [the nightly release channel](/docs/guide/going-further/nightly-release-channel). - */ - compileTemplate: { - async $resolve (val, get) { - return val ?? ((await get('future') as Record).compatibilityVersion !== 4) - }, - }, - - /** - * Whether to provide a legacy `templateUtils` object (with `serialize`, - * `importName` and `importSources`) when compiling Nuxt templates. - * - * This flag will be removed with the release of v4 and exists only for - * advance testing within Nuxt v3.12+ or in [the nightly release channel](/docs/guide/going-further/nightly-release-channel). - */ - templateUtils: { - async $resolve (val, get) { - return val ?? ((await get('future') as Record).compatibilityVersion !== 4) - }, - }, - /** * Whether to provide relative paths in the `builder:watch` hook. * diff --git a/packages/ui-templates/lib/dev.ts b/packages/ui-templates/lib/dev.ts index 75e431f66c..12e7a3fcfd 100644 --- a/packages/ui-templates/lib/dev.ts +++ b/packages/ui-templates/lib/dev.ts @@ -1,8 +1,8 @@ +import { runInNewContext } from 'node:vm' import { join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { promises as fsp } from 'node:fs' import type { Plugin } from 'vite' -import { template } from 'lodash-es' import genericMessages from '../templates/messages.json' const templatesRoot = fileURLToPath(new URL('..', import.meta.url)) @@ -15,6 +15,8 @@ export const DevRenderingPlugin = () => { async transformIndexHtml (html: string, context) { const page = context.originalUrl || '/' + if (page.endsWith('.png')) { return } + if (page === '/') { const templateNames = await fsp.readdir(r('templates')) const serializedData = JSON.stringify({ templateNames }) @@ -25,11 +27,19 @@ export const DevRenderingPlugin = () => { const messages = JSON.parse(await fsp.readFile(r(page, 'messages.json'), 'utf-8')) - return template(contents, { - interpolate: /\{\{\{?([\s\S]+?)\}?\}\}/g, - })({ - messages: { ...genericMessages, ...messages }, - }) + const chunks = contents.split(/\{{2,3}[^{}]+\}{2,3}/g) + let templateString = chunks.shift() + for (const expression of contents.matchAll(/\{{2,3}([^{}]+)\}{2,3}/g)) { + const value = runInNewContext(expression[1].trim(), { + messages: { ...genericMessages, ...messages }, + }) + templateString += `${value}${chunks.shift()}` + } + if (chunks.length > 0) { + templateString += chunks.join('') + } + + return templateString }, } } diff --git a/packages/ui-templates/package.json b/packages/ui-templates/package.json index b47bc45d9b..2721e46670 100644 --- a/packages/ui-templates/package.json +++ b/packages/ui-templates/package.json @@ -20,7 +20,6 @@ }, "devDependencies": { "@types/html-minifier": "4.0.5", - "@types/lodash-es": "4.17.12", "@unocss/reset": "0.61.0", "critters": "0.0.22", "execa": "9.2.0", @@ -28,7 +27,6 @@ "html-minifier": "4.0.0", "jiti": "1.21.6", "knitwork": "1.1.0", - "lodash-es": "4.17.21", "pathe": "1.1.2", "prettier": "3.3.2", "scule": "1.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 23227d901b..91848bf01e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -191,9 +191,6 @@ importers: klona: specifier: ^2.0.6 version: 2.0.6 - knitwork: - specifier: ^1.1.0 - version: 1.1.0 mlly: specifier: ^1.7.1 version: 1.7.1 @@ -225,15 +222,9 @@ importers: '@types/hash-sum': specifier: 1.0.2 version: 1.0.2 - '@types/lodash-es': - specifier: 4.17.12 - version: 4.17.12 '@types/semver': specifier: 7.5.8 version: 7.5.8 - lodash-es: - specifier: 4.17.21 - version: 4.17.21 nitropack: specifier: 2.9.6 version: 2.9.6(encoding@0.1.13)(magicast@0.3.4) @@ -584,9 +575,6 @@ importers: '@types/html-minifier': specifier: 4.0.5 version: 4.0.5 - '@types/lodash-es': - specifier: 4.17.12 - version: 4.17.12 '@unocss/reset': specifier: 0.61.0 version: 0.61.0 @@ -608,9 +596,6 @@ importers: knitwork: specifier: 1.1.0 version: 1.1.0 - lodash-es: - specifier: 4.17.21 - version: 4.17.21 pathe: specifier: 1.1.2 version: 1.1.2