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)
@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 handimport CAF from "caf/caf"would come from./dist/esm/caf.mjswhere 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:
It fixes currently broken behavior in most new browsers, due to changes the HTML spec made to
AbortSignalthat started to land in browsers recently (last few months).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
fromspecifier? Is WP not able to understand the import-entry-points from the npm package, like"caf/caf"or"caf/cag"? Does WP require all yourimportstatements to use explicit file paths, or does it just not like CAF’s exports?If at all possible,
CAFshould be imported as one of these two: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.0doesn’t work with Rollup either (https://github.com/owncloud/web/pull/7141 leads to broken unit tests complaining aboutcaf/caf, don’t let yourself be fooled by unrelated the CI error 😉). Any chance we get av2.3.1or an official vue2-compatiblev3.0.0anytime soon? 😃 thx!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
Together with
import CAF from "caf/core";with no luck though.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
Hoping maybe this is news that leads to a resolution here: https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/
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.exportsand hopefully in the future it will be a nice and easy way to check and define what a library exports.Only thing I can think of is to have the fallback more “future compatible” . If the consumer does not support
package.exportstheir bundler will most likely look atmainand continue from there. In this case it lands atmain:https://github.com/getify/CAF/blob/master/package.json#L5
If main would be compatible with
.export theimport { CAF } from 'caf';would work. But in this case main has a default export ofCAFand therefore I’m so far doingimport CAF from 'caf'.vue-concurrency points
maintodist: https://github.com/MartinMalinda/vue-concurrency/blob/master/package.json#L7I’m not sure if that would be suitable for CAF.
There’s also a
modulefield 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 ifpackage.exportsis 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
What do you mean? This works perfectly fine as far as I can tell:
No, that’s not what you want. You should pick one of these two:
import Caf from "caf"actually would “work” but in a surprising/weird way. You’d have a namespace calledCafthat had properties on it namedCAFandCAG… so then to use the library, you’d have to do in codex = 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).