Skip to content

Commit bf3e410

Browse files
mato533sapphi-red
andauthored
feat: call Logger for plugin logs in build (#13757)
Co-authored-by: sapphi-red <[email protected]>
1 parent 51a42c6 commit bf3e410

File tree

4 files changed

+251
-58
lines changed

4 files changed

+251
-58
lines changed

eslint.config.js

+5-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import tseslint from 'typescript-eslint'
88
import globals from 'globals'
99

1010
const require = createRequire(import.meta.url)
11-
const pkg = require('./package.json')
1211
const pkgVite = require('./packages/vite/package.json')
1312

1413
// Some rules work better with typechecking enabled, but as enabling it is slow,
@@ -51,6 +50,11 @@ export default tseslint.config(
5150
...globals.node,
5251
},
5352
},
53+
settings: {
54+
node: {
55+
version: '^18.0.0 || ^20.0.0 || >=22.0.0',
56+
},
57+
},
5458
plugins: {
5559
n: pluginN,
5660
'import-x': pluginImportX,
@@ -213,17 +217,9 @@ export default tseslint.config(
213217
name: 'playground/test',
214218
files: ['playground/**/__tests__/**/*.?([cm])[jt]s?(x)'],
215219
rules: {
216-
// engine field doesn't exist in playgrounds
217-
'n/no-unsupported-features/es-builtins': [
218-
'error',
219-
{
220-
version: pkg.engines.node,
221-
},
222-
],
223220
'n/no-unsupported-features/node-builtins': [
224221
'error',
225222
{
226-
version: pkg.engines.node,
227223
// ideally we would like to allow all experimental features
228224
// https://github.com/eslint-community/eslint-plugin-n/issues/199
229225
ignores: ['fetch'],

packages/vite/src/node/__tests__/build.spec.ts

+164-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import { basename, resolve } from 'node:path'
22
import { fileURLToPath } from 'node:url'
3+
import { stripVTControlCharacters } from 'node:util'
34
import colors from 'picocolors'
4-
import { describe, expect, test, vi } from 'vitest'
5-
import type { OutputChunk, OutputOptions, RollupOutput } from 'rollup'
5+
import { afterEach, describe, expect, test, vi } from 'vitest'
6+
import type {
7+
LogLevel,
8+
OutputChunk,
9+
OutputOptions,
10+
RollupLog,
11+
RollupOptions,
12+
RollupOutput,
13+
} from 'rollup'
614
import type { LibraryFormats, LibraryOptions } from '../build'
715
import {
816
build,
917
createBuilder,
18+
onRollupLog,
1019
resolveBuildOutputs,
1120
resolveLibFilename,
1221
} from '../build'
1322
import type { Logger } from '../logger'
1423
import { createLogger } from '../logger'
24+
import { BuildEnvironment, resolveConfig } from '..'
1525

1626
const __dirname = resolve(fileURLToPath(import.meta.url), '..')
1727

@@ -876,6 +886,158 @@ test('adjust worker build error for worker.format', async () => {
876886
expect.unreachable()
877887
})
878888

889+
describe('onRollupLog', () => {
890+
const pluginName = 'rollup-plugin-test'
891+
const msgInfo = 'This is the INFO message.'
892+
const msgWarn = 'This is the WARN message.'
893+
const buildProject = async (
894+
level: LogLevel | 'error',
895+
message: string | RollupLog,
896+
logger: Logger,
897+
options?: Pick<RollupOptions, 'onLog' | 'onwarn'>,
898+
) => {
899+
await build({
900+
root: resolve(__dirname, 'packages/build-project'),
901+
logLevel: 'info',
902+
build: {
903+
write: false,
904+
rollupOptions: {
905+
...options,
906+
logLevel: 'debug',
907+
},
908+
},
909+
customLogger: logger,
910+
plugins: [
911+
{
912+
name: pluginName,
913+
resolveId(id) {
914+
this[level](message)
915+
if (id === 'entry.js') {
916+
return '\0' + id
917+
}
918+
},
919+
load(id) {
920+
if (id === '\0entry.js') {
921+
return `export default "This is test module";`
922+
}
923+
},
924+
},
925+
],
926+
})
927+
}
928+
929+
const callOnRollupLog = async (
930+
logger: Logger,
931+
level: LogLevel,
932+
log: RollupLog,
933+
) => {
934+
const config = await resolveConfig(
935+
{ customLogger: logger },
936+
'build',
937+
'production',
938+
'production',
939+
)
940+
const buildEnvironment = new BuildEnvironment('client', config)
941+
onRollupLog(level, log, buildEnvironment)
942+
}
943+
944+
afterEach(() => {
945+
vi.restoreAllMocks()
946+
})
947+
948+
test('Rollup logs of info should be handled by vite', async () => {
949+
const logger = createLogger()
950+
const loggerSpy = vi.spyOn(logger, 'info').mockImplementation(() => {})
951+
952+
await buildProject('info', msgInfo, logger)
953+
const logs = loggerSpy.mock.calls.map((args) =>
954+
stripVTControlCharacters(args[0]),
955+
)
956+
expect(logs).contain(`[plugin ${pluginName}] ${msgInfo}`)
957+
})
958+
959+
test('Rollup logs of warn should be handled by vite', async () => {
960+
const logger = createLogger('silent')
961+
const loggerSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {})
962+
963+
await buildProject('warn', msgWarn, logger)
964+
const logs = loggerSpy.mock.calls.map((args) =>
965+
stripVTControlCharacters(args[0]),
966+
)
967+
expect(logs).contain(`[plugin ${pluginName}] ${msgWarn}`)
968+
})
969+
970+
test('onLog passed by user is called', async () => {
971+
const logger = createLogger('silent')
972+
973+
const onLogInfo = vi.fn((_log: RollupLog) => {})
974+
await buildProject('info', msgInfo, logger, {
975+
onLog(level, log) {
976+
if (level === 'info') {
977+
onLogInfo(log)
978+
}
979+
},
980+
})
981+
expect(onLogInfo).toBeCalledWith(
982+
expect.objectContaining({ message: `[plugin ${pluginName}] ${msgInfo}` }),
983+
)
984+
})
985+
986+
test('onwarn passed by user is called', async () => {
987+
const logger = createLogger('silent')
988+
989+
const onWarn = vi.fn((_log: RollupLog) => {})
990+
await buildProject('warn', msgWarn, logger, {
991+
onwarn(warning) {
992+
onWarn(warning)
993+
},
994+
})
995+
expect(onWarn).toBeCalledWith(
996+
expect.objectContaining({ message: `[plugin ${pluginName}] ${msgWarn}` }),
997+
)
998+
})
999+
1000+
test('should throw error when warning contains UNRESOLVED_IMPORT', async () => {
1001+
const logger = createLogger()
1002+
await expect(() =>
1003+
callOnRollupLog(logger, 'warn', {
1004+
code: 'UNRESOLVED_IMPORT',
1005+
message: 'test',
1006+
}),
1007+
).rejects.toThrowError(/Rollup failed to resolve import/)
1008+
})
1009+
1010+
test.each([[`Unsupported expression`], [`statically analyzed`]])(
1011+
'should ignore dynamic import warnings (%s)',
1012+
async (message: string) => {
1013+
const logger = createLogger()
1014+
const loggerSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {})
1015+
1016+
await callOnRollupLog(logger, 'warn', {
1017+
code: 'PLUGIN_WARNING',
1018+
message: message,
1019+
plugin: 'rollup-plugin-dynamic-import-variables',
1020+
})
1021+
expect(loggerSpy).toBeCalledTimes(0)
1022+
},
1023+
)
1024+
1025+
test.each([[`CIRCULAR_DEPENDENCY`], [`THIS_IS_UNDEFINED`]])(
1026+
'should ignore some warnings (%s)',
1027+
async (code: string) => {
1028+
const logger = createLogger()
1029+
const loggerSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {})
1030+
1031+
await callOnRollupLog(logger, 'warn', {
1032+
code: code,
1033+
message: 'test message',
1034+
plugin: pluginName,
1035+
})
1036+
expect(loggerSpy).toBeCalledTimes(0)
1037+
},
1038+
)
1039+
})
1040+
8791041
/**
8801042
* for each chunks in output1, if there's a chunk in output2 with the same fileName,
8811043
* ensure that the chunk code is the same. if not, the chunk hash should have changed.

0 commit comments

Comments
 (0)