94 lines
6.0 KiB
JavaScript
94 lines
6.0 KiB
JavaScript
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
|