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

Dynamic imports don't work when exports specified in package.json and aliases #13865

Open
dhruvkb opened this issue Jul 26, 2021 · 21 comments
Open

Comments

@dhruvkb
Copy link

dhruvkb commented Jul 26, 2021

Bug report

What is the current behavior?


The same problem in require.context and import.meta.webpackContext, so need to be fixed too

For example, highlight.js has the following in exports of package.json:

{
	"exports": {
		"./lib/languages/*": {
			"require": "./lib/languages/*.js",
			"import": "./es/languages/*.js"
		}
	}
}

I tried to import a language dynamically using the following code in a Vue 3 / TS 4 app:

const langName = ref('')
const message = ref('')
const module = await import(
  `highlight.js/lib/languages/${langName.value}`
)
message.value = module.default.name

This leads to the following error:

 error  in ./src/App.vue?vue&type=script&lang=ts

Module not found: Error: Package path ./lib/languages is not exported from package <path_to_proj>/node_modules/highlight.js (see exports field in <path_to_proj>/node_modules/highlight.js/package.json)

If the current behavior is a bug, please provide the steps to reproduce.

  1. Clone minimum reproduction repo and npm install.
  2. Run the project with npm run serve.
  3. See error.

What is the expected behavior?

Replacing ${langName.value} with a literal value works and imports the file as expected:

const langName = ref('')
const message = ref('')
const module = await import(
  `highlight.js/lib/languages/javascript`
)
message.value = module.default.name

Dynamic import should work equally well.

Workarounds

The comment highlightjs/highlight.js#3223 (comment) contains possible workarounds, if that helps to narrow the problem.

Other relevant information:
webpack version: 5
Node.js version: 14
Operating System: mac OS
Additional tools: TypeScript 4, Vue 3, Babel 7

@alexander-akait
Copy link
Member

Yep, bug, feel free to send a fix

@dhruvkb
Copy link
Author

dhruvkb commented Aug 2, 2021

@alexander-akait can you give me some pointers on where to start looking? I'm clueless about what to do to fix this.

@alexander-akait
Copy link
Member

I think you need to start debug here https://github.com/webpack/webpack/blob/main/lib/ContextModuleFactory.js#L155

@sokra
Copy link
Member

sokra commented Aug 4, 2021

This may is a bit more involved to fix...

@vankop
Copy link
Member

vankop commented Aug 4, 2021

should this even work.. spec disallow requesting directories..

@dhruvkb
Copy link
Author

dhruvkb commented Aug 4, 2021

@vankop this problem is not for importing directories, it occurs when dynamically importing a file (which is present in the exports key) from the directory. The import works when the path is statically specified but not when it is generated from string interpolation.

@dominicarrojado
Copy link

Not sure if related to this, but I get this error from my Next.js app when using highlight.js@v11.2.0 in my local dev.

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/languages/arduino' is not defined by "exports" in /xxx/node_modules/highlight.js/package.json imported from /xxx/node_modules/lowlight/lib/common.js

Then when trying to reproduce in code sandbox, I get a different error: https://codesandbox.io/s/interesting-fire-thu88?file=/pages/index.js

@dhruvkb
Copy link
Author

dhruvkb commented Sep 28, 2021

@dominicarrojado the Next.js error you mention is the same that I faced.

azul pushed a commit to nextcloud/text that referenced this issue Oct 27, 2021
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.7.3 to 11.3.1.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md)
- [Commits](highlightjs/highlight.js@10.7.3...11.3.1)

---
updated-dependencies:
- dependency-name: highlight.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Work around a bug in webpack with dynamic imports:
webpack/webpack#13865

Signed-off-by: dependabot[bot] <support@github.com>
@azul
Copy link

azul commented Oct 27, 2021

Rewriting the import to only contain a variable and not a constructed string fixed the build for me.
So in the example app this helped: https://github.com/dhruvkb/expcheck/pull/1/files

update: however this breaks the dynamic import and thus the chunks for these packages will not be build.

I tried various things (webpackInclude, webpackExclude, webpackExports magical comments) to remove the lib/languages from the modules being resolved but none of them worked. Looks like webpack tries to resolve the prefix first when trying to perform an dynamic import. While this works with directories (languages directory must exist for languages/javascript.js to exist) it fails with package.js exports.

azul pushed a commit to nextcloud/text that referenced this issue Oct 27, 2021
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.7.3 to 11.3.1.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md)
- [Commits](highlightjs/highlight.js@10.7.3...11.3.1)

---
updated-dependencies:
- dependency-name: highlight.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Work around a bug in webpack with dynamic imports:
webpack/webpack#13865

Signed-off-by: dependabot[bot] <support@github.com>
azul pushed a commit to nextcloud/text that referenced this issue Oct 27, 2021
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.7.3 to 11.3.1.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md)
- [Commits](highlightjs/highlight.js@10.7.3...11.3.1)

---
updated-dependencies:
- dependency-name: highlight.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Work around a bug in webpack with dynamic imports:
webpack/webpack#13865

Signed-off-by: dependabot[bot] <support@github.com>
@azul
Copy link

azul commented Oct 29, 2021

I ran the build again with --profile writing to a json log.

Trace taken with `--profile`
ModuleNotFoundError: Module not found: Error: Package path ./lib/languages is not exported from package /home/azul/code/nextcloud/server/apps/text/node_modules/highlight.js (see exports field in /home/azul/code/nextcloud/server/apps/text/node_modules/highlight.js/package.json)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/webpack/lib/Compilation.js:1768:28
    at /home/azul/code/nextcloud/server/apps/text/node_modules/webpack/lib/ContextModuleFactory.js:210:15
    at /home/azul/code/nextcloud/server/apps/text/node_modules/neo-async/async.js:2830:7
    at /home/azul/code/nextcloud/server/apps/text/node_modules/neo-async/async.js:6877:13
    at /home/azul/code/nextcloud/server/apps/text/node_modules/webpack/lib/ContextModuleFactory.js:180:26
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/Resolver.js:340:22
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/Resolver.js:408:21
    at eval (eval at create (/home/azul/code/nextcloud/server/apps/text/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/Resolver.js:408:21
    at eval (eval at create (/home/azul/code/nextcloud/server/apps/text/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:24:1)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:84:26
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/Resolver.js:408:21
    at eval (eval at create (/home/azul/code/nextcloud/server/apps/text/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:24:1)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/Resolver.js:408:21
    at eval (eval at create (/home/azul/code/nextcloud/server/apps/text/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:55:1)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/ConditionalPlugin.js:50:25

@azul
Copy link

azul commented Oct 29, 2021

I think you need to start debug here https://github.com/webpack/webpack/blob/main/lib/ContextModuleFactory.js#L155

The one entry in `dependencies` at that point
category: "esm"
chunkName: "highlight/[request]"
exclude: null
groupOptions: {}
include: null
mode: "lazy"
namespaceObject: true
recursive: true
referencedExports: null
regExp: /^\.\/.*$/
request: "highlight.js/lib/languages"
typePrefix: "import()"
Looks like it is really trying to resolve `highlight.js/lib/languages`.

I think there should not be an attempts to resolve highlight.js/lib/languages in the first place. But maybe that's okay and should succeed?

@azul
Copy link

azul commented Oct 29, 2021

Trace of the inner error
Error: Package path ./lib/languages is not exported from package /home/azul/code/nextcloud/server/apps/text/node_modules/highlight.js (see exports field in /home/azul/code/nextcloud/server/apps/text/node_modules/highlight.js/package.json)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js:104:7
    at Hook.eval [as callAsync] (eval at create (/home/azul/code/nextcloud/server/apps/text/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:22:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/home/azul/code/nextcloud/server/apps/text/node_modules/tapable/lib/Hook.js:18:14)
    at Resolver.doResolve (/home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/Resolver.js:407:16)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:74:17
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:118:13
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/forEachBail.js:16:12
    at onJson (/home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:108:6)
    at Array.<anonymous> (/home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:68:7)
    at runCallbacks (/home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:27:15)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:200:4
    at Array.<anonymous> (/home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:440:8)
    at runCallbacks (/home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:27:15)
    at /home/azul/code/nextcloud/server/apps/text/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:200:4
    at /home/azul/code/nextcloud/server/apps/text/node_modules/graceful-fs/graceful-fs.js:123:16
    at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:71:3)

@azul
Copy link

azul commented Oct 29, 2021

#14598 was an attempt at fixing this by ignoring exports in context resolvers. While this fixes the build it's also too permissive.

azul pushed a commit to nextcloud/text that referenced this issue Nov 9, 2021
Use path to the node_modules folder to work around
webpack/webpack#13865

Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.7.3 to 11.3.1.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md)
- [Commits](highlightjs/highlight.js@10.7.3...11.3.1)

---
updated-dependencies:
- dependency-name: highlight.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
azul pushed a commit to nextcloud/text that referenced this issue Nov 9, 2021
Use path to the node_modules folder to work around
webpack/webpack#13865

Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.7.3 to 11.3.1.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md)
- [Commits](highlightjs/highlight.js@10.7.3...11.3.1)

---
updated-dependencies:
- dependency-name: highlight.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
azul pushed a commit to nextcloud/text that referenced this issue Nov 9, 2021
Use path to the node_modules folder to work around
webpack/webpack#13865

Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.7.3 to 11.3.1.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md)
- [Commits](highlightjs/highlight.js@10.7.3...11.3.1)

---
updated-dependencies:
- dependency-name: highlight.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
azul pushed a commit to nextcloud/text that referenced this issue Nov 9, 2021
Use path to the node_modules folder to work around
webpack/webpack#13865

Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.7.3 to 11.3.1.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md)
- [Commits](highlightjs/highlight.js@10.7.3...11.3.1)

---
updated-dependencies:
- dependency-name: highlight.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@ichangela-ontic
Copy link

ichangela-ontic commented Jun 28, 2023

I got a temporary hack for this issue. import file normaly from package in a file then do dynamic import of that file.

src/components/externalForm/fwkComponentOnticFormRenderer.tsx

import { OnticFormRenderer } from "fwk-components";  // our internal package. which I was not able to dynamic import directly
export default OnticFormRenderer;
const OnticFormRenderer = dynamic(
    // https://github.com/webpack/webpack/issues/13865
  () => import('./fwkComponentOnticFormRenderer'),
  {
    ssr: false,
  }
);

@Hypnosphi
Copy link
Contributor

@ichangela-ontic unfortunately it doesn't help with cases like the one mentioned in this issue, where the import string itself is dynamic:

const module = await import(
  `highlight.js/lib/languages/${langName.value}`
)

@dobromir-hristov
Copy link

If you add a webpack alias to highlight.js, you can then use that instead of a relative path

// this uses webpack-chain, but the idea is the same
  config.resolve.alias.set('highlight-js-alias', path.dirname(require.resolve('highlight.js/package.json')));

then you can do

const file = await import(
          /* webpackChunkName: "highlight-js-[request]" */
          `highlight-js-alias/lib/languages/${file}`
        );

The benefit of this, is that in a monorepo setup for example, webpack can find highlight.js using node's resolving mechanisms, so if things get hoisted up, you dont have to worry about that.

@alexander-akait
Copy link
Member

Also need to fix #17737

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Priority - High
Development

Successfully merging a pull request may close this issue.