Next.js Codebase Analysis <> create-next-app <> create-app.ts explained — Part 1.19
In the previous article, I provided insights about ternary operation and a type used in create-app.ts
Let’s understand more lines of code from create-app.ts
// if you have passed --example in your CLI to create-next-app
// this example flag becomes true
if (example) {
let repoUrl: URL | undefined
// constructs a url
// You can read more about it here
// https://nodejs.org/api/url.html
try {
repoUrl = new URL(example)
} catch (error: unknown) {
// This block is straight forward
const err = error as Error & { code: string | undefined }
if (err.code !== 'ERR_INVALID_URL') {
console.error(error)
process.exit(1)
}
}
if (repoUrl) {
// Now it makes sense why an URL object is created
// to gain access to help functions such origin like below
// Worth noting this is how URLs should be validated
if (repoUrl.origin !== 'https://github.com') {
console.error(
`Invalid URL: ${red(
`"${example}"`
)}. Only GitHub repositories are supported. Please use a GitHub URL and try again.`
)
process.exit(1)
}
// repoInfo is variable declared at the beginning of function
// createApp.
// I am interested to find out more about getRepoInfo
// Without looking at the function definition
// It is obvious that it gets the repository information
// Looking at function names, you should be able to tell what it does
// otherwise, you are naming them wrong
repoInfo = await getRepoInfo(repoUrl, examplePath)
getRepoInfo
export async function getRepoInfo(
url: URL,
examplePath?: string
): Promise<RepoInfo | undefined> {
const [, username, name, t, _branch, ...file] = url.pathname.split('/')
const filePath = examplePath ? examplePath.replace(/^\//, '') : file.join('/')
if (
// Support repos whose entire purpose is to be a Next.js example, e.g.
// https://github.com/:username/:my-cool-nextjs-example-repo-name.
t === undefined ||
// Support GitHub URL that ends with a trailing slash, e.g.
// https://github.com/:username/:my-cool-nextjs-example-repo-name/
// In this case "t" will be an empty string while the next part "_branch" will be undefined
(t === '' && _branch === undefined)
) {
try {
const infoResponse = await fetch(
`https://api.github.com/repos/${username}/${name}`
)
if (infoResponse.status !== 200) {
return
}
const info = await infoResponse.json()
return { username, name, branch: info['default_branch'], filePath }
} catch {
return
}
}
// If examplePath is available, the branch name takes the entire path
const branch = examplePath
? `${_branch}/${file.join('/')}`.replace(new RegExp(`/${filePath}|/$`), '')
: _branch
if (username && name && branch && t === 'tree') {
return { username, name, branch, filePath }
}
}
The above code snippet is picked from helper function in a file named examples.ts. This file name makes sense because this function deals with URL passed as part of — example option that should point to Github.
Up next, I will explain with log what the following code has:
const [, username, name, t, _branch, ...file] = url.pathname.split('/')
Because it caught my interest.
Conclusion:
After moving past few lines that deal with example option, a new helper function named getRepoInfo is discovered and is located in helpers/examples.ts. Why should it be in this file? — example option directly deals with links pointing to Github repo, so it makes perfect sense to place this function inside example.ts file.
Another observation worth mentioning is to convert a url string to URL object in Nodejs to access the prototype functions such as origin, host etc.,
Get free courses inspired by the best practices used in open source.
About me:
Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.
I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com
My Github — https://github.com/ramu-narasinga
My website — https://ramunarasinga.com
My Youtube channel — https://www.youtube.com/@ramu-narasinga
Learning platform — https://thinkthroo.com
Codebase Architecture — https://app.thinkthroo.com/architecture
Best practices — https://app.thinkthroo.com/best-practices
Production-grade projects — https://app.thinkthroo.com/production-grade-projects