DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on

“Jiti” usage in Docusaurus source code.

For this week, I have been reading unbuild source code and found few packages that I have never seen before or used. I wanted to share some interesting packages that are used in these OSS projects so we can learn a thing or two ;)

The following are discussed in this article:

  1. What is Jiti?

  2. Jiti’s usage in Docusaurus

Image description

What is Jiti?

Jiti is a package built by authors at Unjs. Unjs provides JS tools, libraries and has about 63 npm packages and 421m downloads per month. Sheesh, that’s a lot.

Jiti repository has this description “Runtime TypeScript and ESM support for Node.js”. Okay, what does this mean? To understand more about this tool, I looked at the features it offers:

  • Seamless TypeScript and ESM syntax support for Node.js

  • Seamless interoperability between ESM and CommonJS

  • Asynchronous API to replace import()

  • Synchronous API to replace require() (deprecated)

  • Super slim and zero dependency

  • Custom resolve aliases

  • Smart syntax detection to avoid extra transforms

  • Node.js native require.cache integration

  • Filesystem transpile with hard disk caches

  • ESM Loader support

  • JSX support (opt-in)

Sure enough, it has features that I do not understand yet, the one feature that rings a bell for me is the Seamless interoperability between ESM and CommonJS because I have seen this in dynamic imports in OSS projects where a file is defined using CommonJS (module.exports) required in an file using ESM syntax (export default) but still not sure if what I saw back then has any resemblance to what Jiti offers. I am interested to learn more about this package, may be in the future.

But let’s review Jiti’s usage in Open Source projects such as Docusaurus and Unbuild

Jiti’s usage in Docusaurus

I found the below code related to Jiti in the Docusaurus — moduleUtils.js

import jiti from 'jiti';

/*
jiti is able to load ESM, CJS, JSON, TS modules
 */
export async function loadFreshModule(modulePath: string): Promise<unknown> {
  try {
    if (typeof modulePath !== 'string') {
      throw new Error(
        logger.interpolate`Invalid module path of type name=${modulePath}`,
      );
    }
    const load = jiti(__filename, {
      // Transpilation cache, can be safely enabled
      cache: true,
      // Bypass Node.js runtime require cache
      // Same as "import-fresh" package we used previously
      requireCache: false,
      // Only take into consideration the default export
      // For now we don't need named exports
      // This also helps normalize return value for both CJS/ESM/TS modules
      interopDefault: true,
      // debug: true,
    });

    return load(modulePath);
Enter fullscreen mode Exit fullscreen mode

Let’s get the hint from the comments — “jiti is able to load ESM, CJS, JSON, TS modules”, this would be the interoperability feature. jiti is imported and directly called as a function with some parameters for additional configuration and it has comments explaining what the configuration is for.

// Transpilation cache, can be safely enabled
cache: true,
// Bypass Node.js runtime require cache
// Same as "import-fresh" package we used previously
requireCache: false,
// Only take into consideration the default export
// For now we don't need named exports
// This also helps normalize return value for both CJS/ESM/TS modules
interopDefault: true,
// debug: true,
Enter fullscreen mode Exit fullscreen mode

I also found this note in Docusaurus migration guide:

New Config Loader

Docusaurus v3 changes its internal config loading library from import-fresh to jiti. It is responsible for loading files such as docusaurus.config.js or sidebars.js, and Docusaurus plugins.

:::info How to upgrade

In theory, you have nothing to do, and your existing config files should keep working as before.

However, this is a major dependency swap and subtle behavior changes could occur.

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/@thinkthroo

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

References:

  1. https://github.com/unjs/unbuild/tree/main/src

  2. https://github.com/unjs/unbuild/blob/main/src/build.ts#L36

  3. https://github.com/search?q=repo%3Afacebook%2Fdocusaurus%20jiti&type=code

  4. https://github.com/facebook/docusaurus/blob/71d682c53b2f6bcb2e70c86dde79cbb7c581e9a8/website/docs/migration/v3.mdx#L759

  5. https://github.com/facebook/docusaurus/blob/71d682c53b2f6bcb2e70c86dde79cbb7c581e9a8/packages/docusaurus-utils/src/moduleUtils.ts#L21

  6. https://www.npmjs.com/package/jiti

  7. https://unjs.io/packages?q=&order=1&orderBy=title

Top comments (0)