diff --git a/packages/next/build/swc/index.js b/packages/next/build/swc/index.js index 29483f14fff3..69365931ec6a 100644 --- a/packages/next/build/swc/index.js +++ b/packages/next/build/swc/index.js @@ -76,6 +76,9 @@ async function loadWasm() { parse(src, options) { return Promise.resolve(bindings.parse(src.toString(), options)) }, + getTargetTriple() { + return undefined + }, } return wasmBindings } catch (e) { @@ -187,6 +190,8 @@ function loadNative() { parse(src, options) { return bindings.parse(src, toBuffer(options ?? {})) }, + + getTargetTriple: bindings.getTargetTriple, } return nativeBindings } @@ -237,6 +242,6 @@ export async function parse(src, options) { export function getBinaryMetadata() { let bindings = loadBindingsSync() return { - target: bindings.getTargetTriple(), + target: bindings ? bindings.getTargetTriple() : undefined, } } diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 3e0665694117..4e8d4d4a8e53 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -43,7 +43,11 @@ import { WellKnownErrorsPlugin } from './webpack/plugins/wellknown-errors-plugin import { regexLikeCss } from './webpack/config/blocks/css' import { CopyFilePlugin } from './webpack/plugins/copy-file-plugin' import { FlightManifestPlugin } from './webpack/plugins/flight-manifest-plugin' -import { TelemetryPlugin } from './webpack/plugins/telemetry-plugin' +import { + Feature, + SWC_TARGET_TRIPLE, + TelemetryPlugin, +} from './webpack/plugins/telemetry-plugin' import type { Span } from '../trace' import { getRawPageExtensions } from './utils' import browserslist from 'next/dist/compiled/browserslist' @@ -406,6 +410,15 @@ export default async function getBaseWebpackConfig( const distDir = path.join(dir, config.distDir) let useSWCLoader = !babelConfigFile + let SWCBinaryTarget: [Feature, boolean] | undefined = undefined + if (useSWCLoader) { + // TODO: we do not collect wasm target yet + const binaryTarget = require('./swc')?.getBinaryMetadata?.() + ?.target as SWC_TARGET_TRIPLE + SWCBinaryTarget = binaryTarget + ? [`swc/target/${binaryTarget}` as const, true] + : undefined + } if (!loggedSwcDisabled && !useSWCLoader && babelConfigFile) { Log.info( @@ -1492,23 +1505,26 @@ export default async function getBaseWebpackConfig( !dev && !isServer && new TelemetryPlugin( - new Map([ - ['swcLoader', useSWCLoader], - ['swcMinify', config.swcMinify], - ['swcRelay', !!config.compiler?.relay], - ['swcStyledComponents', !!config.compiler?.styledComponents], - [ - 'swcReactRemoveProperties', - !!config.compiler?.reactRemoveProperties, - ], + new Map( [ - 'swcExperimentalDecorators', - !!jsConfig?.compilerOptions?.experimentalDecorators, - ], - ['swcRemoveConsole', !!config.compiler?.removeConsole], - ['swcImportSource', !!jsConfig?.compilerOptions?.jsxImportSource], - ['swcEmotion', !!config.experimental.emotion], - ]) + ['swcLoader', useSWCLoader], + ['swcMinify', config.swcMinify], + ['swcRelay', !!config.compiler?.relay], + ['swcStyledComponents', !!config.compiler?.styledComponents], + [ + 'swcReactRemoveProperties', + !!config.compiler?.reactRemoveProperties, + ], + [ + 'swcExperimentalDecorators', + !!jsConfig?.compilerOptions?.experimentalDecorators, + ], + ['swcRemoveConsole', !!config.compiler?.removeConsole], + ['swcImportSource', !!jsConfig?.compilerOptions?.jsxImportSource], + ['swcEmotion', !!config.experimental.emotion], + SWCBinaryTarget, + ].filter<[Feature, boolean]>(Boolean as any) + ) ), ].filter(Boolean as any as ExcludesFalse), } diff --git a/packages/next/build/webpack/plugins/telemetry-plugin.ts b/packages/next/build/webpack/plugins/telemetry-plugin.ts index aeb73cad89db..5aa5eaab7dff 100644 --- a/packages/next/build/webpack/plugins/telemetry-plugin.ts +++ b/packages/next/build/webpack/plugins/telemetry-plugin.ts @@ -1,6 +1,24 @@ import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack' -type Feature = +/** + * List of target triples next-swc native binary supports. + */ +export type SWC_TARGET_TRIPLE = + | 'x86_64-apple-darwin' + | 'x86_64-unknown-linux-gnu' + | 'x86_64-pc-windows-msvc' + | 'i686-pc-windows-msvc' + | 'aarch64-unknown-linux-gnu' + | 'armv7-unknown-linux-gnueabihf' + | 'aarch64-apple-darwin' + | 'aarch64-linux-android' + | 'arm-linux-androideabi' + | 'x86_64-unknown-freebsd' + | 'x86_64-unknown-linux-musl' + | 'aarch64-unknown-linux-musl' + | 'aarch64-pc-windows-msvc' + +export type Feature = | 'next/image' | 'next/script' | 'next/dynamic' @@ -13,6 +31,7 @@ type Feature = | 'swcRemoveConsole' | 'swcImportSource' | 'swcEmotion' + | `swc/target/${SWC_TARGET_TRIPLE}` interface FeatureUsage { featureName: Feature @@ -52,6 +71,19 @@ const BUILD_FEATURES: Array = [ 'swcRemoveConsole', 'swcImportSource', 'swcEmotion', + 'swc/target/x86_64-apple-darwin', + 'swc/target/x86_64-unknown-linux-gnu', + 'swc/target/x86_64-pc-windows-msvc', + 'swc/target/i686-pc-windows-msvc', + 'swc/target/aarch64-unknown-linux-gnu', + 'swc/target/armv7-unknown-linux-gnueabihf', + 'swc/target/aarch64-apple-darwin', + 'swc/target/aarch64-linux-android', + 'swc/target/arm-linux-androideabi', + 'swc/target/x86_64-unknown-freebsd', + 'swc/target/x86_64-unknown-linux-musl', + 'swc/target/aarch64-unknown-linux-musl', + 'swc/target/aarch64-pc-windows-msvc', ] /** diff --git a/packages/next/telemetry/events/build.ts b/packages/next/telemetry/events/build.ts index 9b64803af6ac..2a260b060394 100644 --- a/packages/next/telemetry/events/build.ts +++ b/packages/next/telemetry/events/build.ts @@ -1,4 +1,5 @@ import { TelemetryPlugin } from '../../build/webpack/plugins/telemetry-plugin' +import type { SWC_TARGET_TRIPLE } from '../../build/webpack/plugins/telemetry-plugin' const REGEXP_DIRECTORY_DUNDER = /[\\/]__[^\\/]+(? { regex.exec(stderr).pop() // swcRemoveConsole regex.exec(stderr).pop() // swcImportSource regex.exec(stderr).pop() // swcEmotion + regex.exec(stderr).pop() // swc/targets/* + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() + regex.exec(stderr).pop() const image = regex.exec(stderr).pop() expect(image).toContain(`"featureName": "next/image"`) expect(image).toContain(`"invocationCount": 1`)