Closed paddotk closed 2 years ago
It looks like somewhere in your code you are trying to import the default export like import marked from 'marked'
.
Make sure you replace all occurrences with import { marked } from 'marked'
I'm using TypeScript and can also confirm that I am also experiencing the same issue on 4.0.0
. I am importing it using import { marked } from "marked";
but getting 'marked' can only be imported using 'import marked = require("marked")' or a default import.
. It is possible that I just need to wait until @types/marked
is bumped up a major version though.
@UziTech I tried that but didn't work... @AlanMorel From the error it looks like a Webpack issue. It also shows in my unit tests which are .js files.
It seems unlikely to be a webpack-specific issue because the project I'm using Marked on is not using webpack at all.
It is possible that I just need to wait until
@types/marked
is bumped up a major version though.
I have the same problem and @types/marked
is still in 3.X
@types/marked v4 should be released soon
Great, I believe that update to @types/marked
will resolve my issue, so I will wait for that, thanks!
Side question though: any reason marked
itself is not providing the typings for the library? It would both eliminate needing a separate @types/marked
dependency while also ensuring that you can bump both the library and typings at the same time. Not a huge deal though, just curious.
Also waiting for @types/marked
... Do you guys have a workaround or maybe I should go back to previous stable version?
Pretty sure your only options are wait for the updated types (which should be coming soon) or use a previous version.
Ok, thanks. If it is the typings that cause the issue though, is there any way to omit the blocking error for now? Such as placing a // @ts-ignore
comment somewhere?
@paddotk If you are in a hurry you can always use gitpkg.now.sh and get an NPM package from the latest commit of UziTech's PR while waiting for it to be merged.
"@types/marked": "https://gitpkg.now.sh/UziTech/DefinitelyTyped/types/marked?415785793c958a98fa8902c482fe8be7959f86f6"
The types have been merged and it's looking good on my end now
It seems like v4.0.0 still doesn't work with Webpack. It looks like Webpack is trying to import lib/marked.cjs
as an ES6 module. If I manually remove the "browser" settings in package.json
or set it to be the same as "main", webpack works.
I guess this stems from the pre-ES6 module PR #1661, but I think it's safe to at least revert this PR for the short term until a better solution is available, if it causes webpack to not work at all...
looks like webpack suggests this fix.
@boazy if you want to test that out and create a PR for that we could get it merged in.
I'm also having issues. I'm not using webpack, typescript, babel or anything, just using ESM module to run my code in Express.
v3 works correctly, if I upgrade to v4 and switch my import from import marked from 'marked';
to import { marked } from 'marked';
I get the following error trying to run it:
/<path>/app/shared/text/format.js:1
Error [ERR_REQUIRE_ESM]: require() of ES Module /<path>/node_modules/marked/lib/marked.esm.js not supported.
Instead change the require of marked.esm.js in null to a dynamic import() which is available in all CommonJS modules.
I also have the same issue when using marked
in CodeSandbox.
When using marked@4.0.0
, and trying to import { marked } from 'marked
(using the latest @types/marked@4.0.0
), marked
is undefined. For now I've resorted to using marked@3.0.8
with import marked from 'marked
. But it would e nice to have this fixed.
marked 4.0.1 has been released that may help with ESM instead of commonJS issues. The main
entry in package.json
now points to the commonJS code.
Real node ESM modules using babel will need to configure for it (unrelated to first comment).
It seems to fix my issue, thanks!
@webstech This still doesn't work for me:
const INITIAL_MARKED_OPTIONS = {
gfm: false,
headerIds: false,
}
// Reset Marked to the defaults and set custom options
marked.setOptions({
...marked.getDefaults(),
...INITIAL_MARKED_OPTIONS,
})
@webstech This still doesn't work for me:
Did you restart the editor? The types change requires that for some setups (vscode/eslint in my case). Are you getting compile errors? Pasted your code into mine and there were no complaints. _marked.marked
does not show up in a search. Do you know where this is coming from?
@webstech
I was actually working on CodeSandbox. Tried a couple of times but couldn't get it working.
Here's a demo:
I tried to download the sandbox (File → Export to ZIP
), and did the following:
npm install
npm run start
But I got this:
Failed to compile.
./src/Application.tsx
Attempted import error: 'marked' is not exported from 'marked'.
/home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/chokidar.js:17
throw new Error(
^
Error: No version of chokidar is available. Tried chokidar@2 and chokidar@3.
You could try to manually install any chokidar version.
chokidar@3: Error: Cannot find module 'chokidar'
Require stack:
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/chokidar.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/DirectoryWatcher.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/watcherManager.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/watchpack.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/webpack/lib/node/NodeWatchFileSystem.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/webpack/lib/node/NodeEnvironmentPlugin.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/webpack/lib/webpack.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/react-scripts/scripts/start.js
chokidar@2: Error: Cannot find module 'watchpack-chokidar2'
Require stack:
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/chokidar.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/DirectoryWatcher.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/watcherManager.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/watchpack.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/webpack/lib/node/NodeWatchFileSystem.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/webpack/lib/node/NodeEnvironmentPlugin.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/webpack/lib/webpack.js
- /home/Ricardo/Workspace/Playground/g0bw2/node_modules/react-scripts/scripts/start.js
at Object.<anonymous> (/home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/chokidar.js:17:7)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:94:18)
at Object.<anonymous> (/home/Ricardo/Workspace/Playground/g0bw2/node_modules/watchpack/lib/DirectoryWatcher.js:9:16)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
Proceeded with npm install chokidar@3
and then npm run start
again, and now I got just this:
Failed to compile.
./src/Application.tsx
Attempted import error: 'marked' is not exported from 'marked'.
The development server was launched, and a browser window opened with this:
I was actually working on CodeSandbox. Tried a couple of times but couldn't get it working.
Sorry, I missed that. Tracked this down to a different change in package.json
. This line:
"browser": "./lib/marked.cjs",
is causing the problem for react apps and possibly anyone using webpack. If it is removed or points to ./lib/marked.esm.js
, your react app builds and runs (obviously I did not do this on CodeSandBox).
Found a possible solution .
"browser": {
"./lib/marked.cjs": "./lib/marked.cjs",
"./lib/marked.esm.js": "./lib/marked.esm.js"
},
Ran some tests (react and marked repo) with no problems. @benmccann Do you have any thoughts on this?
I do not have a test case where the commonJS file would be used for the browser.
Related to the previous solution link, there is a mention of using exports
to resolve this. vscode says exports/browser is an unknown property and it does not appear to have any affect on webpack (invalid target mappings do not cause an error). Finished chasing this angle.
For me #2276 broke marked. The ts compiler just couldn't find marked library anymore!! 4.0.0 is fine, but 4.0.1 doesn't work in my setup (typescript + webpack). I would be in favor of reverting that change or finding a fix that works for everyone.
I think the current setup is pretty confusing because the .cjs
file isn't strictly CJS, but is UMD. I sent a PR to make that clearer without making any other changes: https://github.com/markedjs/marked/pull/2281
As far as the issues people are having here, it's really difficult to tell what's going wrong without more details. I'd encourage anyone who is having an issue to create and share a repository to reproduce the issue
It may be impossible to support all combinations of bundlers and CDNs since so many do weird things. I think the folks that are having trouble with Webpack are most likely using Webpack 4, which is somewhat broken in the way it does resolution. If you use Webpack 5, I expect it will work.
@benmccann I tried your branch (by cloning it directly into the node_modules/marked dir). I still have an issue:
In the code (targetting the browser):
import { marked } from 'marked';
This gives the error: TS2307: Cannot find module 'marked' or its corresponding type declarations. (works fine with 4.0.0)
Trying import { marked } from 'marked/lib/marked.umd'
gives: Module not found: Error: Package path ./lib/marked.umd is not exported from package /elabftw/node_modules/marked (see exports field in /elabftw/node_modules/marked/package.json), but in the editor there is no error with this import, only with the bundler.
I'm not that familiar with the export part of the package.json, but maybe it's missing something? Anyway, thanks for trying to fix this! :)
If needed, I'll try and make a reproducible small repo. Right now files are here: import line and webpack config.
I'd encourage anyone who is having an issue to create and share a repository to reproduce the issue
npx create-react-app my-ts-app --template typescript
cd my-ts-app
yarn install
Edit App.tsx
to add:
import { marked } from 'marked';
...
const msg = marked.parse('# Welcome');
{msg} // somewhere in the html
Run yarn install
and yarn start
and it fails. It works with the changes to marked package.json
I mentioned in prior comment.
Will try with the pull request updates.
UPDATE: The pull request changes work with the sample above. Webpack 5.5.
@rfgamaral Your react app also runs with #2281. Webpack 4.44.
@webstech Awesome, thank you for letting me know 👍
I'd encourage anyone who is having an issue to create and share a repository to reproduce the issue
My issue is similar but not identical. When I moved some code from our web app (using create-react-app) to a library, it started failing with TypeError: Cannot read properties of undefined (reading 'parse')
.
Repro repo here.
@LukeNotable It looks like the issue is that typescript compiles to javascript that looks for marked.marked.parse
. I'm guessing this is a typescript issue and there is probably a tsconfig setting for this.
// my-lib/dist/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useMarked = void 0;
const marked_1 = require("marked");
function useMarked() {
return marked_1.marked.parse('# hi');
}
exports.useMarked = useMarked;
//# sourceMappingURL=index.js.map
Thanks for looking!
What that transpiled code is doing looks right, especially since the Usage in the docs says we can do const { marked } = require('marked');
. However, trying that explicitly even in the app fails with the same error. 🤔
So it's not really a question of app vs lib, but of import
vs require
, although beyond that is over my head.
I also facing same issue currently typescript with "@types/marked": "^4.0.3"
and got error message
ERROR: Could not resolve "marked"
@ryanadhi I resolved to fix the lib manually before building with webpack:
bash src/tools/fix-marked-lib.sh node_modules/marked/package.json
It's ugly but it works and I just couldn't find a way to make marked work with my build process (webpack) after 4.0.1 :/
edit: june 2023: issue is gone, script is not needed anymore
I just did this for now
// @ts-ignore
import { marked } from "marked/lib/marked.esm.js"; // Using full path to library
I'm also experiencing this issue on Webpack 5. I'm importing marked
in a package that just compiles to JS. That compilation changes the import statement from import
to require
.
That package is then imported by my Webpack 5 library, that correctly installs marked
as a dependency, but throws the TypeError: Cannot read properties of undefined (reading 'use')
error.
If I manually change the import to point at the esm
module it works. If I use Webpack's resolve functionality to point to the version I need and remove the exports
declaration from the marked
package, it works. That's not a workable solution, though, since the exports
clause limits me to import it directly.
Any chance you could expose all the files in the lib
folder in the exports
clause to sidestep this issue? That would allow us to use @emilmuller's workaround with Webpack 5.
@laustdeleuran are you importing with import { marked } from 'marked'
?
@UziTech sure am:
import { marked } from 'marked';
marked.use({
...
});
@laustdeleuran it's hard to understand what might be wrong in your case because you're using an intermediate package and I can't see the source of that package. Could you please share it? It's quite likely the issue may be there
@benmccann , that's fair, I wish I had a more reproducible setup.
In short, we have a monorepo using pnpm
. I have a package in that repo that uses marked
. The file in question looks something like:
import DOMPurify from 'isomorphic-dompurify';
import { marked } from 'marked';
marked.use({
renderer: {
/* ...some options here */
},
});
export const format = (markdown: string) =>
DOMPurify.sanitize(marked.parse(markdown, { breaks: true }));
That package compiles that to CJS, which ends up looking something like:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.format = void 0;
var _isomorphicDompurify = _interopRequireDefault(require("isomorphic-dompurify"));
var _marked = require("marked");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_marked.marked.use({
renderer: {
/* ...some options here */
}
});
const format = markdown => _isomorphicDompurify.default.sanitize(_marked.marked.parse(markdown, {
breaks: true
}));
exports.format = format;
That module then gets imported in another project in the monorepo, which is a create-react-app
. I'm trying to upgrade the react-scripts
in that project, which means I'm also upgrading from Webpack 4 to Webpack 5. That upgrade is going smoothly, except for the above file now throwing the TypeError: Cannot read properties of undefined (reading 'use')
error.
@benmccann, if I get rid of the exports
clause in marked
's package.json
, or expand it to include the individual builds, I can resolve this error by overriding the webpack import using resolve
:
"alias": {
"marked": "marked/lib/marked.esm.js",
},
Which in effect applies @emilmuller's fix to Webpack 5.
Put up a basic stab at that fix in #2747.
@laustdeleuran does it work any better if you change this:
import { marked } from 'marked';
marked.use({
renderer: {
/* ...some options here */
},
});
To this?
import { use } from 'marked';
use({
renderer: {
/* ...some options here */
},
});
Or maybe this?
import * as marked from 'marked';
marked.use({
renderer: {
/* ...some options here */
},
});
There's still not enough info here to really understand what's going on. What's the package.json
in the intermediate package, how is the intermediate package being bundled, etc.?
import { use } from 'marked';
As far as I can tell, marked
doesn't export use
directly? This just gets me a TS error:
import * as marked from 'marked';
This just gets me the same result, as it just compiles to the same thing in CJS.
There's still not enough info here to really understand what's going on. What's the package.json in the intermediate package, how is the intermediate package being bundled, etc.?
Fair, but I don't really know how to make a small repro for you. Here's the subpackage's package.json
:
{
"private": true,
"main": "./dist/src/index.js",
"types": "./dist/src/index.d.ts",
"dependencies": {
"@babel/cli": "^7.14.8",
"@babel/core": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/preset-typescript": "^7.15.0",
"@types/handlebars": "^4.1.0",
"@types/marked": "^4.0.8",
"babel-plugin-module-resolver": "^4.1.0",
"date-fns": "^2.29.3",
"handlebars": "^4.7.7",
"imask": "^6.3.0",
"isomorphic-dompurify": "^0.19.0",
"lodash": "^4.17.21",
"marked": "^4.2.12",
"mockdate": "^3.0.2",
"pluralize": "^8.0.0",
"tsc-alias": "^1.3.9",
"typescript": "^4.3.5"
},
"devDependencies": {
"@types/jest": "^27.4.1",
"@types/node": "^16.7.1",
"@typescript-eslint/eslint-plugin": "^4.29.2",
"@typescript-eslint/parser": "^4.29.2",
"babel-jest": "^27.0.6",
"eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-airbnb-typescript": "^13.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.24.1",
"eslint-plugin-jest-dom": "^3.9.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-testing-library": "^4.11.0",
"jest": "^27.5.1",
"prettier": "^2.5.1"
},
"scripts": {
"lint": "pnpm run lint:eslint && pnpm run lint:tsc",
"lint:eslint": "eslint . --cache",
"lint:tsc": "tsc --noEmit",
"test": "TZ='Etc/UTC' jest",
"build": "tsc --project tsconfig.build.json --emitDeclarationOnly && tsc-alias --project tsconfig.build.json -s && babel . --out-dir dist --extensions .ts,.tsx --ignore 'node_modules,dist,**/*.test.ts'",
"install": "pnpm run build"
}
}
@benmccann
I managed to make a minimal-ish repo that reproduces the error: https://github.com/laustdeleuran/marked-2265-module-import-export-issue
This seems like a bug in webpack. This is how webpack compiles marked in your minimal repo (Thanks for that by the way :100:). Than tries to call String.marked.use which throws the error.
/***/ "../node_modules/.pnpm/marked@4.2.12/node_modules/marked/lib/marked.cjs":
/*!******************************************************************************!*\
!*** ../node_modules/.pnpm/marked@4.2.12/node_modules/marked/lib/marked.cjs ***!
\******************************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
module.exports = __webpack_require__.p + "static/media/marked.79f9f27bbd94805ba150.cjs";
/***/ }),
Or there is some webpack configuration that needs to be changed. I am not a webpack expert but it might be helpful to create an issue in their repo to see if someone has seen this before and has an easy fix.
Okay. Thanks for looking into it. I've opened an issue in Webpack's issue tracker here, so we'll see what they say.
Webpack has a lot of open issues, though, so wondering if they'll have he resources to look into it. I looked in the issue tracker for create-react-app
as well, and didn't see anything that looked related, outside of maybe https://github.com/facebook/create-react-app/issues/12100.
Which, in concert with @UziTech's comment about configurations, made me wonder if it's something in create-react-app
's configuration that is interacting badly with how marked
is compiled when used in a subpackage. Ack, there's so many interlocking tools here that's it's difficult to detangle.
Marked version: 4.0.0
Describe the bug I updated marked in our project from
^3.0.2
to4.0.0
(before it worked fine), and after the update I get an errormarked__WEBPACK_IMPORTED_MODULE_5___default(...) is not a function
when using it. It seems that the module is no longer exported properly, I tried to change the importimport { marked } from 'marked'
as well as usingmarked.parse()
as shown in the readme, but that doesn't seem to help.To Reproduce Steps to reproduce the behavior: Use a webpack/npm project, import by means of
import marked from 'marked'
. Use themarked()
function.