Environment
Description
The issue happens in the real project, there we will have following import path:
{
name: '<root>/packages/data/data-resolver-types/generated/foo.ts',
children: [
{
name: '<root>/packages/data/data-types-common/index.ts',
children: [
{
name: '<root>/packages/data/data-types-common/src/fragments/index.ts',
children: [
{
name: '<root>/packages/data/data-types-common/src/fragments/baz.ts',
children: [
{
name: '<root>/packages/data/data-types-common/index.ts',
circular: true
}
]
}
]
}
]
}
]
}
Notice that <root>/packages/data/data-types-common/index.ts is circularly referenced.
Webpack successfully builds such code, but once @linaria/webpack-loader is in place build freezes (actually it's an infinite loop).
The easiest way to find out that is to go to node_modules/@linaria/babel-preset/lib/transform-stages/1-prepare-for-eval.js and modify it to log active mutexes:
const mutexes = new Map();
+setInterval(() => {
+ console.log('mutexes', mutexes)
+}, 2000)
It outputs something like that:
mutexes Map(3) {
'/linaria-circulars-issue/src/index.js' => Promise { <pending> },
'/linaria-circulars-issue/src/pkg-a/index.js' => Promise { <pending> },
'/linaria-circulars-issue/src/pkg-a/styles.js' => Promise { <pending> }
}
Notice: these promises will be never resolved 💥
I created a simple repro of this in https://github.com/layershifter/linaria-circulars-issue. In my simplified case Webpack does not go into infinite loop, it just outputs nothing:
$ yarn b:webpack:linaria
...
Without circulars it complies successfully:
$ yarn b:webpack:linaria-no-circulars
asset main.js 2.31 KiB [compared for emit] (name: main)
asset styles.css 24 bytes [compared for emit] (name: main)
Entrypoint main 2.33 KiB = styles.css 24 bytes main.js 2.31 KiB
orphan modules 2.79 KiB (javascript) 937 bytes (runtime) [orphan] 8 modules
runtime modules 274 bytes 1 module
webpack 5.75.0 compiled successfully in 520 ms
I also tried Webpack, Rollup and esbuild without Linaria, all they pass:
$ yarn b:webpack
asset main.js 690 bytes [emitted] (name: main)
orphan modules 338 bytes [orphan] 4 modules
./src/index.js + 4 modules 488 bytes [not cacheable] [built] [code generated]
webpack 5.75.0 compiled successfully in 57 ms
$ yarn b:rollup
./src/index.js → ./dist/rollup/main.js...
(!) Circular dependency
src/pkg-a/index.js -> src/pkg-a/styles.js -> src/pkg-a/index.js
created ./dist/rollup/main.js in 19ms
Notice that Rollup complains about circulars, but builds it
yarn b:esbuild
dist/esbuild/main.js 801b
⚡ Done in 3ms
Reproducible Demo
Environment
@linaria/[email protected],@linaria/[email protected],@linaria/[email protected]Description
The issue happens in the real project, there we will have following import path:
Webpack successfully builds such code, but once
@linaria/webpack-loaderis in place build freezes (actually it's an infinite loop).The easiest way to find out that is to go to
node_modules/@linaria/babel-preset/lib/transform-stages/1-prepare-for-eval.jsand modify it to log activemutexes:It outputs something like that:
I created a simple repro of this in https://github.com/layershifter/linaria-circulars-issue. In my simplified case Webpack does not go into infinite loop, it just outputs nothing:
Without circulars it complies successfully:
I also tried Webpack, Rollup and esbuild without Linaria, all they pass:
$ yarn b:webpack asset main.js 690 bytes [emitted] (name: main) orphan modules 338 bytes [orphan] 4 modules ./src/index.js + 4 modules 488 bytes [not cacheable] [built] [code generated] webpack 5.75.0 compiled successfully in 57 msyarn b:esbuild dist/esbuild/main.js 801b ⚡ Done in 3msReproducible Demo
yarnyarn b:webpack:linaria-no-circulars