|
1 | 1 | import { basename, resolve } from 'node:path'
|
2 | 2 | import { fileURLToPath } from 'node:url'
|
| 3 | +import { stripVTControlCharacters } from 'node:util' |
3 | 4 | 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' |
6 | 14 | import type { LibraryFormats, LibraryOptions } from '../build'
|
7 | 15 | import {
|
8 | 16 | build,
|
9 | 17 | createBuilder,
|
| 18 | + onRollupLog, |
10 | 19 | resolveBuildOutputs,
|
11 | 20 | resolveLibFilename,
|
12 | 21 | } from '../build'
|
13 | 22 | import type { Logger } from '../logger'
|
14 | 23 | import { createLogger } from '../logger'
|
| 24 | +import { BuildEnvironment, resolveConfig } from '..' |
15 | 25 |
|
16 | 26 | const __dirname = resolve(fileURLToPath(import.meta.url), '..')
|
17 | 27 |
|
@@ -876,6 +886,158 @@ test('adjust worker build error for worker.format', async () => {
|
876 | 886 | expect.unreachable()
|
877 | 887 | })
|
878 | 888 |
|
| 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 | + |
879 | 1041 | /**
|
880 | 1042 | * for each chunks in output1, if there's a chunk in output2 with the same fileName,
|
881 | 1043 | * ensure that the chunk code is the same. if not, the chunk hash should have changed.
|
|
0 commit comments