Evercoder/culori

Culori ESM import throws an error in Next.js production build

VojtechVidra opened this issue · 5 comments

Hi Dan Burzo!

I've encountered strange issue when using latest culori with Next.js in production build only. I've created minimal reproduction of the issue (see the repo below).

How to reproduce

Dev

If you run the app with npm run dev command it works as expected, the converter converts the color with no problem in both the culori and culori/require usage.

Prod

However if you run the production build npm run build && npm run start the culori ESM version throws an error but the culori/require version still works as expected.

https://github.com/VojtechVidra/nextjs-culori

I'm not sure if this is an issue with Culori or Next.js, but I've figured I'll ask you first.

Thanks for creating this great package!

Hi @VojtechVidra! What seems to be going on is some unintended tree-shaking of the ESM entry point src/index.js when you import something that the bundler deems to be free of side-effects.

Importing just converter seems to skip all the side-effects further down in the file:

import { converter } from "culori";

If instead you import the LCh converter directly, which is defined as a side-effect in the entry point, all the other side effects are executed and the code works:

import { lch } from 'culori';

If I understand correctly, Next.js 13 uses Turbopack, so that may be the place to open up an issue. I misread that, Next.js 13 uses a built-in Compiler, so the Next.js repo may be the place to log the issue. It feels to me like overeager tree-shaking. Admittedly, the way Culori is organized is a bit quirky!

This is not a problem for the CommonJS bundle because tree-shaking is not applicable there.

The issue may be caused by our usage of sideEffects: false; in package.json, which if I remember correctly was necessary in order to allow for tree-shaking ESM modules. I'm going to leave the issue open as we may want to revisit this value in the future, to offer better support for the various bundlers.

The issue may be caused by our usage of sideEffects: false; in package.json, which if I remember correctly was necessary in order to allow for tree-shaking ESM modules. I'm going to leave the issue open as we may want to revisit this value in the future, to offer better support for the various bundlers.

I confirm this.

Same thing happens when creating a build with Svelte.
Local dev environment works as expected, whereas when creating a build I get some sort of error which traces back to the interpolate function.

I manually removed "sideEffects": false, from the package.json of culori and the build works fine afterwards.

In culori@3.1.2 I've replaced sideEffects: false with an array of files producing side effects. This should allow both the tree-shaken version (using culori/fn) and the non-tree-shaken version to work correctly with more bundlers.

Tested the files in test/tree-shaking/ with esbuild, rollup, and parcel. Let me know how this new setup works for you!

I just updated to 3.1.2 and can confirm the build is working as expected in a Svelte app.
Thanks @danburzo , you rock dude.