diff --git a/packages/nuxt/src/components/module.ts b/packages/nuxt/src/components/module.ts index 4f71dc19b2a..891617d6543 100644 --- a/packages/nuxt/src/components/module.ts +++ b/packages/nuxt/src/components/module.ts @@ -9,7 +9,7 @@ import { TreeShakeTemplatePlugin } from './tree-shake' const isPureObjectOrString = (val: any) => (!Array.isArray(val) && typeof val === 'object') || typeof val === 'string' const isDirectory = (p: string) => { try { return statSync(p).isDirectory() } catch (_e) { return false } } -function compareDirByPathLength ({ path: pathA }: { path: string}, { path: pathB }: { path: string}) { +function compareDirByPathLength ({ path: pathA }: { path: string }, { path: pathB }: { path: string }) { return pathB.split(/[\\/]/).filter(Boolean).length - pathA.split(/[\\/]/).filter(Boolean).length } @@ -165,31 +165,34 @@ export default defineNuxtModule({ } }) - nuxt.hook('vite:extendConfig', (config, { isClient }) => { + nuxt.hook('vite:extendConfig', (config, { isClient, isServer }) => { + const mode = isClient ? 'client' : 'server' + config.plugins = config.plugins || [] config.plugins.push(loaderPlugin.vite({ - sourcemap: nuxt.options.sourcemap, + sourcemap: nuxt.options.sourcemap[mode], getComponents, - mode: isClient ? 'client' : 'server' + mode })) - if (nuxt.options.experimental.treeshakeClientOnly) { + if (nuxt.options.experimental.treeshakeClientOnly && isServer) { config.plugins.push(TreeShakeTemplatePlugin.vite({ - sourcemap: nuxt.options.sourcemap, + sourcemap: nuxt.options.sourcemap[mode], getComponents })) } }) nuxt.hook('webpack:config', (configs) => { configs.forEach((config) => { + const mode = config.name === 'client' ? 'client' : 'server' config.plugins = config.plugins || [] config.plugins.push(loaderPlugin.webpack({ - sourcemap: nuxt.options.sourcemap, + sourcemap: nuxt.options.sourcemap[mode], getComponents, - mode: config.name === 'client' ? 'client' : 'server' + mode })) - if (nuxt.options.experimental.treeshakeClientOnly) { + if (nuxt.options.experimental.treeshakeClientOnly && mode === 'server') { config.plugins.push(TreeShakeTemplatePlugin.webpack({ - sourcemap: nuxt.options.sourcemap, + sourcemap: nuxt.options.sourcemap[mode], getComponents })) } diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index 8455e60ee14..be20faa9253 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -58,7 +58,7 @@ export async function initNitro (nuxt: Nuxt) { .concat(nuxt.options._generate ? ['/', ...nuxt.options.generate.routes] : []) .concat(nuxt.options.ssr === false ? ['/', '/200.html', '/404.html'] : []) }, - sourcemap: nuxt.options.sourcemap, + sourceMap: nuxt.options.sourcemap.server, externals: { inline: [ ...(nuxt.options.dev diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 16b60315274..111e12fff82 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -68,18 +68,18 @@ async function initNuxt (nuxt: Nuxt) { addWebpackPlugin(ImportProtectionPlugin.webpack(config)) // Add unctx transform - addVitePlugin(UnctxTransformPlugin(nuxt).vite({ sourcemap: nuxt.options.sourcemap })) - addWebpackPlugin(UnctxTransformPlugin(nuxt).webpack({ sourcemap: nuxt.options.sourcemap })) + addVitePlugin(UnctxTransformPlugin(nuxt).vite({ sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client })) + addWebpackPlugin(UnctxTransformPlugin(nuxt).webpack({ sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client })) if (!nuxt.options.dev) { const removeFromServer = ['onBeforeMount', 'onMounted', 'onBeforeUpdate', 'onRenderTracked', 'onRenderTriggered', 'onActivated', 'onDeactivated', 'onBeforeUnmount'] const removeFromClient = ['onServerPrefetch', 'onRenderTracked', 'onRenderTriggered'] // Add tree-shaking optimisations for SSR - build time only - addVitePlugin(TreeShakePlugin.vite({ sourcemap: nuxt.options.sourcemap, treeShake: removeFromServer }), { client: false }) - addVitePlugin(TreeShakePlugin.vite({ sourcemap: nuxt.options.sourcemap, treeShake: removeFromClient }), { server: false }) - addWebpackPlugin(TreeShakePlugin.webpack({ sourcemap: nuxt.options.sourcemap, treeShake: removeFromServer }), { client: false }) - addWebpackPlugin(TreeShakePlugin.webpack({ sourcemap: nuxt.options.sourcemap, treeShake: removeFromClient }), { server: false }) + addVitePlugin(TreeShakePlugin.vite({ sourcemap: nuxt.options.sourcemap.server, treeShake: removeFromServer }), { client: false }) + addVitePlugin(TreeShakePlugin.vite({ sourcemap: nuxt.options.sourcemap.client, treeShake: removeFromClient }), { server: false }) + addWebpackPlugin(TreeShakePlugin.webpack({ sourcemap: nuxt.options.sourcemap.server, treeShake: removeFromServer }), { client: false }) + addWebpackPlugin(TreeShakePlugin.webpack({ sourcemap: nuxt.options.sourcemap.client, treeShake: removeFromClient }), { server: false }) } // TODO: [Experimental] Avoid emitting assets when flag is enabled diff --git a/packages/nuxt/src/imports/module.ts b/packages/nuxt/src/imports/module.ts index e6bd204ebfd..7f4a1dd49be 100644 --- a/packages/nuxt/src/imports/module.ts +++ b/packages/nuxt/src/imports/module.ts @@ -91,8 +91,8 @@ export default defineNuxtModule>({ }) } else { // Transform to inject imports in production mode - addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: nuxt.options.sourcemap })) - addWebpackPlugin(TransformPlugin.webpack({ ctx, options, sourcemap: nuxt.options.sourcemap })) + addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client })) + addWebpackPlugin(TransformPlugin.webpack({ ctx, options, sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client })) } const regenerateImports = async () => { diff --git a/packages/nuxt/src/pages/module.ts b/packages/nuxt/src/pages/module.ts index 6f080c1c312..0388c3a032d 100644 --- a/packages/nuxt/src/pages/module.ts +++ b/packages/nuxt/src/pages/module.ts @@ -88,7 +88,7 @@ export default defineNuxtModule({ // Extract macros from pages const macroOptions: TransformMacroPluginOptions = { dev: nuxt.options.dev, - sourcemap: nuxt.options.sourcemap, + sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client, macros: { definePageMeta: 'meta' } diff --git a/packages/schema/src/config/build.ts b/packages/schema/src/config/build.ts index c3e8eaf9648..8bf843e382e 100644 --- a/packages/schema/src/config/build.ts +++ b/packages/schema/src/config/build.ts @@ -26,9 +26,20 @@ export default defineUntypedSchema({ /** * Whether to generate sourcemaps. * + * @type {boolean | { server?: boolean, client?: boolean }} * @version 3 */ - sourcemap: true, + sourcemap: { + $resolve: (val, get) => { + if (typeof val === 'boolean') { + return { server: val, client: val } + } + return defu(val, { + server: true, + client: get('dev') + }) + }, + }, /** * Shared build configuration. * @version 2 diff --git a/packages/schema/src/types/config.ts b/packages/schema/src/types/config.ts index dbf73f4b4d4..8ae7f650c7f 100644 --- a/packages/schema/src/types/config.ts +++ b/packages/schema/src/types/config.ts @@ -26,6 +26,7 @@ export type NuxtConfigLayer = ConfigLayer> _layers: NuxtConfigLayer[] } @@ -58,11 +59,11 @@ export interface ViteConfig extends ViteUserConfig { type RuntimeConfigNamespace = Record -export interface PublicRuntimeConfig extends RuntimeConfigNamespace { } +export interface PublicRuntimeConfig extends RuntimeConfigNamespace {} // TODO: remove before release of 3.0.0 /** @deprecated use RuntimeConfig interface */ -export interface PrivateRuntimeConfig extends RuntimeConfigNamespace { } +export interface PrivateRuntimeConfig extends RuntimeConfigNamespace {} export interface RuntimeConfig extends PrivateRuntimeConfig, RuntimeConfigNamespace { public: PublicRuntimeConfig @@ -85,4 +86,4 @@ export interface NuxtAppConfig { keepalive: boolean | KeepAliveProps } -export interface AppConfig { } +export interface AppConfig {} diff --git a/packages/vite/src/client.ts b/packages/vite/src/client.ts index 1a1e6865292..4cd0a48b8ac 100644 --- a/packages/vite/src/client.ts +++ b/packages/vite/src/client.ts @@ -51,6 +51,7 @@ export async function buildClient (ctx: ViteBuildContext) { dedupe: ['vue'] }, build: { + sourcemap: ctx.nuxt.options.sourcemap.client, manifest: true, outDir: resolve(ctx.nuxt.options.buildDir, 'dist/client'), rollupOptions: { diff --git a/packages/vite/src/server.ts b/packages/vite/src/server.ts index d03546d1774..5a2c2a403ac 100644 --- a/packages/vite/src/server.ts +++ b/packages/vite/src/server.ts @@ -81,6 +81,7 @@ export async function buildServer (ctx: ViteBuildContext) { ] }, build: { + sourcemap: ctx.nuxt.options.sourcemap.server, outDir: resolve(ctx.nuxt.options.buildDir, 'dist/server'), ssr: ctx.nuxt.options.ssr ?? true, rollupOptions: { diff --git a/packages/vite/src/vite.ts b/packages/vite/src/vite.ts index 3348d37dd7e..664dafbf261 100644 --- a/packages/vite/src/vite.ts +++ b/packages/vite/src/vite.ts @@ -59,7 +59,7 @@ export async function bundle (nuxt: Nuxt) { } }, plugins: [ - composableKeysPlugin.vite({ sourcemap: nuxt.options.sourcemap, rootDir: nuxt.options.rootDir }), + composableKeysPlugin.vite({ sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client, rootDir: nuxt.options.rootDir }), replace({ ...Object.fromEntries([';', '(', '{', '}', ' ', '\t', '\n'].map(d => [`${d}global.`, `${d}globalThis.`])), preventAssignment: true diff --git a/packages/webpack/src/configs/client.ts b/packages/webpack/src/configs/client.ts index 8daa02c1b75..e01d82fa2ce 100644 --- a/packages/webpack/src/configs/client.ts +++ b/packages/webpack/src/configs/client.ts @@ -22,11 +22,16 @@ export function client (ctx: WebpackConfigContext) { } function clientDevtool (ctx: WebpackConfigContext) { - if (!ctx.isDev) { + if (!ctx.nuxt.options.sourcemap.client) { ctx.config.devtool = false return } + if (!ctx.isDev) { + ctx.config.devtool = 'source-map' + return + } + const scriptPolicy = getCspScriptPolicy(ctx) const noUnsafeEval = scriptPolicy && !scriptPolicy.includes('\'unsafe-eval\'') ctx.config.devtool = noUnsafeEval diff --git a/packages/webpack/src/configs/server.ts b/packages/webpack/src/configs/server.ts index a5fae9ceb1e..46c7b490bb0 100644 --- a/packages/webpack/src/configs/server.ts +++ b/packages/webpack/src/configs/server.ts @@ -27,7 +27,8 @@ function serverPreset (ctx: WebpackConfigContext) { const { config } = ctx config.output!.filename = 'server.mjs' - config.devtool = 'cheap-module-source-map' + + config.devtool = ctx.nuxt.options.sourcemap.server ? ctx.isDev ? 'cheap-module-source-map' : 'source-map' : false config.optimization = { splitChunks: false, diff --git a/packages/webpack/src/webpack.ts b/packages/webpack/src/webpack.ts index f23dffce199..c3a52296064 100644 --- a/packages/webpack/src/webpack.ts +++ b/packages/webpack/src/webpack.ts @@ -36,10 +36,10 @@ export async function bundle (nuxt: Nuxt) { // Configure compilers const compilers = webpackConfigs.map((config) => { config.plugins!.push(DynamicBasePlugin.webpack({ - sourcemap: nuxt.options.sourcemap + sourcemap: nuxt.options.sourcemap[config.name as 'client' | 'server'] })) config.plugins!.push(composableKeysPlugin.webpack({ - sourcemap: nuxt.options.sourcemap, + sourcemap: nuxt.options.sourcemap[config.name as 'client' | 'server'], rootDir: nuxt.options.rootDir }))