feat(nuxt): warn on external webpack/nitro/postcss config (#22521)

This commit is contained in:
Lehoczky Zoltán 2023-08-08 13:33:10 +02:00 committed by GitHub
parent a4d1ee226a
commit e373fa7d68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 100 additions and 24 deletions

View File

@ -6,9 +6,10 @@ import { isIgnored, tryResolveModule, useNuxt } from '@nuxt/kit'
import { interopDefault } from 'mlly'
import { debounce } from 'perfect-debounce'
import { normalize, relative, resolve } from 'pathe'
import type { Nuxt } from 'nuxt/schema'
import type { Nuxt, NuxtBuilder } from 'nuxt/schema'
import { generateApp as _generateApp, createApp } from './app'
import { checkForExternalConfigurationFiles } from './external-config-files'
export async function build (nuxt: Nuxt) {
const app = createApp(nuxt)
@ -43,7 +44,7 @@ export async function build (nuxt: Nuxt) {
await nuxt.callHook('build:before')
if (!nuxt.options._prepare) {
await bundle(nuxt)
await Promise.all([checkForExternalConfigurationFiles(), bundle(nuxt)])
await nuxt.callHook('build:done')
}
@ -178,23 +179,23 @@ async function bundle (nuxt: Nuxt) {
? await loadBuilder(nuxt, nuxt.options.builder)
: nuxt.options.builder
return bundle(nuxt)
await bundle(nuxt)
} catch (error: any) {
await nuxt.callHook('build:error', error)
if (error.toString().includes('Cannot find module \'@nuxt/webpack-builder\'')) {
throw new Error([
'Could not load `@nuxt/webpack-builder`. You may need to add it to your project dependencies, following the steps in `https://github.com/nuxt/framework/pull/2812`.'
].join('\n'))
throw new Error('Could not load `@nuxt/webpack-builder`. You may need to add it to your project dependencies, following the steps in `https://github.com/nuxt/framework/pull/2812`.')
}
throw error
}
}
async function loadBuilder (nuxt: Nuxt, builder: string) {
async function loadBuilder (nuxt: Nuxt, builder: string): Promise<NuxtBuilder> {
const builderPath = await tryResolveModule(builder, [nuxt.options.rootDir, import.meta.url])
if (builderPath) {
return import(pathToFileURL(builderPath).href)
if (!builderPath) {
throw new Error(`Loading \`${builder}\` builder failed. You can read more about the nuxt \`builder\` option at: \`https://nuxt.com/docs/api/configuration/nuxt-config#builder\``)
}
return import(pathToFileURL(builderPath).href)
}

View File

@ -0,0 +1,77 @@
import { findPath } from '@nuxt/kit'
import { basename } from 'pathe'
import { generateApp as _generateApp } from './app'
/**
* Check for those external configuration files that are not compatible with Nuxt,
* and warns the user about them.
*
* @see {@link https://nuxt.com/docs/getting-started/configuration#external-configuration-files}
*/
export async function checkForExternalConfigurationFiles () {
const checkResults = await Promise.all([checkViteConfig(), checkWebpackConfig(), checkNitroConfig(), checkPostCSSConfig()])
const warningMessages = checkResults.filter(Boolean) as string[]
if (!warningMessages.length) {
return
}
const foundOneExternalConfig = warningMessages.length === 1
if (foundOneExternalConfig) {
console.warn(warningMessages[0])
} else {
const warningsAsList = warningMessages.map(message => `- ${message}`).join('\n')
const warning = `Found multiple external configuration files: \n\n${warningsAsList}`
console.warn(warning)
}
}
async function checkViteConfig () {
// https://github.com/vitejs/vite/blob/8fe69524d25d45290179175ba9b9956cbce87a91/packages/vite/src/node/constants.ts#L38
return await checkAndWarnAboutConfigFileExistence({
fileName: 'vite.config',
extensions: ['.js', '.mjs', '.ts', '.cjs', '.mts', '.cts'],
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.vite\` instead. You can read more in \`https://nuxt.com/docs/api/configuration/nuxt-config#vite\`.`
})
}
async function checkWebpackConfig () {
// https://webpack.js.org/configuration/configuration-languages/
return await checkAndWarnAboutConfigFileExistence({
fileName: 'webpack.config',
extensions: ['.js', '.mjs', '.ts', '.cjs', '.mts', '.cts', 'coffee'],
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.webpack\` instead. You can read more in \`https://nuxt.com/docs/api/configuration/nuxt-config#webpack-1\`.`
})
}
async function checkNitroConfig () {
// https://nitro.unjs.io/config#configuration
return await checkAndWarnAboutConfigFileExistence({
fileName: 'nitro.config',
extensions: ['.ts', '.mts'],
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.nitro\` instead. You can read more in \`https://nuxt.com/docs/api/configuration/nuxt-config#nitro\`.`
})
}
async function checkPostCSSConfig () {
return await checkAndWarnAboutConfigFileExistence({
fileName: 'postcss.config',
extensions: ['.js', '.cjs'],
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.postcss\` instead. You can read more in \`https://nuxt.com/docs/api/configuration/nuxt-config#postcss\`.`
})
}
interface CheckAndWarnAboutConfigFileExistenceOptions {
fileName: string,
extensions: string[],
createWarningMessage: (foundFile: string) => string
}
async function checkAndWarnAboutConfigFileExistence (options: CheckAndWarnAboutConfigFileExistenceOptions) {
const { fileName, extensions, createWarningMessage } = options
const configFile = await findPath(fileName, { extensions }).catch(() => null)
if (configFile) {
return createWarningMessage(basename(configFile))
}
}

View File

@ -95,7 +95,7 @@ export type NuxtConfigLayer = ConfigLayer<NuxtConfig & {
/** Normalized Nuxt options available as `nuxt.options.*` */
export interface NuxtOptions extends Omit<ConfigSchema, 'builder' | 'webpack'> {
sourcemap: Required<Exclude<ConfigSchema['sourcemap'], boolean>>
builder: '@nuxt/vite-builder' | '@nuxt/webpack-builder' | { bundle: (nuxt: Nuxt) => Promise<void> }
builder: '@nuxt/vite-builder' | '@nuxt/webpack-builder' | NuxtBuilder
webpack: ConfigSchema['webpack'] & {
$client: ConfigSchema['webpack']
$server: ConfigSchema['webpack']
@ -104,6 +104,10 @@ export interface NuxtOptions extends Omit<ConfigSchema, 'builder' | 'webpack'> {
$schema: SchemaDefinition
}
export interface NuxtBuilder {
bundle: (nuxt: Nuxt) => Promise<void>
}
export interface ViteConfig extends Omit<ViteUserConfig, 'publicDir'> {
/** The path to the entrypoint for the Vite build. */
entry?: string

View File

@ -1,14 +1,14 @@
import { existsSync } from 'node:fs'
import * as vite from 'vite'
import { basename, dirname, join, resolve } from 'pathe'
import type { Nuxt, ViteConfig } from '@nuxt/schema'
import { dirname, join, resolve } from 'pathe'
import type { Nuxt, NuxtBuilder, ViteConfig } from '@nuxt/schema'
import { addVitePlugin, isIgnored, logger, resolvePath } from '@nuxt/kit'
import replace from '@rollup/plugin-replace'
import { sanitizeFilePath } from 'mlly'
import { withoutLeadingSlash } from 'ufo'
import { filename } from 'pathe/utils'
import { resolveTSConfig } from 'pkg-types'
import { consola } from 'consola'
import { buildClient } from './client'
import { buildServer } from './server'
import virtual from './plugins/virtual'
@ -26,14 +26,7 @@ export interface ViteBuildContext {
ssrServer?: vite.ViteDevServer
}
export async function bundle (nuxt: Nuxt) {
// https://github.com/vitejs/vite/blob/8fe69524d25d45290179175ba9b9956cbce87a91/packages/vite/src/node/constants.ts#L38
const viteConfigPrefix = resolve(nuxt.options.rootDir, 'vite.config')
const viteConfigFile = await resolvePath(viteConfigPrefix).catch(() => null)
if (viteConfigFile && viteConfigFile !== viteConfigPrefix) {
consola.warn(`Using \`${basename(viteConfigFile)}\` is not supported together with Nuxt. Use \`options.vite\` instead. You can read more in \`https://nuxt.com/docs/api/configuration/nuxt-config#vite\`.`)
}
export const bundle: NuxtBuilder['bundle'] = async (nuxt) => {
const useAsyncEntry = nuxt.options.experimental.asyncEntry ||
(nuxt.options.vite.devBundler === 'vite-node' && nuxt.options.dev)
const entry = await resolvePath(resolve(nuxt.options.appDir, useAsyncEntry ? 'entry.async' : 'entry'))

View File

@ -7,7 +7,7 @@ import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import type { Compiler, Watching } from 'webpack'
import { defu } from 'defu'
import type { Nuxt } from '@nuxt/schema'
import type { NuxtBuilder } from '@nuxt/schema'
import { joinURL } from 'ufo'
import { logger, useNuxt } from '@nuxt/kit'
@ -22,7 +22,7 @@ import { applyPresets, createWebpackConfigContext, getWebpackConfig } from './ut
// TODO: Support plugins
// const plugins: string[] = []
export async function bundle (nuxt: Nuxt) {
export const bundle: NuxtBuilder['bundle'] = async (nuxt) => {
registerVirtualModules()
const webpackConfigs = [client, ...nuxt.options.ssr ? [server] : []].map((preset) => {
@ -75,7 +75,8 @@ export async function bundle (nuxt: Nuxt) {
// Start Builds
if (nuxt.options.dev) {
return Promise.all(compilers.map(c => compile(c)))
await Promise.all(compilers.map(c => compile(c)))
return
}
for (const c of compilers) {