DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on • Edited on • Originally published at thinkthroo.com

“Defu” usage in unbuild 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 Defu?

  2. Defu’s usage in unbuild

What is Defu?

Defu 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.

Defu repository has this description “Assign default properties recursively”.

This package is straightforward to use:

Install

# yarn
yarn add defu
# npm
npm install defu
# pnpm
pnpm install defu
Enter fullscreen mode Exit fullscreen mode

Usage

import { defu } from "defu";

console.log(defu({ a: { b: 2 } }, { a: { b: 1, c: 3 } }));
// => { a: { b: 2, c: 3 } }
Enter fullscreen mode Exit fullscreen mode

Leftmost arguments have more priority when assigning defaults.

Defu is used to merge objects and the leftmost arguments have precedence as shown in the above example, picked from Readme.

Defu’s usage in unbuild

At line 93 in build.ts, you will find this below code snippet:

// Merge options
  const options = defu(
    buildConfig,
    pkg.unbuild || pkg.build,
    inputConfig,
    preset,
    <BuildOptions>{
      name: (pkg?.name || "").split("/").pop() || "default",
      rootDir,
      entries: [],
      clean: true,
      declaration: undefined,
      outDir: "dist",
      stub: _stubMode,
      stubOptions: {
        /**
         * See https://github.com/unjs/jiti#%EF%B8%8F-options
         */
        jiti: {
          interopDefault: true,
          alias: {},
        },
      },
      watch: _watchMode,
      watchOptions: _watchMode
        ? {
            exclude: "node_modules/**",
            include: "src/**",
          }
        : undefined,
      externals: [
        ...Module.builtinModules,
        ...Module.builtinModules.map((m) => "node:" + m),
      ],
      dependencies: [],
      devDependencies: [],
      peerDependencies: [],
      alias: {},
      replace: {},
      failOnWarn: true,
      sourcemap: false,
      rollup: {
        emitCJS: false,
        watch: false,
        cjsBridge: false,
        inlineDependencies: false,
        preserveDynamicImports: true,
        output: {
          // https://v8.dev/features/import-attributes
          importAttributesKey: "with",
        },
        // Plugins
        replace: {
          preventAssignment: true,
        },
        alias: {},
        resolve: {
          preferBuiltins: true,
        },
        json: {
          preferConst: true,
        },
        commonjs: {
          ignoreTryCatch: true,
        },
        esbuild: { target: "esnext" },
        dts: {
          // https://github.com/Swatinem/rollup-plugin-dts/issues/143
          compilerOptions: { preserveSymlinks: false },
          respectExternal: true,
        },
      },
      parallel: false,
    },
  ) as BuildOptions;
Enter fullscreen mode Exit fullscreen mode

this options object is large and following the Defu’s definition, all these objects are merged recursively with leftmost arguments taking precedence.

I wonder how this package is different from lodash._merge. Something to explore, I guess.

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/blob/main/src/build.ts#L93

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

  3. https://www.npmjs.com/package/defu

API Trace View

Struggling with slow API calls?

Dan Mindru walks through how he used Sentry's new Trace View feature to shave off 22.3 seconds from an API call.

Get a practical walkthrough of how to identify bottlenecks, split tasks into multiple parallel tasks, identify slow AI model calls, and more.

Read more →

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more