Skip to content

[@unocss/webpack] CSS generation is inconsistent with persistent caching enabled #419

@chrissantamaria

Description

@chrissantamaria

Problem

👋 noticed an issue with @unocss/webpack and Webpack 5's new persistent caching feature. It looks like @unocss/webpack's approach of using loaders to extract code for class parsing can break with persistent caching - when a module is considered a cache hit, loaders are skipped entirely. This has the end result of subsequent builds having a potentially incomplete set of unocss classes included.

I've created a minimal reproduction repo to help isolate this issue - instructions are included in the README.

Potential solution

One approach could be to perform the code extraction (i.e. pushing to tasks) in the NormalModuleFactory stage as all modules (cached or otherwise) pass through this hook when being added to the dependency tree. Unfortunately, this requires manually reading the file contents rather than pulling what the loader has already read. Fortunately, compiler.inputFileSystem.readFile can be used which (from what I can tell) has internal caching to make the impact of repeated reads fairly negligable.

I've loosely tested this approach and it seems to solve the original issue - the second cached build succeeds and produces the same output. It's unfortunately a bit hacky and doesn't compose cleanly with unplugin but could at least be used as a starting point for a cache-friendly setup. Happy to post a snippet or open a rough PR.

However, for some reason the third (also cached) build seems to crash with or without the fix:

Build output
➜  unocss-bug-persistent-caching git:(main) ✗ yarn build
yarn run v1.22.11
warning package.json: No license field
$ webpack
assets by status 131 KiB [cached] 3 assets
Entrypoint main = main.css main.js
cached modules 134 KiB (javascript) 238 bytes (css/mini-extract) [cached] 13 modules
orphan modules 39 bytes [orphan] 1 module
./_virtual_uno.css 39 bytes [built] [1 error]

ERROR in ./_virtual_uno.css (./_virtual_uno.css.webpack[javascript/auto]!=!./node_modules/css-loader/dist/cjs.js!./_virtual_uno.css)
Module build failed (from ./node_modules/css-loader/dist/cjs.js):
Error: ENOENT: no such file or directory, open '/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/_virtual_uno.css'
 @ ./_virtual_uno.css
 @ ./src/index.js 3:0-17

ERROR in ./_virtual_uno.css
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
HookWebpackError: Module build failed (from ./node_modules/css-loader/dist/cjs.js):
Error: ENOENT: no such file or directory, open '/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/_virtual_uno.css'
    at tryRunOrWebpackError (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/HookWebpackError.js:88:9)
    at __webpack_require_module__ (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/Compilation.js:4979:12)
    at __webpack_require__ (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/Compilation.js:4936:18)
    at /Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/Compilation.js:5007:20
    at symbolIterator (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/neo-async/async.js:3485:9)
    at done (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/neo-async/async.js:3527:9)
    at Hook.eval [as callAsync] (eval at create (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/tapable/lib/Hook.js:18:14)
    at /Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/Compilation.js:4914:43
    at symbolIterator (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/neo-async/async.js:3482:9)
-- inner error --
Error: Module build failed (from ./node_modules/css-loader/dist/cjs.js):
Error: ENOENT: no such file or directory, open '/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/_virtual_uno.css'
    at Object.<anonymous> (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/css-loader/dist/cjs.js!/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/_virtual_uno.css:1:7)
    at /Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/javascript/JavascriptModulesPlugin.js:432:11
    at Hook.eval [as call] (eval at create (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1)
    at Hook.CALL_DELEGATE [as _call] (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/tapable/lib/Hook.js:14:14)
    at /Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/Compilation.js:4981:39
    at tryRunOrWebpackError (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/HookWebpackError.js:83:7)
    at __webpack_require_module__ (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/Compilation.js:4979:12)
    at __webpack_require__ (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/Compilation.js:4936:18)
    at /Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/webpack/lib/Compilation.js:5007:20
    at symbolIterator (/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/neo-async/async.js:3485:9)

Generated code for /Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/node_modules/css-loader/dist/cjs.js!/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/_virtual_uno.css
1 | throw new Error("Module build failed (from ./node_modules/css-loader/dist/cjs.js):\nError: ENOENT: no such file or directory, open '/Users/chrissantamaria/Desktop/unocss-bug-persistent-caching/_virtual_uno.css'");
 @ ./src/index.js 3:0-17

webpack 5.65.0 compiled with 2 errors in 522 ms

I haven't had much time to debug this, though it seems to be unrelated from the loader issue. Definitely still worth addressing, can open a second issue if you'd like.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions