Skip to content

Instantly share code, notes, and snippets.

@nodkz
Created August 4, 2022 19:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nodkz/51b37fd1af3c1e2d758aa56ea4e7fd62 to your computer and use it in GitHub Desktop.
Save nodkz/51b37fd1af3c1e2d758aa56ea4e7fd62 to your computer and use it in GitHub Desktop.
Pages map generation for @module-federation/nextjs-mf
import fg from 'fast-glob';
/**
* From provided ROOT_DIR `scan` pages directory
* and return list of user defined pages
* (except special ones, like _app, _document, _error)
*/
export function getNextPages(cwd: string) {
// scan all files in pages folder except pages/api
let pageList = fg.sync('pages/**/*.{ts,tsx,js,jsx}', {
cwd,
onlyFiles: true,
ignore: ['pages/api/**'],
});
// remove specific nextjs pages
const exclude = [
/^pages\/_app\..*/, // _app.tsx
/^pages\/_document\..*/, // _document.tsx
/^pages\/_error\..*/, // _error.tsx
/^pages\/404\..*/, // 404.tsx
/^pages\/500\..*/, // 500.tsx
/^pages\/\[\.\.\..*\]\..*/, // [...federationPage].tsx
];
pageList = pageList.filter((page) => {
return !exclude.some((r) => r.test(page));
});
return pageList;
}
export function removeExtension(item: string) {
return item.replace(/\.(ts|tsx|js|jsx)$/, '');
}
/**
* Create MF map from list of NextJS pages
*
* From
* ['pages/index.tsx', 'pages/storage/[...slug].tsx', 'pages/storage/index.tsx']
* Getting the following map
* {
* '/': './pages/index',
* '/storage/*': './pages/storage/[...slug]',
* '/storage': './pages/storage/index'
* }
*/
export function preparePageMap(pages: string[]) {
const result = {} as Record<string, string>;
pages.forEach((pageWithExtension) => {
const page = removeExtension(pageWithExtension);
let key = '/' + page.replace(/\[\.\.\.[^\]]+\]/gi, '*').replace(/\[([^\]]+)\]/gi, ':$1');
key = key.replace(/^\/pages\//, '/').replace(/\/index$/, '') || '/';
result[key] = `./${page}`;
});
return result;
}
import type { LoaderContext } from 'webpack';
import { getNextPages, preparePageMap } from '../utils/getNextPages';
export default function preparePagesMapLoader(this: LoaderContext<{}>, content: any) {
// this.addContextDependency(`${this.rootContext}/src/pages`);
const pages = getNextPages(`${this.rootContext}/src`);
const pageMap = preparePageMap(pages);
const result = `module.exports = {
default: ${JSON.stringify(pageMap)},
};`;
this.callback(null, result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment