feat(blog): add file-based blog with dynamic slugs, MDX content and layout shell

- Introduced blog routing using Next.js App Router
- Implemented dynamic [slug] pages for blog posts
- Added MDX-based content loading via lib/posts
- Integrated shared TopBar layout with navigation
- Established clear content, lib and component separation
This commit is contained in:
PascalSchattenburg
2026-01-22 14:14:15 +01:00
parent b717952234
commit d147843c76
10412 changed files with 2475583 additions and 0 deletions

View File

@@ -0,0 +1,373 @@
import { readFileSync } from 'node:fs';
import { inspect } from 'node:util';
import JSON5 from 'next/dist/compiled/json5';
import { createConfigItem, loadOptions } from 'next/dist/compiled/babel/core';
import loadFullConfig from 'next/dist/compiled/babel/core-lib-config';
import { consumeIterator } from './util';
import * as Log from '../../output/log';
import { isReactCompilerRequired } from '../../swc';
import { installBindings } from '../../swc/install-bindings';
const nextDistPath = /(next[\\/]dist[\\/]shared[\\/]lib)|(next[\\/]dist[\\/]client)|(next[\\/]dist[\\/]pages)/;
function shouldSkipBabel(transformMode, configFilePath, hasReactCompiler) {
return transformMode === 'standalone' && configFilePath == null && !hasReactCompiler;
}
const fileExtensionRegex = /\.([a-z]+)$/;
async function getCacheCharacteristics(loaderOptions, source, filename) {
var _fileExtensionRegex_exec;
let isStandalone, isServer, pagesDir;
switch(loaderOptions.transformMode){
case 'default':
isStandalone = false;
isServer = loaderOptions.isServer;
pagesDir = loaderOptions.pagesDir;
break;
case 'standalone':
isStandalone = true;
break;
default:
throw Object.defineProperty(new Error(`unsupported transformMode in loader options: ${inspect(loaderOptions)}`), "__NEXT_ERROR_CODE", {
value: "E811",
enumerable: false,
configurable: true
});
}
const isPageFile = pagesDir != null && filename.startsWith(pagesDir);
const isNextDist = nextDistPath.test(filename);
const hasModuleExports = source.indexOf('module.exports') !== -1;
const fileExt = ((_fileExtensionRegex_exec = fileExtensionRegex.exec(filename)) == null ? void 0 : _fileExtensionRegex_exec[1]) || 'unknown';
let { reactCompilerPlugins, reactCompilerExclude, configFile: configFilePath, transformMode } = loaderOptions;
// Compute `hasReactCompiler` as part of the cache characteristics / key,
// rather than inside of `getFreshConfig`:
// - `isReactCompilerRequired` depends on the file contents
// - `node_modules` and `reactCompilerExclude` depend on the file path, which
// isn't part of the cache characteristics
let hasReactCompiler = reactCompilerPlugins != null && reactCompilerPlugins.length !== 0 && !loaderOptions.isServer && !/[/\\]node_modules[/\\]/.test(filename) && // Assumption: `reactCompilerExclude` is cheap because it should only
// operate on the file path and *not* the file contents (it's sync)
!(reactCompilerExclude == null ? void 0 : reactCompilerExclude(filename));
// `isReactCompilerRequired` is expensive to run (parses/visits with SWC), so
// only run it if there's a good chance we might be able to skip calling Babel
// entirely (speculatively call `shouldSkipBabel`).
//
// Otherwise, we can let react compiler handle this logic for us. It should
// behave equivalently.
if (hasReactCompiler && shouldSkipBabel(transformMode, configFilePath, /*hasReactCompiler*/ false)) {
hasReactCompiler &&= await isReactCompilerRequired(filename);
}
return {
isStandalone,
isServer,
isPageFile,
isNextDist,
hasModuleExports,
hasReactCompiler,
fileExt,
configFilePath
};
}
/**
* Return an array of Babel plugins, conditioned upon loader options and
* source file characteristics.
*/ function getPlugins(loaderOptions, cacheCharacteristics) {
const { isServer, isPageFile, isNextDist, hasModuleExports } = cacheCharacteristics;
const { development, hasReactRefresh } = loaderOptions;
const applyCommonJsItem = hasModuleExports ? createConfigItem(require('../plugins/commonjs'), {
type: 'plugin'
}) : null;
const reactRefreshItem = hasReactRefresh ? createConfigItem([
require('next/dist/compiled/react-refresh/babel'),
{
skipEnvCheck: true
}
], {
type: 'plugin'
}) : null;
const pageConfigItem = !isServer && isPageFile ? createConfigItem([
require('../plugins/next-page-config')
], {
type: 'plugin'
}) : null;
const disallowExportAllItem = !isServer && isPageFile ? createConfigItem([
require('../plugins/next-page-disallow-re-export-all-exports')
], {
type: 'plugin'
}) : null;
const transformDefineItem = createConfigItem([
require.resolve('next/dist/compiled/babel/plugin-transform-define'),
{
'process.env.NODE_ENV': development ? 'development' : 'production',
'typeof window': isServer ? 'undefined' : 'object',
'process.browser': isServer ? false : true
},
'next-js-transform-define-instance'
], {
type: 'plugin'
});
const nextSsgItem = !isServer && isPageFile ? createConfigItem([
require.resolve('../plugins/next-ssg-transform')
], {
type: 'plugin'
}) : null;
const commonJsItem = isNextDist ? createConfigItem(require('next/dist/compiled/babel/plugin-transform-modules-commonjs'), {
type: 'plugin'
}) : null;
const nextFontUnsupported = createConfigItem([
require('../plugins/next-font-unsupported')
], {
type: 'plugin'
});
return [
reactRefreshItem,
pageConfigItem,
disallowExportAllItem,
applyCommonJsItem,
transformDefineItem,
nextSsgItem,
commonJsItem,
nextFontUnsupported
].filter(Boolean);
}
const isJsonFile = /\.(json|babelrc)$/;
const isJsFile = /\.js$/;
/**
* While this function does block execution while reading from disk, it
* should not introduce any issues. The function is only invoked when
* generating a fresh config, and only a small handful of configs should
* be generated during compilation.
*/ function getCustomBabelConfig(configFilePath) {
if (isJsonFile.exec(configFilePath)) {
const babelConfigRaw = readFileSync(configFilePath, 'utf8');
return JSON5.parse(babelConfigRaw);
} else if (isJsFile.exec(configFilePath)) {
return require(configFilePath);
}
throw Object.defineProperty(new Error('The Next.js Babel loader does not support .mjs or .cjs config files.'), "__NEXT_ERROR_CODE", {
value: "E477",
enumerable: false,
configurable: true
});
}
let babelConfigWarned = false;
/**
* Check if custom babel configuration from user only contains options that
* can be migrated into latest Next.js features supported by SWC.
*
* This raises soft warning messages only, not making any errors yet.
*/ function checkCustomBabelConfigDeprecation(config) {
if (!config || Object.keys(config).length === 0) {
return;
}
const { plugins, presets, ...otherOptions } = config;
if (Object.keys(otherOptions ?? {}).length > 0) {
return;
}
if (babelConfigWarned) {
return;
}
babelConfigWarned = true;
const isPresetReadyToDeprecate = !presets || presets.length === 0 || presets.length === 1 && presets[0] === 'next/babel';
const pluginReasons = [];
const unsupportedPlugins = [];
if (Array.isArray(plugins)) {
for (const plugin of plugins){
const pluginName = Array.isArray(plugin) ? plugin[0] : plugin;
// [NOTE]: We cannot detect if the user uses babel-plugin-macro based transform plugins,
// such as `styled-components/macro` in here.
switch(pluginName){
case 'styled-components':
case 'babel-plugin-styled-components':
pluginReasons.push(`\t- 'styled-components' can be enabled via 'compiler.styledComponents' in 'next.config.js'`);
break;
case '@emotion/babel-plugin':
pluginReasons.push(`\t- '@emotion/babel-plugin' can be enabled via 'compiler.emotion' in 'next.config.js'`);
break;
case 'babel-plugin-relay':
pluginReasons.push(`\t- 'babel-plugin-relay' can be enabled via 'compiler.relay' in 'next.config.js'`);
break;
case 'react-remove-properties':
pluginReasons.push(`\t- 'react-remove-properties' can be enabled via 'compiler.reactRemoveProperties' in 'next.config.js'`);
break;
case 'transform-remove-console':
pluginReasons.push(`\t- 'transform-remove-console' can be enabled via 'compiler.removeConsole' in 'next.config.js'`);
break;
default:
unsupportedPlugins.push(pluginName);
break;
}
}
}
if (isPresetReadyToDeprecate && unsupportedPlugins.length === 0) {
Log.warn(`It looks like there is a custom Babel configuration that can be removed${pluginReasons.length > 0 ? ':' : '.'}`);
if (pluginReasons.length > 0) {
Log.warn(`Next.js supports the following features natively: `);
Log.warn(pluginReasons.join(''));
Log.warn(`For more details configuration options, please refer https://nextjs.org/docs/architecture/nextjs-compiler#supported-features`);
}
}
}
/**
* Generate a new, flat Babel config, ready to be handed to Babel-traverse.
* This config should have no unresolved overrides, presets, etc.
*
* The config returned by this function is cached, so the function should not
* depend on file-specific configuration or configuration that could change
* across invocations without a process restart.
*/ async function getFreshConfig(ctx, cacheCharacteristics, loaderOptions, target) {
const { transformMode } = loaderOptions;
const { hasReactCompiler, configFilePath, fileExt } = cacheCharacteristics;
let customConfig = configFilePath && getCustomBabelConfig(configFilePath);
if (shouldSkipBabel(transformMode, configFilePath, hasReactCompiler)) {
// Optimization: There's nothing useful to do, bail out and skip babel on
// this file
return null;
}
checkCustomBabelConfigDeprecation(customConfig);
// We can assume that `reactCompilerPlugins` does not change without a process
// restart (it's safe to cache), as it's specified in the `next.config.js`,
// which always causes a full restart of `next dev` if changed.
const reactCompilerPluginsIfEnabled = hasReactCompiler ? loaderOptions.reactCompilerPlugins ?? [] : [];
let isServer, pagesDir, srcDir, development;
if (transformMode === 'default') {
isServer = loaderOptions.isServer;
pagesDir = loaderOptions.pagesDir;
srcDir = loaderOptions.srcDir;
development = loaderOptions.development;
}
let options = {
babelrc: false,
cloneInputAst: false,
// Use placeholder file info. `updateBabelConfigWithFileDetails` will
// replace this after caching.
filename: `basename.${fileExt}`,
inputSourceMap: undefined,
sourceFileName: `basename.${fileExt}`,
// Set the default sourcemap behavior based on Webpack's mapping flag,
// but allow users to override if they want.
sourceMaps: loaderOptions.sourceMaps === undefined ? ctx.sourceMap : loaderOptions.sourceMaps
};
const baseCaller = {
name: 'next-babel-turbo-loader',
supportsStaticESM: true,
supportsDynamicImport: true,
// Provide plugins with insight into webpack target.
// https://github.com/babel/babel-loader/issues/787
target,
// Webpack 5 supports TLA behind a flag. We enable it by default
// for Babel, and then webpack will throw an error if the experimental
// flag isn't enabled.
supportsTopLevelAwait: true,
isServer,
srcDir,
pagesDir,
isDev: development,
transformMode,
...loaderOptions.caller
};
options.plugins = [
...transformMode === 'default' ? getPlugins(loaderOptions, cacheCharacteristics) : [],
...reactCompilerPluginsIfEnabled,
...(customConfig == null ? void 0 : customConfig.plugins) || []
];
// target can be provided in babelrc
options.target = isServer ? undefined : customConfig == null ? void 0 : customConfig.target;
// env can be provided in babelrc
options.env = customConfig == null ? void 0 : customConfig.env;
options.presets = (()=>{
// If presets is defined the user will have next/babel in their babelrc
if (customConfig == null ? void 0 : customConfig.presets) {
return customConfig.presets;
}
// If presets is not defined the user will likely have "env" in their babelrc
if (customConfig) {
return undefined;
}
// If no custom config is provided the default is to use next/babel
return [
'next/babel'
];
})();
options.overrides = loaderOptions.overrides;
options.caller = {
...baseCaller,
hasJsxRuntime: transformMode === 'default' ? loaderOptions.hasJsxRuntime : undefined
};
// Babel does strict checks on the config so undefined is not allowed
if (typeof options.target === 'undefined') {
delete options.target;
}
Object.defineProperty(options.caller, 'onWarning', {
enumerable: false,
writable: false,
value: (reason)=>{
if (!(reason instanceof Error)) {
reason = Object.defineProperty(new Error(reason), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
ctx.emitWarning(reason);
}
});
const loadedOptions = loadOptions(options);
const config = consumeIterator(loadFullConfig(loadedOptions));
return config;
}
/**
* Each key returned here corresponds with a Babel config that can be shared.
* The conditions of permissible sharing between files is dependent on specific
* file attributes and Next.js compiler states: `CharacteristicsGermaneToCaching`.
*/ function getCacheKey(cacheCharacteristics) {
const { isStandalone, isServer, isPageFile, isNextDist, hasModuleExports, hasReactCompiler, fileExt, configFilePath } = cacheCharacteristics;
const flags = 0 | (isStandalone ? 1 : 0) | (isServer ? 2 : 0) | (isPageFile ? 4 : 0) | (isNextDist ? 8 : 0) | (hasModuleExports ? 16 : 0) | (hasReactCompiler ? 32 : 0);
// separate strings with null bytes, assuming null bytes are not valid in file
// paths
return `${configFilePath || ''}\x00${fileExt}\x00${flags}`;
}
const configCache = new Map();
const configFiles = new Set();
/**
* Applies file-specific values to a potentially-cached configuration object.
*/ function updateBabelConfigWithFileDetails(cachedConfig, loaderOptions, filename, inputSourceMap) {
if (cachedConfig == null) {
return null;
}
return {
...cachedConfig,
options: {
...cachedConfig.options,
cwd: loaderOptions.cwd,
root: loaderOptions.cwd,
filename,
inputSourceMap,
// Ensure that Webpack will get a full absolute path in the sourcemap
// so that it can properly map the module back to its internal cached
// modules.
sourceFileName: filename
}
};
}
export default async function getConfig(ctx, { source, target, loaderOptions, filename, inputSourceMap }) {
// Install bindings early so they are definitely available to the loader.
// When run by webpack in next this is already done with correct configuration so this is a no-op.
// In turbopack loaders are run in a subprocess so it may or may not be done.
await installBindings();
const cacheCharacteristics = await getCacheCharacteristics(loaderOptions, source, filename);
if (loaderOptions.configFile) {
// Ensures webpack invalidates the cache for this loader when the config file changes
ctx.addDependency(loaderOptions.configFile);
}
const cacheKey = getCacheKey(cacheCharacteristics);
const cachedConfig = configCache.get(cacheKey);
if (cachedConfig !== undefined) {
return updateBabelConfigWithFileDetails(cachedConfig, loaderOptions, filename, inputSourceMap);
}
if (loaderOptions.configFile && !configFiles.has(loaderOptions.configFile)) {
configFiles.add(loaderOptions.configFile);
Log.info(`Using external babel configuration from ${loaderOptions.configFile}`);
}
const freshConfig = await getFreshConfig(ctx, cacheCharacteristics, loaderOptions, target);
configCache.set(cacheKey, freshConfig);
return updateBabelConfigWithFileDetails(freshConfig, loaderOptions, filename, inputSourceMap);
}
//# sourceMappingURL=get-config.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,41 @@
import transform from './transform';
async function nextBabelLoader(ctx, parentTrace, inputSource, inputSourceMap) {
const filename = ctx.resourcePath;
// Ensure `.d.ts` are not processed.
if (filename.endsWith('.d.ts')) {
return [
inputSource,
inputSourceMap
];
}
const target = ctx.target;
const loaderOptions = parentTrace.traceChild('get-options')// @ts-ignore TODO: remove ignore once webpack 5 types are used
.traceFn(()=>ctx.getOptions());
if (loaderOptions.exclude && loaderOptions.exclude(filename)) {
return [
inputSource,
inputSourceMap
];
}
const loaderSpanInner = parentTrace.traceChild('next-babel-turbo-transform');
const { code: transformedSource, map: outputSourceMap } = await loaderSpanInner.traceAsyncFn(async ()=>await transform(ctx, inputSource, inputSourceMap, loaderOptions, filename, target, loaderSpanInner));
return [
transformedSource,
outputSourceMap
];
}
function nextBabelLoaderOuter(inputSource, // webpack's source map format is compatible with babel, but the type signature doesn't match
inputSourceMap) {
const callback = this.async();
const loaderSpan = this.currentTraceSpan.traceChild('next-babel-turbo-loader');
loaderSpan.traceAsyncFn(()=>nextBabelLoader(this, loaderSpan, inputSource, inputSourceMap)).then(([transformedSource, outputSourceMap])=>callback == null ? void 0 : callback(/* err */ null, transformedSource, outputSourceMap ?? inputSourceMap), (err)=>{
callback == null ? void 0 : callback(err);
});
}
// check this type matches `webpack.LoaderDefinitionFunction`, but be careful
// not to publicly rely on the webpack type since the generated typescript
// declarations will be wrong.
const _nextBabelLoaderOuter = nextBabelLoaderOuter;
export default nextBabelLoaderOuter;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/build/babel/loader/index.ts"],"sourcesContent":["import type { Span } from '../../../trace'\nimport transform from './transform'\nimport type { NextJsLoaderContext } from './types'\nimport type { SourceMap } from './util'\nimport type { webpack } from 'next/dist/compiled/webpack/webpack'\n\nasync function nextBabelLoader(\n ctx: NextJsLoaderContext,\n parentTrace: Span,\n inputSource: string,\n inputSourceMap: SourceMap | null | undefined\n): Promise<[string, SourceMap | null | undefined]> {\n const filename = ctx.resourcePath\n\n // Ensure `.d.ts` are not processed.\n if (filename.endsWith('.d.ts')) {\n return [inputSource, inputSourceMap]\n }\n\n const target = ctx.target\n const loaderOptions: any = parentTrace\n .traceChild('get-options')\n // @ts-ignore TODO: remove ignore once webpack 5 types are used\n .traceFn(() => ctx.getOptions())\n\n if (loaderOptions.exclude && loaderOptions.exclude(filename)) {\n return [inputSource, inputSourceMap]\n }\n\n const loaderSpanInner = parentTrace.traceChild('next-babel-turbo-transform')\n const { code: transformedSource, map: outputSourceMap } =\n await loaderSpanInner.traceAsyncFn(\n async () =>\n await transform(\n ctx,\n inputSource,\n inputSourceMap,\n loaderOptions,\n filename,\n target,\n loaderSpanInner\n )\n )\n\n return [transformedSource, outputSourceMap]\n}\n\nfunction nextBabelLoaderOuter(\n this: NextJsLoaderContext,\n inputSource: string,\n // webpack's source map format is compatible with babel, but the type signature doesn't match\n inputSourceMap?: any\n) {\n const callback = this.async()\n\n const loaderSpan = this.currentTraceSpan.traceChild('next-babel-turbo-loader')\n loaderSpan\n .traceAsyncFn(() =>\n nextBabelLoader(this, loaderSpan, inputSource, inputSourceMap)\n )\n .then(\n ([transformedSource, outputSourceMap]) =>\n callback?.(\n /* err */ null,\n transformedSource,\n outputSourceMap ?? inputSourceMap\n ),\n (err) => {\n callback?.(err)\n }\n )\n}\n\n// check this type matches `webpack.LoaderDefinitionFunction`, but be careful\n// not to publicly rely on the webpack type since the generated typescript\n// declarations will be wrong.\nconst _nextBabelLoaderOuter: webpack.LoaderDefinitionFunction<\n {},\n NextJsLoaderContext\n> = nextBabelLoaderOuter\n\nexport default nextBabelLoaderOuter\n"],"names":["transform","nextBabelLoader","ctx","parentTrace","inputSource","inputSourceMap","filename","resourcePath","endsWith","target","loaderOptions","traceChild","traceFn","getOptions","exclude","loaderSpanInner","code","transformedSource","map","outputSourceMap","traceAsyncFn","nextBabelLoaderOuter","callback","async","loaderSpan","currentTraceSpan","then","err","_nextBabelLoaderOuter"],"mappings":"AACA,OAAOA,eAAe,cAAa;AAKnC,eAAeC,gBACbC,GAAwB,EACxBC,WAAiB,EACjBC,WAAmB,EACnBC,cAA4C;IAE5C,MAAMC,WAAWJ,IAAIK,YAAY;IAEjC,oCAAoC;IACpC,IAAID,SAASE,QAAQ,CAAC,UAAU;QAC9B,OAAO;YAACJ;YAAaC;SAAe;IACtC;IAEA,MAAMI,SAASP,IAAIO,MAAM;IACzB,MAAMC,gBAAqBP,YACxBQ,UAAU,CAAC,cACZ,+DAA+D;KAC9DC,OAAO,CAAC,IAAMV,IAAIW,UAAU;IAE/B,IAAIH,cAAcI,OAAO,IAAIJ,cAAcI,OAAO,CAACR,WAAW;QAC5D,OAAO;YAACF;YAAaC;SAAe;IACtC;IAEA,MAAMU,kBAAkBZ,YAAYQ,UAAU,CAAC;IAC/C,MAAM,EAAEK,MAAMC,iBAAiB,EAAEC,KAAKC,eAAe,EAAE,GACrD,MAAMJ,gBAAgBK,YAAY,CAChC,UACE,MAAMpB,UACJE,KACAE,aACAC,gBACAK,eACAJ,UACAG,QACAM;IAIR,OAAO;QAACE;QAAmBE;KAAgB;AAC7C;AAEA,SAASE,qBAEPjB,WAAmB,EACnB,6FAA6F;AAC7FC,cAAoB;IAEpB,MAAMiB,WAAW,IAAI,CAACC,KAAK;IAE3B,MAAMC,aAAa,IAAI,CAACC,gBAAgB,CAACd,UAAU,CAAC;IACpDa,WACGJ,YAAY,CAAC,IACZnB,gBAAgB,IAAI,EAAEuB,YAAYpB,aAAaC,iBAEhDqB,IAAI,CACH,CAAC,CAACT,mBAAmBE,gBAAgB,GACnCG,4BAAAA,SACE,OAAO,GAAG,MACVL,mBACAE,mBAAmBd,iBAEvB,CAACsB;QACCL,4BAAAA,SAAWK;IACb;AAEN;AAEA,6EAA6E;AAC7E,0EAA0E;AAC1E,8BAA8B;AAC9B,MAAMC,wBAGFP;AAEJ,eAAeA,qBAAoB","ignoreList":[0]}

View File

@@ -0,0 +1,88 @@
/*
* Partially adapted from @babel/core (MIT license).
*/ import traverse from 'next/dist/compiled/babel/traverse';
import generate from 'next/dist/compiled/babel/generator';
import normalizeFile from 'next/dist/compiled/babel/core-lib-normalize-file';
import normalizeOpts from 'next/dist/compiled/babel/core-lib-normalize-opts';
import loadBlockHoistPlugin from 'next/dist/compiled/babel/core-lib-block-hoist-plugin';
import PluginPass from 'next/dist/compiled/babel/core-lib-plugin-pass';
import getConfig from './get-config';
import { consumeIterator } from './util';
function getTraversalParams(file, pluginPairs) {
const passPairs = [];
const passes = [];
const visitors = [];
for (const plugin of pluginPairs.concat(loadBlockHoistPlugin())){
const pass = new PluginPass(file, plugin.key, plugin.options);
passPairs.push([
plugin,
pass
]);
passes.push(pass);
visitors.push(plugin.visitor);
}
return {
passPairs,
passes,
visitors
};
}
function invokePluginPre(file, passPairs) {
for (const [{ pre }, pass] of passPairs){
if (pre) {
pre.call(pass, file);
}
}
}
function invokePluginPost(file, passPairs) {
for (const [{ post }, pass] of passPairs){
if (post) {
post.call(pass, file);
}
}
}
function transformAstPass(file, pluginPairs, parentSpan) {
const { passPairs, passes, visitors } = getTraversalParams(file, pluginPairs);
invokePluginPre(file, passPairs);
const visitor = traverse.visitors.merge(visitors, passes, // @ts-ignore - the exported types are incorrect here
file.opts.wrapPluginVisitorMethod);
parentSpan.traceChild('babel-turbo-traverse').traceFn(()=>traverse(file.ast, visitor, file.scope));
invokePluginPost(file, passPairs);
}
function transformAst(file, babelConfig, parentSpan) {
for (const pluginPairs of babelConfig.passes){
transformAstPass(file, pluginPairs, parentSpan);
}
}
export default async function transform(ctx, source, inputSourceMap, loaderOptions, filename, target, parentSpan) {
const getConfigSpan = parentSpan.traceChild('babel-turbo-get-config');
const babelConfig = await getConfig(ctx, {
source,
loaderOptions,
inputSourceMap: inputSourceMap ?? undefined,
target,
filename
});
if (!babelConfig) {
return {
code: source,
map: inputSourceMap ?? null
};
}
getConfigSpan.stop();
const normalizeSpan = parentSpan.traceChild('babel-turbo-normalize-file');
const file = consumeIterator(normalizeFile(babelConfig.passes, normalizeOpts(babelConfig), source));
normalizeSpan.stop();
const transformSpan = parentSpan.traceChild('babel-turbo-transform');
transformAst(file, babelConfig, transformSpan);
transformSpan.stop();
const generateSpan = parentSpan.traceChild('babel-turbo-generate');
const { code, map } = generate(file.ast, file.opts.generatorOpts, file.code);
generateSpan.stop();
return {
code,
map
};
}
//# sourceMappingURL=transform.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,77 @@
import type { webpack } from 'next/dist/compiled/webpack/webpack'
import type { JSONValue } from '../../../server/config-shared'
import type { Span } from '../../../trace'
export interface NextJsLoaderContext extends webpack.LoaderContext<{}> {
currentTraceSpan: Span
target: string
}
export interface NextBabelLoaderBaseOptions {
cwd: string
/**
* Should we read the user-provided custom babel config? Used in both `transformMode`s.
*/
configFile?: string
/**
* Custom plugins to be added to the generated babel options.
*/
reactCompilerPlugins?: Array<JSONValue>
/**
* Paths that the loader should not apply the react-compiler to.
*/
reactCompilerExclude?: (excludePath: string) => boolean
overrides?: any
/**
* Extra fields to pass to presets/plugins via the Babel 'caller' API.
*/
caller?: any
/**
* Advanced: Can override webpack's sourcemap behavior (see `NextJsLoaderContext["sourceMap"]`).
*/
sourceMaps?: boolean | 'inline' | 'both' | null | undefined
}
/**
* Options to create babel loader for the default transformations.
*
* This is primary usecase of babel-loader configuration for running
* all of the necessary transforms for the ecmascript instead of swc loader.
*/
export type NextBabelLoaderOptionDefaultPresets = NextBabelLoaderBaseOptions & {
transformMode: 'default'
isServer: boolean
distDir: string
pagesDir: string | undefined
srcDir: string
development: boolean
hasJsxRuntime: boolean
hasReactRefresh: boolean
}
/**
* Options to create babel loader for 'standalone' transformations.
*
* This'll create a babel loader does not enable any of the default Next.js
* presets or plugins that perform transformations. Non-transforming syntax
* plugins (e.g. Typescript) will still be enabled.
*
* This is useful when Babel is used in combination with SWC, and we expect SWC
* to perform downleveling and Next.js-specific transforms. Standalone mode is
* used in Turbopack and when React Compiler is used with webpack.
*/
export type NextBabelLoaderOptionStandalone = NextBabelLoaderBaseOptions & {
transformMode: 'standalone'
isServer: boolean
}
export type NextBabelLoaderOptions =
| NextBabelLoaderOptionDefaultPresets
| NextBabelLoaderOptionStandalone

View File

@@ -0,0 +1,10 @@
export function consumeIterator(iter) {
while(true){
const { value, done } = iter.next();
if (done) {
return value;
}
}
}
//# sourceMappingURL=util.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/build/babel/loader/util.ts"],"sourcesContent":["import type { TransformOptions } from 'next/dist/compiled/babel/core'\n\nexport function consumeIterator(iter: Iterator<any>) {\n while (true) {\n const { value, done } = iter.next()\n if (done) {\n return value\n }\n }\n}\n\n/**\n * Source map standard format as to revision 3.\n *\n * `TransformOptions` uses this type, but doesn't export it separately\n */\nexport type SourceMap = NonNullable<TransformOptions['inputSourceMap']>\n\n/**\n * An extension of the normal babel configuration, with extra `babel-loader`-specific fields that transforms can read.\n *\n * See: https://github.com/babel/babel-loader/blob/main/src/injectCaller.js\n */\nexport type BabelLoaderTransformOptions = TransformOptions & {\n target?: string\n}\n"],"names":["consumeIterator","iter","value","done","next"],"mappings":"AAEA,OAAO,SAASA,gBAAgBC,IAAmB;IACjD,MAAO,KAAM;QACX,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGF,KAAKG,IAAI;QACjC,IAAID,MAAM;YACR,OAAOD;QACT;IACF;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,27 @@
import commonjsPlugin from 'next/dist/compiled/babel/plugin-transform-modules-commonjs';
// Handle module.exports in user code
export default function CommonJSModulePlugin(...args) {
const commonjs = commonjsPlugin(...args);
return {
visitor: {
Program: {
exit (path, state) {
let foundModuleExports = false;
path.traverse({
MemberExpression (expressionPath) {
if (expressionPath.node.object.name !== 'module') return;
if (expressionPath.node.property.name !== 'exports') return;
foundModuleExports = true;
}
});
if (!foundModuleExports) {
return;
}
commonjs.visitor.Program.exit.call(this, path, state);
}
}
}
};
}
//# sourceMappingURL=commonjs.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/build/babel/plugins/commonjs.ts"],"sourcesContent":["import type { NodePath, types } from 'next/dist/compiled/babel/core'\nimport type { PluginObj } from 'next/dist/compiled/babel/core'\nimport commonjsPlugin from 'next/dist/compiled/babel/plugin-transform-modules-commonjs'\n\n// Handle module.exports in user code\nexport default function CommonJSModulePlugin(...args: any): PluginObj {\n const commonjs = commonjsPlugin(...args)\n return {\n visitor: {\n Program: {\n exit(path: NodePath<types.Program>, state) {\n let foundModuleExports = false\n path.traverse({\n MemberExpression(expressionPath: any) {\n if (expressionPath.node.object.name !== 'module') return\n if (expressionPath.node.property.name !== 'exports') return\n foundModuleExports = true\n },\n })\n\n if (!foundModuleExports) {\n return\n }\n\n commonjs.visitor.Program.exit.call(this, path, state)\n },\n },\n },\n }\n}\n"],"names":["commonjsPlugin","CommonJSModulePlugin","args","commonjs","visitor","Program","exit","path","state","foundModuleExports","traverse","MemberExpression","expressionPath","node","object","name","property","call"],"mappings":"AAEA,OAAOA,oBAAoB,6DAA4D;AAEvF,qCAAqC;AACrC,eAAe,SAASC,qBAAqB,GAAGC,IAAS;IACvD,MAAMC,WAAWH,kBAAkBE;IACnC,OAAO;QACLE,SAAS;YACPC,SAAS;gBACPC,MAAKC,IAA6B,EAAEC,KAAK;oBACvC,IAAIC,qBAAqB;oBACzBF,KAAKG,QAAQ,CAAC;wBACZC,kBAAiBC,cAAmB;4BAClC,IAAIA,eAAeC,IAAI,CAACC,MAAM,CAACC,IAAI,KAAK,UAAU;4BAClD,IAAIH,eAAeC,IAAI,CAACG,QAAQ,CAACD,IAAI,KAAK,WAAW;4BACrDN,qBAAqB;wBACvB;oBACF;oBAEA,IAAI,CAACA,oBAAoB;wBACvB;oBACF;oBAEAN,SAASC,OAAO,CAACC,OAAO,CAACC,IAAI,CAACW,IAAI,CAAC,IAAI,EAAEV,MAAMC;gBACjD;YACF;QACF;IACF;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,59 @@
import jsx from 'next/dist/compiled/babel/plugin-syntax-jsx';
export default function({ types: t }) {
return {
inherits: jsx,
visitor: {
JSXElement (_path, state) {
state.set('jsx', true);
},
// Fragment syntax is still JSX since it compiles to createElement(),
// but JSXFragment is not a JSXElement
JSXFragment (_path, state) {
state.set('jsx', true);
},
Program: {
exit (path, state) {
if (state.get('jsx')) {
const pragma = t.identifier(state.opts.pragma);
let importAs = pragma;
// if there's already a React in scope, use that instead of adding an import
const existingBinding = state.opts.reuseImport !== false && state.opts.importAs && path.scope.getBinding(state.opts.importAs);
// var _jsx = _pragma.createElement;
if (state.opts.property) {
if (state.opts.importAs) {
importAs = t.identifier(state.opts.importAs);
} else {
importAs = path.scope.generateUidIdentifier('pragma');
}
const mapping = t.variableDeclaration('var', [
t.variableDeclarator(pragma, t.memberExpression(importAs, t.identifier(state.opts.property)))
]);
// if the React binding came from a require('react'),
// make sure that our usage comes after it.
let newPath;
if (existingBinding && t.isVariableDeclarator(existingBinding.path.node) && t.isCallExpression(existingBinding.path.node.init) && t.isIdentifier(existingBinding.path.node.init.callee) && existingBinding.path.node.init.callee.name === 'require') {
;
[newPath] = existingBinding.path.parentPath.insertAfter(mapping);
} else {
;
[newPath] = path.unshiftContainer('body', mapping);
}
path.scope.registerDeclaration(newPath);
}
if (!existingBinding) {
const importSpecifier = t.importDeclaration([
state.opts.import ? t.importSpecifier(importAs, t.identifier(state.opts.import)) : state.opts.importNamespace ? t.importNamespaceSpecifier(importAs) : t.importDefaultSpecifier(importAs)
], t.stringLiteral(state.opts.module || 'react'));
const [newPath] = path.unshiftContainer('body', importSpecifier);
for (const specifier of newPath.get('specifiers')){
path.scope.registerBinding('module', specifier);
}
}
}
}
}
}
};
}
//# sourceMappingURL=jsx-pragma.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,26 @@
export default function NextPageDisallowReExportAllExports() {
return {
visitor: {
ImportDeclaration (path) {
if ([
'@next/font/local',
'@next/font/google',
'next/font/local',
'next/font/google'
].includes(path.node.source.value)) {
var _path_node_loc, _path_node_loc1;
const err = Object.defineProperty(new SyntaxError(`"next/font" requires SWC although Babel is being used due to a custom babel config being present.\nRead more: https://nextjs.org/docs/messages/babel-font-loader-conflict`), "__NEXT_ERROR_CODE", {
value: "E542",
enumerable: false,
configurable: true
});
err.code = 'BABEL_PARSE_ERROR';
err.loc = ((_path_node_loc = path.node.loc) == null ? void 0 : _path_node_loc.start) ?? ((_path_node_loc1 = path.node.loc) == null ? void 0 : _path_node_loc1.end) ?? path.node.loc;
throw err;
}
}
}
};
}
//# sourceMappingURL=next-font-unsupported.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/build/babel/plugins/next-font-unsupported.ts"],"sourcesContent":["import type { NodePath, types } from 'next/dist/compiled/babel/core'\nimport type { PluginObj } from 'next/dist/compiled/babel/core'\n\nexport default function NextPageDisallowReExportAllExports(): PluginObj<any> {\n return {\n visitor: {\n ImportDeclaration(path: NodePath<types.ImportDeclaration>) {\n if (\n [\n '@next/font/local',\n '@next/font/google',\n 'next/font/local',\n 'next/font/google',\n ].includes(path.node.source.value)\n ) {\n const err = new SyntaxError(\n `\"next/font\" requires SWC although Babel is being used due to a custom babel config being present.\\nRead more: https://nextjs.org/docs/messages/babel-font-loader-conflict`\n )\n ;(err as any).code = 'BABEL_PARSE_ERROR'\n ;(err as any).loc =\n path.node.loc?.start ?? path.node.loc?.end ?? path.node.loc\n throw err\n }\n },\n },\n }\n}\n"],"names":["NextPageDisallowReExportAllExports","visitor","ImportDeclaration","path","includes","node","source","value","err","SyntaxError","code","loc","start","end"],"mappings":"AAGA,eAAe,SAASA;IACtB,OAAO;QACLC,SAAS;YACPC,mBAAkBC,IAAuC;gBACvD,IACE;oBACE;oBACA;oBACA;oBACA;iBACD,CAACC,QAAQ,CAACD,KAAKE,IAAI,CAACC,MAAM,CAACC,KAAK,GACjC;wBAMEJ,gBAAwBA;oBAL1B,MAAMK,MAAM,qBAEX,CAFW,IAAIC,YACd,CAAC,yKAAyK,CAAC,GADjK,qBAAA;+BAAA;oCAAA;sCAAA;oBAEZ;oBACED,IAAYE,IAAI,GAAG;oBACnBF,IAAYG,GAAG,GACfR,EAAAA,iBAAAA,KAAKE,IAAI,CAACM,GAAG,qBAAbR,eAAeS,KAAK,OAAIT,kBAAAA,KAAKE,IAAI,CAACM,GAAG,qBAAbR,gBAAeU,GAAG,KAAIV,KAAKE,IAAI,CAACM,GAAG;oBAC7D,MAAMH;gBACR;YACF;QACF;IACF;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,94 @@
import { types as BabelTypes } from 'next/dist/compiled/babel/core';
const CONFIG_KEY = 'config';
function errorMessage(state, details) {
const pageName = (state.filename || '').split(state.cwd || '').pop() || 'unknown';
return `Invalid page config export found. ${details} in file ${pageName}. See: https://nextjs.org/docs/messages/invalid-page-config`;
}
// config to parsing pageConfig for client bundles
export default function nextPageConfig({ types: t }) {
return {
visitor: {
Program: {
enter (path, state) {
path.traverse({
ExportDeclaration (exportPath, exportState) {
var _exportPath_node_specifiers;
if (BabelTypes.isExportNamedDeclaration(exportPath.node) && ((_exportPath_node_specifiers = exportPath.node.specifiers) == null ? void 0 : _exportPath_node_specifiers.some((specifier)=>{
return (t.isIdentifier(specifier.exported) ? specifier.exported.name : specifier.exported.value) === CONFIG_KEY;
})) && BabelTypes.isStringLiteral(exportPath.node.source)) {
throw Object.defineProperty(new Error(errorMessage(exportState, 'Expected object but got export from')), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
},
ExportNamedDeclaration (exportPath, exportState) {
var _exportPath_node_declaration, _exportPath_scope_getBinding;
if (exportState.bundleDropped || !exportPath.node.declaration && exportPath.node.specifiers.length === 0) {
return;
}
const declarations = [
...((_exportPath_node_declaration = exportPath.node.declaration) == null ? void 0 : _exportPath_node_declaration.declarations) || [],
(_exportPath_scope_getBinding = exportPath.scope.getBinding(CONFIG_KEY)) == null ? void 0 : _exportPath_scope_getBinding.path.node
].filter(Boolean);
for (const specifier of exportPath.node.specifiers){
if ((t.isIdentifier(specifier.exported) ? specifier.exported.name : specifier.exported.value) === CONFIG_KEY) {
// export {} from 'somewhere'
if (BabelTypes.isStringLiteral(exportPath.node.source)) {
throw Object.defineProperty(new Error(errorMessage(exportState, `Expected object but got import`)), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
// import hello from 'world'
// export { hello as config }
} else if (BabelTypes.isIdentifier(specifier.local)) {
var _exportPath_scope_getBinding1;
if (BabelTypes.isImportSpecifier((_exportPath_scope_getBinding1 = exportPath.scope.getBinding(specifier.local.name)) == null ? void 0 : _exportPath_scope_getBinding1.path.node)) {
throw Object.defineProperty(new Error(errorMessage(exportState, `Expected object but got import`)), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
}
}
}
for (const declaration of declarations){
if (!BabelTypes.isIdentifier(declaration.id, {
name: CONFIG_KEY
})) {
continue;
}
let { init } = declaration;
if (BabelTypes.isTSAsExpression(init)) {
init = init.expression;
}
if (!BabelTypes.isObjectExpression(init)) {
const got = init ? init.type : 'undefined';
throw Object.defineProperty(new Error(errorMessage(exportState, `Expected object but got ${got}`)), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
for (const prop of init.properties){
if (BabelTypes.isSpreadElement(prop)) {
throw Object.defineProperty(new Error(errorMessage(exportState, `Property spread is not allowed`)), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
}
}
}
}, state);
}
}
}
};
}
//# sourceMappingURL=next-page-config.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
export default function NextPageDisallowReExportAllExports() {
return {
visitor: {
ExportAllDeclaration (path) {
var _path_node_loc, _path_node_loc1;
const err = Object.defineProperty(new SyntaxError(`Using \`export * from '...'\` in a page is disallowed. Please use \`export { default } from '...'\` instead.\n` + `Read more: https://nextjs.org/docs/messages/export-all-in-page`), "__NEXT_ERROR_CODE", {
value: "E555",
enumerable: false,
configurable: true
});
err.code = 'BABEL_PARSE_ERROR';
err.loc = ((_path_node_loc = path.node.loc) == null ? void 0 : _path_node_loc.start) ?? ((_path_node_loc1 = path.node.loc) == null ? void 0 : _path_node_loc1.end) ?? path.node.loc;
throw err;
}
}
};
}
//# sourceMappingURL=next-page-disallow-re-export-all-exports.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/build/babel/plugins/next-page-disallow-re-export-all-exports.ts"],"sourcesContent":["import type { NodePath, types } from 'next/dist/compiled/babel/core'\nimport type { PluginObj } from 'next/dist/compiled/babel/core'\n\nexport default function NextPageDisallowReExportAllExports(): PluginObj<any> {\n return {\n visitor: {\n ExportAllDeclaration(path: NodePath<types.ExportAllDeclaration>) {\n const err = new SyntaxError(\n `Using \\`export * from '...'\\` in a page is disallowed. Please use \\`export { default } from '...'\\` instead.\\n` +\n `Read more: https://nextjs.org/docs/messages/export-all-in-page`\n )\n ;(err as any).code = 'BABEL_PARSE_ERROR'\n ;(err as any).loc =\n path.node.loc?.start ?? path.node.loc?.end ?? path.node.loc\n throw err\n },\n },\n }\n}\n"],"names":["NextPageDisallowReExportAllExports","visitor","ExportAllDeclaration","path","err","SyntaxError","code","loc","node","start","end"],"mappings":"AAGA,eAAe,SAASA;IACtB,OAAO;QACLC,SAAS;YACPC,sBAAqBC,IAA0C;oBAO3DA,gBAAwBA;gBAN1B,MAAMC,MAAM,qBAGX,CAHW,IAAIC,YACd,CAAC,8GAA8G,CAAC,GAC9G,CAAC,8DAA8D,CAAC,GAFxD,qBAAA;2BAAA;gCAAA;kCAAA;gBAGZ;gBACED,IAAYE,IAAI,GAAG;gBACnBF,IAAYG,GAAG,GACfJ,EAAAA,iBAAAA,KAAKK,IAAI,CAACD,GAAG,qBAAbJ,eAAeM,KAAK,OAAIN,kBAAAA,KAAKK,IAAI,CAACD,GAAG,qBAAbJ,gBAAeO,GAAG,KAAIP,KAAKK,IAAI,CAACD,GAAG;gBAC7D,MAAMH;YACR;QACF;IACF;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,315 @@
import { SERVER_PROPS_SSG_CONFLICT } from '../../../lib/constants';
import { SERVER_PROPS_ID, STATIC_PROPS_ID } from '../../../shared/lib/constants';
export const EXPORT_NAME_GET_STATIC_PROPS = 'getStaticProps';
export const EXPORT_NAME_GET_STATIC_PATHS = 'getStaticPaths';
export const EXPORT_NAME_GET_SERVER_PROPS = 'getServerSideProps';
const ssgExports = new Set([
EXPORT_NAME_GET_STATIC_PROPS,
EXPORT_NAME_GET_STATIC_PATHS,
EXPORT_NAME_GET_SERVER_PROPS,
// legacy methods added so build doesn't fail from importing
// server-side only methods
`unstable_getStaticProps`,
`unstable_getStaticPaths`,
`unstable_getServerProps`,
`unstable_getServerSideProps`
]);
function decorateSsgExport(t, path, state) {
const gsspName = state.isPrerender ? STATIC_PROPS_ID : SERVER_PROPS_ID;
const gsspId = t.identifier(gsspName);
const addGsspExport = (exportPath)=>{
if (state.done) {
return;
}
state.done = true;
const [pageCompPath] = exportPath.replaceWithMultiple([
t.exportNamedDeclaration(t.variableDeclaration(// We use 'var' instead of 'let' or 'const' for ES5 support. Since
// this runs in `Program#exit`, no ES2015 transforms (preset env)
// will be ran against this code.
'var', [
t.variableDeclarator(gsspId, t.booleanLiteral(true))
]), [
t.exportSpecifier(gsspId, gsspId)
]),
exportPath.node
]);
exportPath.scope.registerDeclaration(pageCompPath);
};
path.traverse({
ExportDefaultDeclaration (exportDefaultPath) {
addGsspExport(exportDefaultPath);
},
ExportNamedDeclaration (exportNamedPath) {
addGsspExport(exportNamedPath);
}
});
}
const isDataIdentifier = (name, state)=>{
if (ssgExports.has(name)) {
if (name === EXPORT_NAME_GET_SERVER_PROPS) {
if (state.isPrerender) {
throw Object.defineProperty(new Error(SERVER_PROPS_SSG_CONFLICT), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
state.isServerProps = true;
} else {
if (state.isServerProps) {
throw Object.defineProperty(new Error(SERVER_PROPS_SSG_CONFLICT), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
state.isPrerender = true;
}
return true;
}
return false;
};
export default function nextTransformSsg({ types: t }) {
function getIdentifier(path) {
const parentPath = path.parentPath;
if (parentPath.type === 'VariableDeclarator') {
const pp = parentPath;
const name = pp.get('id');
return name.node.type === 'Identifier' ? name : null;
}
if (parentPath.type === 'AssignmentExpression') {
const pp = parentPath;
const name = pp.get('left');
return name.node.type === 'Identifier' ? name : null;
}
if (path.node.type === 'ArrowFunctionExpression') {
return null;
}
return path.node.id && path.node.id.type === 'Identifier' ? path.get('id') : null;
}
function isIdentifierReferenced(ident) {
const b = ident.scope.getBinding(ident.node.name);
if (b == null ? void 0 : b.referenced) {
// Functions can reference themselves, so we need to check if there's a
// binding outside the function scope or not.
if (b.path.type === 'FunctionDeclaration') {
return !b.constantViolations.concat(b.referencePaths)// Check that every reference is contained within the function:
.every((ref)=>ref.findParent((p)=>p === b.path));
}
return true;
}
return false;
}
function markFunction(path, state) {
const ident = getIdentifier(path);
if ((ident == null ? void 0 : ident.node) && isIdentifierReferenced(ident)) {
state.refs.add(ident);
}
}
function markImport(path, state) {
const local = path.get('local');
if (isIdentifierReferenced(local)) {
state.refs.add(local);
}
}
return {
visitor: {
Program: {
enter (path, state) {
state.refs = new Set();
state.isPrerender = false;
state.isServerProps = false;
state.done = false;
path.traverse({
VariableDeclarator (variablePath, variableState) {
if (variablePath.node.id.type === 'Identifier') {
const local = variablePath.get('id');
if (isIdentifierReferenced(local)) {
variableState.refs.add(local);
}
} else if (variablePath.node.id.type === 'ObjectPattern') {
const pattern = variablePath.get('id');
const properties = pattern.get('properties');
properties.forEach((p)=>{
const local = p.get(p.node.type === 'ObjectProperty' ? 'value' : p.node.type === 'RestElement' ? 'argument' : function() {
throw Object.defineProperty(new Error('invariant'), "__NEXT_ERROR_CODE", {
value: "E400",
enumerable: false,
configurable: true
});
}());
if (isIdentifierReferenced(local)) {
variableState.refs.add(local);
}
});
} else if (variablePath.node.id.type === 'ArrayPattern') {
const pattern = variablePath.get('id');
const elements = pattern.get('elements');
elements.forEach((e)=>{
var _e_node, _e_node1;
let local;
if (((_e_node = e.node) == null ? void 0 : _e_node.type) === 'Identifier') {
local = e;
} else if (((_e_node1 = e.node) == null ? void 0 : _e_node1.type) === 'RestElement') {
local = e.get('argument');
} else {
return;
}
if (isIdentifierReferenced(local)) {
variableState.refs.add(local);
}
});
}
},
FunctionDeclaration: markFunction,
FunctionExpression: markFunction,
ArrowFunctionExpression: markFunction,
ImportSpecifier: markImport,
ImportDefaultSpecifier: markImport,
ImportNamespaceSpecifier: markImport,
ExportNamedDeclaration (exportNamedPath, exportNamedState) {
const specifiers = exportNamedPath.get('specifiers');
if (specifiers.length) {
specifiers.forEach((s)=>{
if (isDataIdentifier(t.isIdentifier(s.node.exported) ? s.node.exported.name : s.node.exported.value, exportNamedState)) {
s.remove();
}
});
if (exportNamedPath.node.specifiers.length < 1) {
exportNamedPath.remove();
}
return;
}
const decl = exportNamedPath.get('declaration');
if (decl == null || decl.node == null) {
return;
}
switch(decl.node.type){
case 'FunctionDeclaration':
{
const name = decl.node.id.name;
if (isDataIdentifier(name, exportNamedState)) {
exportNamedPath.remove();
}
break;
}
case 'VariableDeclaration':
{
const inner = decl.get('declarations');
inner.forEach((d)=>{
if (d.node.id.type !== 'Identifier') {
return;
}
const name = d.node.id.name;
if (isDataIdentifier(name, exportNamedState)) {
d.remove();
}
});
break;
}
default:
{
break;
}
}
}
}, state);
if (!state.isPrerender && !state.isServerProps) {
return;
}
const refs = state.refs;
let count;
function sweepFunction(sweepPath) {
const ident = getIdentifier(sweepPath);
if ((ident == null ? void 0 : ident.node) && refs.has(ident) && !isIdentifierReferenced(ident)) {
++count;
if (t.isAssignmentExpression(sweepPath.parentPath.node) || t.isVariableDeclarator(sweepPath.parentPath.node)) {
sweepPath.parentPath.remove();
} else {
sweepPath.remove();
}
}
}
function sweepImport(sweepPath) {
const local = sweepPath.get('local');
if (refs.has(local) && !isIdentifierReferenced(local)) {
++count;
sweepPath.remove();
if (sweepPath.parent.specifiers.length === 0) {
sweepPath.parentPath.remove();
}
}
}
do {
;
path.scope.crawl();
count = 0;
path.traverse({
// eslint-disable-next-line no-loop-func
VariableDeclarator (variablePath) {
if (variablePath.node.id.type === 'Identifier') {
const local = variablePath.get('id');
if (refs.has(local) && !isIdentifierReferenced(local)) {
++count;
variablePath.remove();
}
} else if (variablePath.node.id.type === 'ObjectPattern') {
const pattern = variablePath.get('id');
const beforeCount = count;
const properties = pattern.get('properties');
properties.forEach((p)=>{
const local = p.get(p.node.type === 'ObjectProperty' ? 'value' : p.node.type === 'RestElement' ? 'argument' : function() {
throw Object.defineProperty(new Error('invariant'), "__NEXT_ERROR_CODE", {
value: "E400",
enumerable: false,
configurable: true
});
}());
if (refs.has(local) && !isIdentifierReferenced(local)) {
++count;
p.remove();
}
});
if (beforeCount !== count && pattern.get('properties').length < 1) {
variablePath.remove();
}
} else if (variablePath.node.id.type === 'ArrayPattern') {
const pattern = variablePath.get('id');
const beforeCount = count;
const elements = pattern.get('elements');
elements.forEach((e)=>{
var _e_node, _e_node1;
let local;
if (((_e_node = e.node) == null ? void 0 : _e_node.type) === 'Identifier') {
local = e;
} else if (((_e_node1 = e.node) == null ? void 0 : _e_node1.type) === 'RestElement') {
local = e.get('argument');
} else {
return;
}
if (refs.has(local) && !isIdentifierReferenced(local)) {
++count;
e.remove();
}
});
if (beforeCount !== count && pattern.get('elements').length < 1) {
variablePath.remove();
}
}
},
FunctionDeclaration: sweepFunction,
FunctionExpression: sweepFunction,
ArrowFunctionExpression: sweepFunction,
ImportSpecifier: sweepImport,
ImportDefaultSpecifier: sweepImport,
ImportNamespaceSpecifier: sweepImport
});
}while (count);
decorateSsgExport(t, path, state);
}
}
}
};
}
//# sourceMappingURL=next-ssg-transform.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,50 @@
// matches any hook-like (the default)
const isHook = /^use[A-Z]/;
// matches only built-in hooks provided by React et al
const isBuiltInHook = /^use(Callback|Context|DebugValue|Effect|ImperativeHandle|LayoutEffect|Memo|Reducer|Ref|State)$/;
export default function({ types: t }) {
const visitor = {
CallExpression (path, state) {
const onlyBuiltIns = state.opts.onlyBuiltIns;
// if specified, options.lib is a list of libraries that provide hook functions
const libs = state.opts.lib && (state.opts.lib === true ? [
'react',
'preact/hooks'
] : [].concat(state.opts.lib));
// skip function calls that are not the init of a variable declaration:
if (!t.isVariableDeclarator(path.parent)) return;
// skip function calls where the return value is not Array-destructured:
if (!t.isArrayPattern(path.parent.id)) return;
// name of the (hook) function being called:
const hookName = path.node.callee.name;
if (libs) {
const binding = path.scope.getBinding(hookName);
// not an import
if (!binding || binding.kind !== 'module') return;
const specifier = binding.path.parent.source.value;
// not a match
if (!libs.some((lib)=>lib === specifier)) return;
}
// only match function calls with names that look like a hook
if (!(onlyBuiltIns ? isBuiltInHook : isHook).test(hookName)) return;
path.parent.id = t.objectPattern(path.parent.id.elements.reduce((patterns, element, i)=>{
if (element === null) {
return patterns;
}
return patterns.concat(t.objectProperty(t.numericLiteral(i), // TODO: fix this
element));
}, []));
}
};
return {
name: 'optimize-hook-destructuring',
visitor: {
// this is a workaround to run before preset-env destroys destructured assignments
Program (path, state) {
path.traverse(visitor, state);
}
}
};
}
//# sourceMappingURL=optimize-hook-destructuring.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/build/babel/plugins/optimize-hook-destructuring.ts"],"sourcesContent":["import type {\n NodePath,\n types as BabelTypes,\n} from 'next/dist/compiled/babel/core'\nimport type { PluginObj } from 'next/dist/compiled/babel/core'\n// matches any hook-like (the default)\nconst isHook = /^use[A-Z]/\n\n// matches only built-in hooks provided by React et al\nconst isBuiltInHook =\n /^use(Callback|Context|DebugValue|Effect|ImperativeHandle|LayoutEffect|Memo|Reducer|Ref|State)$/\n\nexport default function ({\n types: t,\n}: {\n types: typeof BabelTypes\n}): PluginObj<any> {\n const visitor = {\n CallExpression(path: NodePath<BabelTypes.CallExpression>, state: any) {\n const onlyBuiltIns = state.opts.onlyBuiltIns\n\n // if specified, options.lib is a list of libraries that provide hook functions\n const libs =\n state.opts.lib &&\n (state.opts.lib === true\n ? ['react', 'preact/hooks']\n : [].concat(state.opts.lib))\n\n // skip function calls that are not the init of a variable declaration:\n if (!t.isVariableDeclarator(path.parent)) return\n\n // skip function calls where the return value is not Array-destructured:\n if (!t.isArrayPattern(path.parent.id)) return\n\n // name of the (hook) function being called:\n const hookName = (path.node.callee as BabelTypes.Identifier).name\n\n if (libs) {\n const binding = path.scope.getBinding(hookName)\n // not an import\n if (!binding || binding.kind !== 'module') return\n\n const specifier = (binding.path.parent as BabelTypes.ImportDeclaration)\n .source.value\n // not a match\n if (!libs.some((lib: any) => lib === specifier)) return\n }\n\n // only match function calls with names that look like a hook\n if (!(onlyBuiltIns ? isBuiltInHook : isHook).test(hookName)) return\n\n path.parent.id = t.objectPattern(\n path.parent.id.elements.reduce<Array<BabelTypes.ObjectProperty>>(\n (patterns, element, i) => {\n if (element === null) {\n return patterns\n }\n\n return patterns.concat(\n t.objectProperty(\n t.numericLiteral(i),\n // TODO: fix this\n element as Exclude<\n typeof element,\n BabelTypes.MemberExpression | BabelTypes.TSParameterProperty\n >\n )\n )\n },\n []\n )\n )\n },\n }\n\n return {\n name: 'optimize-hook-destructuring',\n visitor: {\n // this is a workaround to run before preset-env destroys destructured assignments\n Program(path, state) {\n path.traverse(visitor, state)\n },\n },\n }\n}\n"],"names":["isHook","isBuiltInHook","types","t","visitor","CallExpression","path","state","onlyBuiltIns","opts","libs","lib","concat","isVariableDeclarator","parent","isArrayPattern","id","hookName","node","callee","name","binding","scope","getBinding","kind","specifier","source","value","some","test","objectPattern","elements","reduce","patterns","element","i","objectProperty","numericLiteral","Program","traverse"],"mappings":"AAKA,sCAAsC;AACtC,MAAMA,SAAS;AAEf,sDAAsD;AACtD,MAAMC,gBACJ;AAEF,eAAe,SAAU,EACvBC,OAAOC,CAAC,EAGT;IACC,MAAMC,UAAU;QACdC,gBAAeC,IAAyC,EAAEC,KAAU;YAClE,MAAMC,eAAeD,MAAME,IAAI,CAACD,YAAY;YAE5C,+EAA+E;YAC/E,MAAME,OACJH,MAAME,IAAI,CAACE,GAAG,IACbJ,CAAAA,MAAME,IAAI,CAACE,GAAG,KAAK,OAChB;gBAAC;gBAAS;aAAe,GACzB,EAAE,CAACC,MAAM,CAACL,MAAME,IAAI,CAACE,GAAG,CAAA;YAE9B,uEAAuE;YACvE,IAAI,CAACR,EAAEU,oBAAoB,CAACP,KAAKQ,MAAM,GAAG;YAE1C,wEAAwE;YACxE,IAAI,CAACX,EAAEY,cAAc,CAACT,KAAKQ,MAAM,CAACE,EAAE,GAAG;YAEvC,4CAA4C;YAC5C,MAAMC,WAAW,AAACX,KAAKY,IAAI,CAACC,MAAM,CAA2BC,IAAI;YAEjE,IAAIV,MAAM;gBACR,MAAMW,UAAUf,KAAKgB,KAAK,CAACC,UAAU,CAACN;gBACtC,gBAAgB;gBAChB,IAAI,CAACI,WAAWA,QAAQG,IAAI,KAAK,UAAU;gBAE3C,MAAMC,YAAY,AAACJ,QAAQf,IAAI,CAACQ,MAAM,CACnCY,MAAM,CAACC,KAAK;gBACf,cAAc;gBACd,IAAI,CAACjB,KAAKkB,IAAI,CAAC,CAACjB,MAAaA,QAAQc,YAAY;YACnD;YAEA,6DAA6D;YAC7D,IAAI,CAAC,AAACjB,CAAAA,eAAeP,gBAAgBD,MAAK,EAAG6B,IAAI,CAACZ,WAAW;YAE7DX,KAAKQ,MAAM,CAACE,EAAE,GAAGb,EAAE2B,aAAa,CAC9BxB,KAAKQ,MAAM,CAACE,EAAE,CAACe,QAAQ,CAACC,MAAM,CAC5B,CAACC,UAAUC,SAASC;gBAClB,IAAID,YAAY,MAAM;oBACpB,OAAOD;gBACT;gBAEA,OAAOA,SAASrB,MAAM,CACpBT,EAAEiC,cAAc,CACdjC,EAAEkC,cAAc,CAACF,IACjB,iBAAiB;gBACjBD;YAMN,GACA,EAAE;QAGR;IACF;IAEA,OAAO;QACLd,MAAM;QACNhB,SAAS;YACP,kFAAkF;YAClFkC,SAAQhC,IAAI,EAAEC,KAAK;gBACjBD,KAAKiC,QAAQ,CAACnC,SAASG;YACzB;QACF;IACF;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,135 @@
/**
COPYRIGHT (c) 2017-present James Kyle <me@thejameskyle.com>
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWAR
*/ // This file is https://github.com/jamiebuilds/react-loadable/blob/master/src/babel.js
// - Modified to also look for `next/dynamic`
// - Modified to put `webpack` and `modules` under `loadableGenerated` to be
// backwards compatible with next/dynamic which has a `modules` key
// - Modified to support `dynamic(import('something'))` and
// `dynamic(import('something'), options)
// - Removed `Loadable.Map` support, `next/dynamic` uses overloaded arguments
// instead of a separate API
import { relative as relativePath } from 'path';
export default function({ types: t }) {
return {
visitor: {
ImportDeclaration (path, state) {
let source = path.node.source.value;
if (source !== 'next/dynamic') return;
let defaultSpecifier = path.get('specifiers').find((specifier)=>{
return specifier.isImportDefaultSpecifier();
});
if (!defaultSpecifier) return;
const bindingName = defaultSpecifier.node.local.name;
const binding = path.scope.getBinding(bindingName);
if (!binding) {
return;
}
binding.referencePaths.forEach((refPath)=>{
var _state_file_opts_caller, _state_file_opts_caller1;
let callExpression = refPath.parentPath;
if (!(callExpression == null ? void 0 : callExpression.isCallExpression())) return;
let args = callExpression.get('arguments');
if (args.length > 2) {
throw callExpression.buildCodeFrameError('next/dynamic only accepts 2 arguments');
}
if (!args[0]) {
return;
}
let loader;
let options;
if (args[0].isObjectExpression()) {
options = args[0];
} else {
if (!args[1]) {
callExpression.node.arguments.push(t.objectExpression([]));
}
// This is needed as the code is modified above
args = callExpression.get('arguments');
loader = args[0];
options = args[1];
}
if (!options.isObjectExpression()) return;
const options_ = options;
let properties = options_.get('properties');
let propertiesMap = {};
properties.forEach((property)=>{
const key = property.get('key');
propertiesMap[key.node.name] = property;
});
if (propertiesMap.loadableGenerated) {
return;
}
if (propertiesMap.loader) {
loader = propertiesMap.loader.get('value');
}
if (propertiesMap.modules) {
loader = propertiesMap.modules.get('value');
}
if (!loader || Array.isArray(loader)) {
return;
}
const dynamicImports = [];
const dynamicKeys = [];
if (propertiesMap.ssr) {
const ssr = propertiesMap.ssr.get('value');
const nodePath = Array.isArray(ssr) ? undefined : ssr;
if (nodePath) {
var _state_file_opts_caller2;
const nonSSR = nodePath.node.type === 'BooleanLiteral' && nodePath.node.value === false;
// If `ssr` is set to `false`, erase the loader for server side
if (nonSSR && loader && ((_state_file_opts_caller2 = state.file.opts.caller) == null ? void 0 : _state_file_opts_caller2.isServer)) {
loader.replaceWith(t.arrowFunctionExpression([], t.nullLiteral(), true));
}
}
}
loader.traverse({
Import (importPath) {
var _state_file_opts_caller;
const importArguments = importPath.parentPath.get('arguments');
if (!Array.isArray(importArguments)) return;
const node = importArguments[0].node;
dynamicImports.push(node);
dynamicKeys.push(t.binaryExpression('+', t.stringLiteral((((_state_file_opts_caller = state.file.opts.caller) == null ? void 0 : _state_file_opts_caller.srcDir) ? relativePath(state.file.opts.caller.srcDir, state.file.opts.filename) : state.file.opts.filename) + ' -> '), node));
}
});
if (!dynamicImports.length) return;
options.node.properties.push(t.objectProperty(t.identifier('loadableGenerated'), t.objectExpression(((_state_file_opts_caller = state.file.opts.caller) == null ? void 0 : _state_file_opts_caller.isDev) || ((_state_file_opts_caller1 = state.file.opts.caller) == null ? void 0 : _state_file_opts_caller1.isServer) ? [
t.objectProperty(t.identifier('modules'), t.arrayExpression(dynamicKeys))
] : [
t.objectProperty(t.identifier('webpack'), t.arrowFunctionExpression([], t.arrayExpression(dynamicImports.map((dynamicImport)=>{
return t.callExpression(t.memberExpression(t.identifier('require'), t.identifier('resolveWeak')), [
dynamicImport
]);
}))))
])));
// Turns `dynamic(import('something'))` into `dynamic(() => import('something'))` for backwards compat.
// This is the replicate the behavior in versions below Next.js 7 where we magically handled not executing the `import()` too.
// We'll deprecate this behavior and provide a codemod for it in 7.1.
if (loader.isCallExpression()) {
const arrowFunction = t.arrowFunctionExpression([], loader.node);
loader.replaceWith(arrowFunction);
}
});
}
}
};
}
//# sourceMappingURL=react-loadable-plugin.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,240 @@
import { dirname } from 'path';
const isLoadIntentTest = process.env.NODE_ENV === 'test';
const isLoadIntentDevelopment = process.env.NODE_ENV === 'development';
// Resolve styled-jsx plugins
function styledJsxOptions(options) {
options = options || {};
options.styleModule = 'styled-jsx/style';
if (!Array.isArray(options.plugins)) {
return options;
}
options.plugins = options.plugins.map((plugin)=>{
if (Array.isArray(plugin)) {
const [name, pluginOptions] = plugin;
return [
require.resolve(name),
pluginOptions
];
}
return require.resolve(plugin);
});
return options;
}
// Taken from https://github.com/babel/babel/commit/d60c5e1736543a6eac4b549553e107a9ba967051#diff-b4beead8ad9195361b4537601cc22532R158
function supportsStaticESM(caller) {
return !!(caller == null ? void 0 : caller.supportsStaticESM);
}
/**
* HACK: A drop-in replacement for `@babel/preset-typescript` that only enables
* `@babel/plugin-syntax-typescript` and does not transform the typescript.
*
* This is used for standalone mode, where Babel is being used alongside SWC
* (i.e. Turbopack or with React Compiler on webpack).
*
* This should match the logic/behavior here:
* https://github.com/babel/babel/blob/7f57d3a2e97b7e2800fb82cff9284a3591377971/packages/babel-preset-typescript/src/index.ts#L63
*/ function presetTypescriptSyntaxOnly(_api, options) {
const { allExtensions, ignoreExtensions, ...restOptions } = options;
const disableExtensionDetect = allExtensions || ignoreExtensions;
function getPlugins(isTSX, disallowAmbiguousJSXLike) {
return [
[
require('next/dist/compiled/babel/plugin-syntax-typescript'),
{
isTSX,
disallowAmbiguousJSXLike,
...restOptions
}
]
];
}
return {
plugins: [],
overrides: disableExtensionDetect ? [
{
plugins: getPlugins(options.isTSX, options.disallowAmbiguousJSXLike)
}
] : // Babel is being called with a filename.
[
{
test: /\.ts$/,
plugins: getPlugins(false, false)
},
{
test: /\.mts$/,
sourceType: 'module',
plugins: getPlugins(false, true)
},
{
test: /\.cts$/,
sourceType: 'unambiguous',
plugins: getPlugins(false, true)
},
{
test: /\.tsx$/,
plugins: getPlugins(true, false)
}
]
};
}
export default ((api, options = {})=>{
var _options_presetreact, _options_presetreact1;
const isStandalone = api.caller(// NOTE: `transformMode` may be undefined if the user configured `babel-loader` themselves. In
// this case, we should assume we're in 'default' mode.
(caller)=>!!caller && caller.transformMode === 'standalone');
const isServer = api.caller((caller)=>!!caller && caller.isServer);
// syntax plugins that are used in both standalone and default modes
const sharedSyntaxPlugins = [
require('next/dist/compiled/babel/plugin-syntax-dynamic-import'),
[
require('next/dist/compiled/babel/plugin-syntax-import-attributes'),
{
deprecatedAssertSyntax: true
}
],
(isStandalone || isServer) && require('next/dist/compiled/babel/plugin-syntax-bigint')
].filter(Boolean);
if (isStandalone) {
// Just enable a few syntax plugins, we'll let SWC handle any of the downleveling or
// next.js-specific transforms.
return {
sourceType: 'unambiguous',
presets: [
[
presetTypescriptSyntaxOnly,
options['syntax-typescript'] ?? options['preset-typescript'] ?? {}
]
],
plugins: [
require('next/dist/compiled/babel/plugin-syntax-jsx'),
...sharedSyntaxPlugins
]
};
}
const supportsESM = api.caller(supportsStaticESM);
const isCallerDevelopment = api.caller((caller)=>caller == null ? void 0 : caller.isDev);
// Look at external intent if used without a caller (e.g. via Jest):
const isTest = isCallerDevelopment == null && isLoadIntentTest;
// Look at external intent if used without a caller (e.g. Storybook):
const isDevelopment = isCallerDevelopment === true || isCallerDevelopment == null && isLoadIntentDevelopment;
// Default to production mode if not `test` nor `development`:
const isProduction = !(isTest || isDevelopment);
const isBabelLoader = api.caller((caller)=>!!caller && (caller.name === 'babel-loader' || caller.name === 'next-babel-turbo-loader'));
const useJsxRuntime = ((_options_presetreact = options['preset-react']) == null ? void 0 : _options_presetreact.runtime) === 'automatic' || Boolean(api.caller((caller)=>!!caller && caller.hasJsxRuntime)) && ((_options_presetreact1 = options['preset-react']) == null ? void 0 : _options_presetreact1.runtime) !== 'classic';
const presetEnvConfig = {
// In the test environment `modules` is often needed to be set to true, babel figures that out by itself using the `'auto'` option
// In production/development this option is set to `false` so that webpack can handle import/export with tree-shaking
modules: 'auto',
exclude: [
'transform-typeof-symbol'
],
...options['preset-env']
};
// When transpiling for the server or tests, target the current Node version
// if not explicitly specified:
if ((isServer || isTest) && (!presetEnvConfig.targets || !(typeof presetEnvConfig.targets === 'object' && 'node' in presetEnvConfig.targets))) {
presetEnvConfig.targets = {
// Targets the current process' version of Node. This requires apps be
// built and deployed on the same version of Node.
// This is the same as using "current" but explicit
node: process.versions.node
};
}
const runtimeModuleName = isBabelLoader ? 'next/dist/compiled/@babel/runtime' : null;
return {
sourceType: 'unambiguous',
presets: [
[
require('next/dist/compiled/babel/preset-env'),
presetEnvConfig
],
[
require('next/dist/compiled/babel/preset-react'),
{
// This adds @babel/plugin-transform-react-jsx-source and
// @babel/plugin-transform-react-jsx-self automatically in development
development: isDevelopment || isTest,
...useJsxRuntime ? {
runtime: 'automatic'
} : {
pragma: '__jsx'
},
...options['preset-react']
}
],
[
require('next/dist/compiled/babel/preset-typescript'),
{
allowNamespaces: true,
...options['preset-typescript'] || options['syntax-typescript']
}
]
],
plugins: [
...sharedSyntaxPlugins,
!useJsxRuntime && [
require('./plugins/jsx-pragma'),
{
// This produces the following injected import for modules containing JSX:
// import React from 'react';
// var __jsx = React.createElement;
module: 'react',
importAs: 'React',
pragma: '__jsx',
property: 'createElement'
}
],
[
require('./plugins/optimize-hook-destructuring'),
{
// only optimize hook functions imported from React/Preact
lib: true
}
],
require('./plugins/react-loadable-plugin'),
// only enable this plugin if custom config for it was provided
// otherwise we will only enable it if their browserslist triggers
// preset-env to pull it in
options['class-properties'] && [
require('next/dist/compiled/babel/plugin-proposal-class-properties'),
options['class-properties'] || {}
],
[
require('next/dist/compiled/babel/plugin-proposal-object-rest-spread'),
{
useBuiltIns: true
}
],
!isServer && [
require('next/dist/compiled/babel/plugin-transform-runtime'),
{
corejs: false,
helpers: true,
regenerator: true,
useESModules: supportsESM && presetEnvConfig.modules !== 'commonjs',
absoluteRuntime: runtimeModuleName != null ? dirname(require.resolve(`${runtimeModuleName}/package.json`)) : undefined,
// regenerator needs `moduleName` to be set in addition to
// `absoluteRuntime`.
moduleName: runtimeModuleName,
...options['transform-runtime']
}
],
[
isTest && options['styled-jsx'] && options['styled-jsx']['babel-test'] ? require('styled-jsx/babel-test') : require('styled-jsx/babel'),
styledJsxOptions(options['styled-jsx'])
],
isProduction && [
require('next/dist/compiled/babel/plugin-transform-react-remove-prop-types'),
{
removeImport: true
}
],
// Always compile numeric separator because the resulting number is
// smaller.
require('next/dist/compiled/babel/plugin-proposal-numeric-separator'),
require('next/dist/compiled/babel/plugin-proposal-export-namespace-from')
].filter(Boolean)
};
});
//# sourceMappingURL=preset.js.map

File diff suppressed because one or more lines are too long