diff --git a/packages/nuxt/src/auto-imports/module.ts b/packages/nuxt/src/auto-imports/module.ts index 97a996567ca..308d5445f12 100644 --- a/packages/nuxt/src/auto-imports/module.ts +++ b/packages/nuxt/src/auto-imports/module.ts @@ -74,8 +74,8 @@ export default defineNuxtModule>({ }) } else { // Transform to inject imports in production mode - addVitePlugin(TransformPlugin.vite({ ctx, options })) - addWebpackPlugin(TransformPlugin.webpack({ ctx, options })) + addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: nuxt.options.sourcemap })) + addWebpackPlugin(TransformPlugin.webpack({ ctx, options, sourcemap: nuxt.options.sourcemap })) } const regenerateAutoImports = async () => { diff --git a/packages/nuxt/src/auto-imports/transform.ts b/packages/nuxt/src/auto-imports/transform.ts index 1a0619e6c00..370bf6e2394 100644 --- a/packages/nuxt/src/auto-imports/transform.ts +++ b/packages/nuxt/src/auto-imports/transform.ts @@ -4,7 +4,7 @@ import { parseQuery, parseURL } from 'ufo' import { Unimport } from 'unimport' import { AutoImportsOptions } from '@nuxt/schema' -export const TransformPlugin = createUnplugin(({ ctx, options }: {ctx: Unimport, options: Partial }) => { +export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx: Unimport, options: Partial, sourcemap?: boolean }) => { return { name: 'nuxt:auto-imports-transform', enforce: 'post', @@ -39,7 +39,7 @@ export const TransformPlugin = createUnplugin(({ ctx, options }: {ctx: Unimport, } return { code, - map: s.generateMap({ source: id, includeContent: true }) + map: sourcemap && s.generateMap({ source: id, includeContent: true }) } } } diff --git a/packages/nuxt/src/components/loader.ts b/packages/nuxt/src/components/loader.ts index b490a0d2141..7d1adf4f218 100644 --- a/packages/nuxt/src/components/loader.ts +++ b/packages/nuxt/src/components/loader.ts @@ -9,6 +9,7 @@ import { pascalCase } from 'scule' interface LoaderOptions { getComponents(): Component[] mode: 'server' | 'client' + sourcemap?: boolean } export const loaderPlugin = createUnplugin((options: LoaderOptions) => ({ @@ -22,7 +23,46 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => ({ return pathname.endsWith('.vue') && (query.type === 'template' || !!query.macro || !search) }, transform (code, id) { - return transform(code, id, options.getComponents(), options.mode) + const components = options.getComponents() + + let num = 0 + const imports = new Set() + const map = new Map() + const s = new MagicString(code) + + // replace `_resolveComponent("...")` to direct import + s.replace(/(?<=[ (])_?resolveComponent\(["'](lazy-|Lazy)?([^'"]*?)["']\)/g, (full, lazy, name) => { + const component = findComponent(components, name, options.mode) + if (component) { + const identifier = map.get(component) || `__nuxt_component_${num++}` + map.set(component, identifier) + const isClientOnly = component.mode === 'client' + if (isClientOnly) { + imports.add(genImport('#app/components/client-only', [{ name: 'createClientOnly' }])) + } + if (lazy) { + imports.add(genImport('vue', [{ name: 'defineAsyncComponent', as: '__defineAsyncComponent' }])) + imports.add(`const ${identifier}_lazy = __defineAsyncComponent(${genDynamicImport(component.filePath)})`) + return isClientOnly ? `createClientOnly(${identifier}_lazy)` : `${identifier}_lazy` + } else { + imports.add(genImport(component.filePath, [{ name: component.export, as: identifier }])) + return isClientOnly ? `createClientOnly(${identifier})` : identifier + } + } + // no matched + return full + }) + + if (imports.size) { + s.prepend([...imports, ''].join('\n')) + } + + if (s.hasChanged()) { + return { + code: s.toString(), + map: options.sourcemap && s.generateMap({ source: id, includeContent: true }) + } + } } })) @@ -34,44 +74,3 @@ function findComponent (components: Component[], name: string, mode: LoaderOptio } return component } - -function transform (code: string, id: string, components: Component[], mode: LoaderOptions['mode']) { - let num = 0 - const imports = new Set() - const map = new Map() - const s = new MagicString(code) - - // replace `_resolveComponent("...")` to direct import - s.replace(/(?<=[ (])_?resolveComponent\(["'](lazy-|Lazy)?([^'"]*?)["']\)/g, (full, lazy, name) => { - const component = findComponent(components, name, mode) - if (component) { - const identifier = map.get(component) || `__nuxt_component_${num++}` - map.set(component, identifier) - const isClientOnly = component.mode === 'client' - if (isClientOnly) { - imports.add(genImport('#app/components/client-only', [{ name: 'createClientOnly' }])) - } - if (lazy) { - imports.add(genImport('vue', [{ name: 'defineAsyncComponent', as: '__defineAsyncComponent' }])) - imports.add(`const ${identifier}_lazy = __defineAsyncComponent(${genDynamicImport(component.filePath)})`) - return isClientOnly ? `createClientOnly(${identifier}_lazy)` : `${identifier}_lazy` - } else { - imports.add(genImport(component.filePath, [{ name: component.export, as: identifier }])) - return isClientOnly ? `createClientOnly(${identifier})` : identifier - } - } - // no matched - return full - }) - - if (imports.size) { - s.prepend([...imports, ''].join('\n')) - } - - if (s.hasChanged()) { - return { - code: s.toString(), - map: s.generateMap({ source: id, includeContent: true }) - } - } -} diff --git a/packages/nuxt/src/components/module.ts b/packages/nuxt/src/components/module.ts index c546a1b71a5..e592d37e7ef 100644 --- a/packages/nuxt/src/components/module.ts +++ b/packages/nuxt/src/components/module.ts @@ -132,6 +132,7 @@ export default defineNuxtModule({ nuxt.hook('vite:extendConfig', (config, { isClient }) => { config.plugins = config.plugins || [] config.plugins.push(loaderPlugin.vite({ + sourcemap: nuxt.options.sourcemap, getComponents, mode: isClient ? 'client' : 'server' })) @@ -140,6 +141,7 @@ export default defineNuxtModule({ configs.forEach((config) => { config.plugins = config.plugins || [] config.plugins.push(loaderPlugin.webpack({ + sourcemap: nuxt.options.sourcemap, getComponents, mode: config.name === 'client' ? 'client' : 'server' })) diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index 25b037ec6c2..77f5ede078d 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -55,6 +55,7 @@ export async function initNitro (nuxt: Nuxt) { .concat(nuxt.options._generate ? ['/', ...nuxt.options.generate.routes] : []) .concat(nuxt.options.ssr === false ? ['/', '/200', '/404'] : []) }, + sourcemap: nuxt.options.sourcemap, externals: { inline: [ ...(nuxt.options.dev ? [] : ['vue', '@vue/', '@nuxt/', nuxt.options.buildDir]), diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 42d7c33bd9a..205336a74ca 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -63,8 +63,8 @@ async function initNuxt (nuxt: Nuxt) { addWebpackPlugin(ImportProtectionPlugin.webpack(config)) // Add unctx transform - addVitePlugin(UnctxTransformPlugin(nuxt).vite()) - addWebpackPlugin(UnctxTransformPlugin(nuxt).webpack()) + addVitePlugin(UnctxTransformPlugin(nuxt).vite({ sourcemap: nuxt.options.sourcemap })) + addWebpackPlugin(UnctxTransformPlugin(nuxt).webpack({ sourcemap: nuxt.options.sourcemap })) // Init user modules await nuxt.callHook('modules:before', { nuxt } as ModuleContainer) diff --git a/packages/nuxt/src/core/plugins/unctx.ts b/packages/nuxt/src/core/plugins/unctx.ts index 036d21c6771..82d0e3b2976 100644 --- a/packages/nuxt/src/core/plugins/unctx.ts +++ b/packages/nuxt/src/core/plugins/unctx.ts @@ -12,7 +12,7 @@ export const UnctxTransformPlugin = (nuxt: Nuxt) => { nuxt.hook('app:resolve', (_app) => { app = _app }) nuxt.hook('pages:middleware:extend', (_middlewares) => { middleware = _middlewares }) - return createUnplugin(() => ({ + return createUnplugin((options: { sourcemap?: boolean } = {}) => ({ name: 'unctx:transfrom', enforce: 'post', transformInclude (id) { @@ -23,7 +23,7 @@ export const UnctxTransformPlugin = (nuxt: Nuxt) => { if (result) { return { code: result.code, - map: result.magicString.generateMap({ source: id, includeContent: true }) + map: options.sourcemap && result.magicString.generateMap({ source: id, includeContent: true }) } } } diff --git a/packages/nuxt/src/pages/macros.ts b/packages/nuxt/src/pages/macros.ts index e171d7c4c22..93b337c08be 100644 --- a/packages/nuxt/src/pages/macros.ts +++ b/packages/nuxt/src/pages/macros.ts @@ -7,6 +7,7 @@ import MagicString from 'magic-string' export interface TransformMacroPluginOptions { macros: Record dev?: boolean + sourcemap?: boolean } export const TransformMacroPlugin = createUnplugin((options: TransformMacroPluginOptions) => { @@ -24,7 +25,7 @@ export const TransformMacroPlugin = createUnplugin((options: TransformMacroPlugi function result () { if (s.hasChanged()) { - return { code: s.toString(), map: s.generateMap({ source: id, includeContent: true }) } + return { code: s.toString(), map: options.sourcemap && s.generateMap({ source: id, includeContent: true }) } } } diff --git a/packages/nuxt/src/pages/module.ts b/packages/nuxt/src/pages/module.ts index e83b6ec4a05..c5c9e38102d 100644 --- a/packages/nuxt/src/pages/module.ts +++ b/packages/nuxt/src/pages/module.ts @@ -57,6 +57,7 @@ export default defineNuxtModule({ // Extract macros from pages const macroOptions: TransformMacroPluginOptions = { dev: nuxt.options.dev, + sourcemap: nuxt.options.sourcemap, macros: { definePageMeta: 'meta' } diff --git a/packages/schema/src/config/build.ts b/packages/schema/src/config/build.ts index 239be9efc9c..e8a8ee612d6 100644 --- a/packages/schema/src/config/build.ts +++ b/packages/schema/src/config/build.ts @@ -22,6 +22,12 @@ export default { return map[val] || (get('vite') === false ? map.webpack : map.vite) }, }, + /** + * Whether to generate sourcemaps. + * + * @version 3 + */ + sourcemap: true, /** * Shared build configuration. * @version 2 @@ -132,7 +138,7 @@ export default { * @version 2 */ cssSourceMap: { - $resolve: (val, get) => val ?? get('dev') + $resolve: (val, get) => val ?? get('sourcemap') ?? get('dev') }, /** @@ -242,8 +248,8 @@ export default { ] for (const name of styleLoaders) { const loader = val[name] - if (loader && loader.sourceMap === undefined) { - loader.sourceMap = Boolean(get('build.cssSourceMap')) + if (loader && loader.sourcemap === undefined) { + loader.sourcemap = Boolean(get('build.cssSourceMap')) } } return val @@ -315,7 +321,7 @@ export default { * * @see [terser-webpack-plugin documentation](https://github.com/webpack-contrib/terser-webpack-plugin) * - * @note Enabling sourceMap will leave `//# sourceMappingURL` linking comment at + * @note Enabling sourcemap will leave `//# sourcemappingURL` linking comment at * the end of each output file if webpack `config.devtool` is set to `source-map`. * @version 2 */ @@ -493,7 +499,7 @@ export default { return postcssOptions } }, - sourceMap: undefined, + sourcemap: undefined, implementation: undefined, order: '' }, diff --git a/packages/vite/src/plugins/dynamic-base.ts b/packages/vite/src/plugins/dynamic-base.ts index 17909f625ef..616780cc6c6 100644 --- a/packages/vite/src/plugins/dynamic-base.ts +++ b/packages/vite/src/plugins/dynamic-base.ts @@ -5,6 +5,7 @@ import MagicString from 'magic-string' interface DynamicBasePluginOptions { globalPublicPath?: string + sourcemap?: boolean } export const RelativeAssetPlugin = function (): Plugin { @@ -97,7 +98,7 @@ export const DynamicBasePlugin = createUnplugin(function (options: DynamicBasePl if (s.hasChanged()) { return { code: s.toString(), - map: s.generateMap({ source: id, includeContent: true }) + map: options.sourcemap && s.generateMap({ source: id, includeContent: true }) } } } diff --git a/packages/vite/src/vite.ts b/packages/vite/src/vite.ts index 5671c26a32b..552039c76de 100644 --- a/packages/vite/src/vite.ts +++ b/packages/vite/src/vite.ts @@ -65,7 +65,7 @@ export async function bundle (nuxt: Nuxt) { }, plugins: [ virtual(nuxt.vfs), - DynamicBasePlugin.vite() + DynamicBasePlugin.vite({ sourcemap: nuxt.options.sourcemap }) ], vue: { reactivityTransform: nuxt.options.experimental.reactivityTransform diff --git a/packages/webpack/src/webpack.ts b/packages/webpack/src/webpack.ts index 21956c290de..ab04e37aa6f 100644 --- a/packages/webpack/src/webpack.ts +++ b/packages/webpack/src/webpack.ts @@ -34,6 +34,7 @@ export async function bundle (nuxt: Nuxt) { // Configure compilers const compilers = webpackConfigs.map((config) => { config.plugins.push(DynamicBasePlugin.webpack({ + sourcemap: nuxt.options.sourcemap, globalPublicPath: '__webpack_public_path__' }))