vue-concurrency: Webpack 5 fails due to the way CAF is imported

There is a conflict in the way how CAF is imported on upgrade from Webpack 4 -> 5.

In TaskInstance.ts the current import CAF from "caf"; works with Webpack 4, but crashes on Webpack 5. For Webpack 5 the code that works is import { CAF } from "caf";.

Edit : I actually can’t check if the stricter import that works in Webpack 5 is working on v4 too or not. If it is - then it is an easy fix.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 49 (22 by maintainers)

Most upvoted comments

@MartinMalinda I’ll try to put my 5 cents on this again (feel free to correct me if I’m wrong and sorry in advance, if I’m talking nonsense). If you look at CAF’s package.json, the default export defined there is : ".": { "import": "./dist/esm/index.mjs", "default": "./index.js" }

So, when you do import whatever-you-want-to -import from "caf", this comes from ./dist/esm/index.mjs, which looks like this : export{default as CAF}from"./caf.mjs";export{default as CAG}from"./cag.mjs";export{default as CAFShared}from"./shared.mjs";

This means you there is no default export in this file to use and as far as I understand it - you should import like this import { CAF } from "caf". On other hand import CAF from "caf/caf" would come from ./dist/esm/caf.mjs where the module.exports you mention happens.

Sorry for the delay everybody. I’ll double check the situation again this week, hopefully a new compromise has appeared and if not, I’ll release different versions for different platforms and let you know.

Just as a side note: I am about to release (probably today or tomorrow) v15.0.0 of CAF. This version is important for the following reasons:

  1. It fixes currently broken behavior in most new browsers, due to changes the HTML spec made to AbortSignal that started to land in browsers recently (last few months).

  2. I am deprecating "caf/caf" as an import specifier, and will eventually remove it. I’ve long disliked it as being confusing. The new equivalent import specifier introduced in 15.0.0 is "caf/core".

There is already a pre-release of these updates on npm: 15.0.0-preA. I would encourage you to try that version out, and switch from "caf/caf" to "caf/core" to be future safe.

I’m curious why you have to use such an explicit file path in the from specifier? Is WP not able to understand the import-entry-points from the npm package, like "caf/caf" or "caf/cag"? Does WP require all your import statements to use explicit file paths, or does it just not like CAF’s exports?

If at all possible, CAF should be imported as one of these two:

import { CAF } from "caf";

import CAF from "caf/caf";

I’d discourage (unless absolutely required – but again, why!?) relying on paths, as that creates future potential breakage if I for example re-arrange the structure or names of files. The named import-entry-points are a beneficial abstraction to avoid such issues should something like that ever need to occur.

I’m giving this a quick test.

It seems like basic import works in Webpack 5, but then it errors out on a polyfill import.

https://codesandbox.io/p/sandbox/webpack5-forked-t5pzzn

But it looks its a codesandbox specific problem because in standblitz its all fine.

https://stackblitz.com/edit/webpack-webpack-js-org-tfxmcl?file=src%2Findex.js,package.json

Closing!

Thanks @Hawxy for the fix.

Initially came here because v2.3.0 doesn’t work with Rollup either (https://github.com/owncloud/web/pull/7141 leads to broken unit tests complaining about caf/caf, don’t let yourself be fooled by unrelated the CI error 😉). Any chance we get a v2.3.1 or an official vue2-compatible v3.0.0 anytime soon? 😃 thx!

But! I just tried 4.0.0-7 and the problem vanished 🎉

Sorry, version 4.0.0-7 of what exactly?

Perhaps https://github.com/MartinMalinda/vue-concurrency/releases/tag/4.0.0-7 ?

But! I just tried 4.0.0-7 and the problem vanished 🎉

Thanks for the heads up @getify 🙏

So far I’m trying

 "typescript": "^4.7.0-beta",

Together with import CAF from "caf/core"; with no luck though.

Screenshot 2022-04-22 at 12 14 32

I’ve also tried to change the package.json of CAF in the node modules folder to this format (so it is in the same format as in the TS announcement example) and that also didnt solve the problem

	"exports": {
		".": {
	            "import": {
                         "default": "./dist/esm/index.mjs"
                     }
		},

Hoping maybe this is news that leads to a resolution here: https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/

If I understand this question, are you saying that a library like CAF should avoid defining package.exports stuff because the rest of the ecosystem seems to not understand how to use them?

I’m sorry if that sounded rude from my side. I definitely don’t want to instruct others on what they should do. I understand your points and there’s a nice value in package.exports and hopefully in the future it will be a nice and easy way to check and define what a library exports.

I dunno how to fix the situation. But if we can find something I could add, that wouldn’t break how CAF is already used in other scenarios, I am perfectly happy to do that.

Only thing I can think of is to have the fallback more “future compatible” . If the consumer does not support package.exports their bundler will most likely look at main and continue from there. In this case it lands at main:

https://github.com/getify/CAF/blob/master/package.json#L5

If main would be compatible with . export the import { CAF } from 'caf'; would work. But in this case main has a default export of CAF and therefore I’m so far doing import CAF from 'caf'.

vue-concurrency points main to dist: https://github.com/MartinMalinda/vue-concurrency/blob/master/package.json#L7

I’m not sure if that would be suitable for CAF.

There’s also a module field but I’m not aware how much and by what consumers it is used: https://github.com/MartinMalinda/vue-concurrency/blob/master/package.json#L6 But maybe it could also function as a reasonable fallback if package.exports is not supported. I’m not sure 😕

I’ll see if I have time over the weekend, I might try these in CAF repository and report how it works with TypeScript 🙏 (as I’m using it).

There’s also an option to pass an alias to microbundle, the tool that actually builds the output bundle. Maybe that’s the correct way to go around this. I’ll try to check that also.

@lllopo thanks for testing it out. I’ll try to test the TS option soon. Hopefully the TS config will solve it for everyone and not just flip the issue to the other side (fixing it for WP5 and breaking it for others). Will check!

Sooooo … I’m back. Did a few experiments and here the results.

First - your suggestion works like this : resolve: { alias: { caf: path.resolve(__dirname, 'node_modules/vue-concurrency/node_modules/caf/dist/esm/caf.mjs'), } }

but the problem is that this way I would have to do the old style imports of caf in my project, if I need it elsewhere. So, I find it somewhat unacceptable. For now I’ll maybe use it, so I can use the dist of your project instead of re-building it, but I don’t find it good practice. I think it would be much better solution to have this sorted out at vue-concurrency project level. So, what I found is that TypeScript configuration supports this :

"compilerOptions": { "baseUrl": ".", "paths" : { "..." : ["..."] } }

Wouldn’t this somehow work, along with importing import CAF from 'caf/caf';.

@vdvibhu20

Not working due to ‘caf/caf’ import

What do you mean? This works perfectly fine as far as I can tell:

import CAF from "caf/caf"

if works with simple import

import Caf from ‘caf’;

No, that’s not what you want. You should pick one of these two:

import CAF from "caf/caf"

// or:

import { CAF } from "caf"

import Caf from "caf" actually would “work” but in a surprising/weird way. You’d have a namespace called Caf that had properties on it named CAF and CAG… so then to use the library, you’d have to do in code x = Caf.CAF(..). I advise against that.

Side note: I am considering changing that "caf/caf" import-entry-point to "caf/core" soon, to be less confusing. But I won’t be removing the "caf/caf" entry-point probably ever, so it’s pretty future proof.

No, no … I think I got you right. I just re-checked my package.json. I’m actually even using 4.0.0-1 right now. No worries. I’m also on very-very early stages of the project where I’m using it … I can even call it experimental stage 😃. Fingers crossed you will solve the issues you have. It transpiles fine at my place, but it is probably because I’m using it on different bundler (or maybe different tsconfig).