shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.3

I wanted to find out how shadcn-ui CLI works. In this article, I discuss the code used to build the shadcn-ui/ui CLI.

In part 2.2, I followed along the call stack when the function getProjectConfig is called and discussed functions named getConfig, ge…


This content originally appeared on DEV Community and was authored by Ramu Narasinga

I wanted to find out how shadcn-ui CLI works. In this article, I discuss the code used to build the shadcn-ui/ui CLI.

In part 2.2, I followed along the call stack when the function getProjectConfig is called and discussed functions named getConfig, getRawConfig. A detailed explanation is provided about getRawConfig that is called from getConfig. In this article, we will analyse few more lines of code from getConfig function.

resolveConfigPaths

export async function resolveConfigPaths(cwd: string, config: RawConfig) {
  // Read tsconfig.json.
  const tsConfig = await loadConfig(cwd)

  if (tsConfig.resultType === "failed") {
    throw new Error(
      \`Failed to load ${config.tsx ? "tsconfig" : "jsconfig"}.json. ${
        tsConfig.message ?? ""
      }\`.trim()
    )
  }

  return configSchema.parse({
    ...config,
    resolvedPaths: {
      tailwindConfig: path.resolve(cwd, config.tailwind.config),
      tailwindCss: path.resolve(cwd, config.tailwind.css),
      utils: await resolveImport(config.aliases\["utils"\], tsConfig),
      components: await resolveImport(config.aliases\["components"\], tsConfig),
      ui: config.aliases\["ui"\]
        ? await resolveImport(config.aliases\["ui"\], tsConfig)
        : await resolveImport(config.aliases\["components"\], tsConfig),
    },
  })
}

Let’s break this function down.

loadConfig

// Read tsconfig.json.
const tsConfig = await loadConfig(cwd)

loadConfig is imported from [tsconfig-paths](https://www.npmjs.com/package/tsconfig-paths).

This function loads the tsconfig.json or jsconfig.json. It will start searching from the specified cwd directory.

if (tsConfig.resultType === "failed") {
    throw new Error(
      \`Failed to load ${config.tsx ? "tsconfig" : "jsconfig"}.json. ${
        tsConfig.message ?? ""
      }\`.trim()
    )
  }

This is an error check that throws an error when tsConfig or jsConfig fails to load.

return configSchema.parse({
    ...config,
    resolvedPaths: {
      tailwindConfig: path.resolve(cwd, config.tailwind.config),
      tailwindCss: path.resolve(cwd, config.tailwind.css),
      utils: await resolveImport(config.aliases\["utils"\], tsConfig),
      components: await resolveImport(config.aliases\["components"\], tsConfig),
      ui: config.aliases\["ui"\]
        ? await resolveImport(config.aliases\["ui"\], tsConfig)
        : await resolveImport(config.aliases\["components"\], tsConfig),
    },
  })

configSchema is returned by the resolveConfigPaths. This code snippet uses path.resolve and resolveImport.

resolveImport

import { createMatchPath, type ConfigLoaderSuccessResult } from "tsconfig-paths"

export async function resolveImport(
  importPath: string,
  config: Pick<ConfigLoaderSuccessResult, "absoluteBaseUrl" | "paths">
) {
  return createMatchPath(config.absoluteBaseUrl, config.paths)(
    importPath,
    undefined,
    () => true,
    \[".ts", ".tsx"\]
  )
}

You can read more about createMatchPath.

Conclusion:

I updated the commanderjs-usage-in-shadcnui with shadcn-ui CLI package code to understand the getConfig call in getProjectConfig. Turns out, this little detour to understand the series of function calls following getConfig are to check if there is existing component config.

// Check for existing component config.
const existingConfig = await getConfig(cwd)
if (existingConfig) {
  return existingConfig
}

Just to recap, the call stack is like this: getConfig calls getRawConfig, getRawConfig uses explorer.search (from cosmicconfig) and then if there is an existing component config, resolveConfigPaths is returned that uses some helpers function such as createMatchPath provided by tsconfig-paths package. All this trouble just to check if there’s an existingConfig. Why tho?

The answer lies in the different schema that you get when there’s an existing component config available. (configSchema and rawConfigSchema). There’s something unique about the way these functions are organised!

Want to learn how to build shadcn-ui/ui from scratch? Check out build-from-scratch

About me:

Website: https://ramunarasinga.com/

Linkedin: https://www.linkedin.com/in/ramu-narasinga-189361128/

Github: https://github.com/Ramu-Narasinga

Email: ramu.narasinga@gmail.com

Build shadcn-ui/ui from scratch

References:

  1. https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/utils/get-config.ts#L55
  2. https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/utils/get-config.ts#L4
  3. https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/utils/get-config.ts#L2
  4. https://www.npmjs.com/package/tsconfig-paths
  5. https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/utils/resolve-import.ts#L3
  6. https://www.npmjs.com/package/tsconfig-paths#creatematchpath


This content originally appeared on DEV Community and was authored by Ramu Narasinga


Print Share Comment Cite Upload Translate Updates
APA

Ramu Narasinga | Sciencx (2024-07-01T21:22:59+00:00) shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.3. Retrieved from https://www.scien.cx/2024/07/01/shadcn-ui-ui-codebase-analysis-how-does-shadcn-ui-cli-work-part-2-3/

MLA
" » shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.3." Ramu Narasinga | Sciencx - Monday July 1, 2024, https://www.scien.cx/2024/07/01/shadcn-ui-ui-codebase-analysis-how-does-shadcn-ui-cli-work-part-2-3/
HARVARD
Ramu Narasinga | Sciencx Monday July 1, 2024 » shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.3., viewed ,<https://www.scien.cx/2024/07/01/shadcn-ui-ui-codebase-analysis-how-does-shadcn-ui-cli-work-part-2-3/>
VANCOUVER
Ramu Narasinga | Sciencx - » shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.3. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/07/01/shadcn-ui-ui-codebase-analysis-how-does-shadcn-ui-cli-work-part-2-3/
CHICAGO
" » shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.3." Ramu Narasinga | Sciencx - Accessed . https://www.scien.cx/2024/07/01/shadcn-ui-ui-codebase-analysis-how-does-shadcn-ui-cli-work-part-2-3/
IEEE
" » shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.3." Ramu Narasinga | Sciencx [Online]. Available: https://www.scien.cx/2024/07/01/shadcn-ui-ui-codebase-analysis-how-does-shadcn-ui-cli-work-part-2-3/. [Accessed: ]
rf:citation
» shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.3 | Ramu Narasinga | Sciencx | https://www.scien.cx/2024/07/01/shadcn-ui-ui-codebase-analysis-how-does-shadcn-ui-cli-work-part-2-3/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.