Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

abort-controller dependency problem #122

Closed
David-B-A opened this issue Oct 14, 2022 · 3 comments · Fixed by #201
Closed

abort-controller dependency problem #122

David-B-A opened this issue Oct 14, 2022 · 3 comments · Fixed by #201

Comments

@David-B-A
Copy link
Collaborator

Hello Everyone,

I am getting started with LearnCard SDK, I just installed it using pnpm (pnpm install @learncard/core), but when trying to import { initLearnCard } from '@learncard/core', a dependency error appears:

logger.ts:268 Uncaught Error: Cannot find module './dist/abort-controller'
at webpackMissingModule (logger.ts:268:1)
at ./node_modules/.pnpm/abort-controller@3.0.0/node_modules/abort-controller/polyfill.mjs (logger.ts:268:1)
at options.factory (react refresh:6:1)
at webpack_require (bootstrap:24:1)
at fn (hot module replacement:62:1)
at ./node_modules/.pnpm/@learncard+core@7.0.1/node_modules/@learncard/core/dist/core.esm.js (index.js:91:1)
at options.factory (react refresh:6:1)
at webpack_require (bootstrap:24:1)
at fn (hot module replacement:62:1)
at ./src/pages/Credentials/IssueCredential/index.jsx (index.jsx:33:1)

This issue could not be associated with learn-card but its dependency abort-controller (.mjs or .js). Reviewing abort-controller on npm it appears to not being updated 4 years ago.


App info:

npm -v: 8.19.2
node -v: 16.17.0

React app created with create-react-app, with the following dependencies:

"react": "18.2.0",
"react-dom": "18.2.0",
"react-router-dom": "6.4.2",
"firebase": "9.12.1",
"@mui/material": "5.10.9",
"@mui/icons-material": "^5.10.9",
"@emotion/react": "^11.10.4",
"@emotion/styled": "^11.10.4",

When installing via pnpm, following version of learncard is added:
"@learncard/core": "^7.0.1",

I would appreciate if you could help me to kow how to solve this problem, or if I have made a mistake on any step or there is any missing or incompatible dependency. Thank you!

@TaylorBeeston
Copy link
Collaborator

@David-B-A Hi David!

So the issue comes from node's (semi) recent ESM resolution deciding to require full specifiers.

In short, node would you like you to write this:

import { foo } from 'bar.mjs';

rather than this:

import { foo } from 'bar';

When using native ESM. Because of this, the Webpack team has decided to also add that requirement.

Unfortunately, we don't always have control over code, as is the case for dependencies! The abort-controller library happens to have such an invalid import right here. We need this polyfill in @learncard/core to allow things to function in older versions of node, as well as older browser environments that don't have AbortController and AbortSignal available, and as you noticed, I don't think it's very likely that we'll see the abort-controller package update any time soon.

To remedy this, I can try updating our code to manually handle the polyfilling, importing dist/abort-controller directly (which is CJS and only has a simple require statement). However, this is very likely not the only dependency with such an issue, so in the meantime I would recommend telling Webpack to use the old resolution style that doesn't require adding the file extension!

According to this comment, I would recommend trying to add the following to your webpack config:

{
  test: /\.m?js$/,
  resolve: {
    fullySpecified: false
  }
}

Since you're using CRA, it can be a bit tough to change your webpack config. Personally, I prefer CRACO which doesn't (officially) support CRA 5 yet, but there is a pretty solid beta version that you can use! What that looks like is to follow their instructions, but use pnpm i -D @craco/craco@7.0.0-alpha.8 to install.

Then, in your craco.config.js file, you'll want to include something like this:

module.exports = function ({ env }) {
    return {
        webpack: {
              module: { rules: [{ test: /\.m?js$/, resolve: { fullySpecified: false } }] },
        },
    };
}

I hope this helps, and I'm terribly sorry that you've run into this mess! As you go through this, I'm going to perform some experiments myself using this library with a fresh CRA 5 webapp and try to ease this burden/write better documentation addressing this specific situation!

@David-B-A
Copy link
Collaborator Author

David-B-A commented Oct 18, 2022

Hi @TaylorBeeston,

Than you very much for your answer. I tried with CRACO, but still had the same error, I think it could be due to the incompatibility with create-react-app 5.

Finally I decided to setup the project with webpack and babel:

"devDependencies": {
"@babel/core": "^7.19.3",
"@babel/eslint-parser": "^7.19.1",
"@babel/plugin-transform-runtime": "^7.19.1",
"@babel/preset-env": "^7.19.4",
"@babel/preset-react": "^7.18.6",
"babel-loader": "^8.2.5",
"file-loader": "^6.2.0",
"html-loader": "^4.2.0",
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.6.1",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
},
"dependencies": {
"@babel/runtime": "^7.19.4",
"@emotion/react": "^11.10.4",
"@emotion/styled": "^11.10.4",
"@learncard/core": "^7.0.1",
"@mui/icons-material": "^5.10.9",
"@mui/material": "^5.10.9",
"firebase": "^9.12.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.2"
}

These are my webpack rules:

{
    rules: [
        {
            test: /\.(js|jsx)$/, 
            exclude: /node_modules/, 
            use: { loader: 'babel-loader', },
        },

        {
            test: /\.html$/, 
            use: [
                { loader: 'html-loader', },
            ],
        },

        {
            test: /\.(css|scss)$/, 
            use: [
                { loader: MiniCssExtractPlugin.loader, },
                'css-loader', 
                'sass-loader',
            ],
        },

        {
            test: /\.(png|gif|jpg|svg)$/, 
            use: [
                {
                    loader: 'file-loader', 
                    options: { name: 'assets/[hash].[ext]' },
                }
            ],
        }
    ],
},

And it is working well now, so thank you very much for your help.

Only got these two warnings while compiling (I address them if could be useful):

`
[webpack-dev-server] WARNING in ./node_modules/@learncard/core/dist/core.esm.js 28:73-80
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

[webpack-dev-server] WARNING in ./node_modules/@learncard/core/dist/core.esm.js 32:11-18
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
`

@TaylorBeeston
Copy link
Collaborator

@David-B-A Awesome! Glad you got it working! I'm going to try and get a minimal example using CRA 5 up if I can. It should definitely be possible to use @learncard/core with CRA 5! (We are using it internally already on a CRA 5 site!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants