Lessons from open-source: Taskr in Next.js source code.
Tags: javascript, nextjs, node, react
Published: 2024-03-12 21:58:37

This lesson is picked from [next.js/packages/next/package.json](https://github.com/vercel/next.js/blob/canary/packages/next/package.json). In this article, you will learn what a taskr is, how nextjs uses it and custom plugins in it.

### Taskr

[Taskr](https://www.npmjs.com/package/taskr#taskr) is a highly performant task automation tool, much like Gulp or Grunt, but written with concurrency in mind.

### Example

the following example is picked from [https://www.npmjs.com/package/taskr#example](https://www.npmjs.com/package/taskr#example)

```
const sass = 'src/{admin,client}/\*.sass';
const js = 'src/{admin,client}/\*.js';
const dist = 'build';
 
module.exports = {
  \*lint(task) {
    yield task.source(js).xo({ esnext:true });
  },
  \*scripts(task) {
    yield task.source(js).babel({ presets:\['es2015'\] }).target(\`${dist}/js\`);
  },
  \*styles(task) {
    yield task.source(sass).sass({ outputStyle:'compressed' }).autoprefixer().target(\`${dist}/css\`);
  },
  \*build(task) {
    yield task.parallel(\['lint', 'scripts', 'styles'\]);
  }
}
```

To explain it in simple terms, you define source with a folder, you “apply” (this can be babel compile, sass compile based on above provided examples) and then you copy this transformed/compiled code into target folder.

### How Next.js uses it?

I looked at [packages/next/package.json](https://github.com/vercel/next.js/blob/canary/packages/next/package.json) and it’s script has the following:

```
"scripts": {
    "dev": "taskr",
    "release": "taskr release",
    "build": "pnpm release",
    "prepublishOnly": "cd ../../ && turbo run build",
    "types": "tsc --declaration --emitDeclarationOnly --stripInternal --declarationDir dist",
    "typescript": "tsec --noEmit",
    "ncc-compiled": "ncc cache clean && taskr ncc"
  },
```

This made me wonder what taskr is used for in next.js, after reading the [taskr documentation](https://www.npmjs.com/package/taskr), my understanding is that you need a taskfile.js next to package.json and this is where you write your “tasks”

### taskfile.js with 2833 lines of code:

[taskfile.js in Next.js](https://github.com/vercel/next.js/blob/canary/packages/next/taskfile.js#L82) has 2833 lines of code, this is going to infuriate clean code advocates but I am truly humbed by the next.js authors because you cannot over glorify clean code. I am saying this because I have seen type “any” used in quite some files and now this file with 2833 lines of code makes me reconsider my own clean code principles.

Can it be broken down? I am sure there can be way to achieve this yet the authors chose to grow it to 2833 lines in size.

### Next.js plugins for taskr

![plugin-taskr](https://media.licdn.com/dms/image/D4E12AQFD1-4sCNXc1w/article-inline_image-shrink_1500_2232/0/1710099057471?e=1715817600&v=beta&t=HOQ5PEDt4fxQWZJCSwDbeho_laWKNBaip-WEsQLCmTY)

what is this .swc? I asked myself. First thing I did was to search the docs for such a function but there is no function named swc and then it occured to me that you can [create plugins and use them with taskr](https://www.npmjs.com/package/taskr#plugins). It didn’t take me long to find the [swc plugin as shown below.](https://github.com/vercel/next.js/blob/canary/packages/next/taskfile-swc.js)

![plugin-taskr](https://media.licdn.com/dms/image/D4E12AQFEkWPJt-xJCQ/article-inline_image-shrink_1000_1488/0/1710099057808?e=1715817600&v=beta&t=rUFZBqZVDnlrhAmAVo2ThRM06zHA10cPWKSSRkbYZ34)

Like wise, it has other plugins such as ncc, webpack, watch

![plugin-taskr](https://media.licdn.com/dms/image/D4E12AQHvaN8vJ-tO5Q/article-inline_image-shrink_1000_1488/0/1710099063292?e=1715817600&v=beta&t=KJCwaB9m5NvUqBkVo_dwiQvplnHc8mabBFU1kRBL6ds)

### Conclusion:

This is my first attempt to understand what a taskr package is, obviously there is a lot of happening in these plugins. I do not know what .ncc or .swc plugins do yet, but I am hoping to understand them better with time. Since next package is so large and you want to have more control over compilaton/transformations and their destination folders, using taskr makes sense to me to set the source dir, apply your compilation logic and set the target. Quite smart!