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

Accessing document.currentScript in async chunks returns null in Firefox #10510

Closed
Justineo opened this issue Mar 6, 2020 · 9 comments
Closed
Labels

Comments

@Justineo
Copy link

Justineo commented Mar 6, 2020

Bug report

What is the current behavior?

If modules in an async chunk calls document.currentScript, the result will be null in Firefox while other browsers returns the expected <script> element.

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

The details of the issue is at this repo.

What is the expected behavior?

Developers should have a way to workaround Firefox's potential bug. eg. webpack provide a __webpack_current_script__ inside each async chunk.

Details

The entry file is index.js which contains only:

import("./async")

Where async.js calls document.currentScript:

console.log(document.currentScript);

document.getElementById("output").textContent = document.currentScript
  ? document.currentScript.src
  : "null";

After we compiled index.js with webpack, two files will be produce into the dist folder:

dist/
  1.js
  main.js

After introducing the main.js in index.html, we'll notice that in Chrome, we can see the correct script src:

$PROJECT_PATH/dist/1.js

While in Firefox we got null.

After I did a little investigation, the only difference I found is that Firefox is treating scripts run inside a micro task the same way as those in timeout callbacks, making document.currentScript being evaluated as null. While in other browsers, it's evaluated to the expected script element.

Per the HTML spec:

(document.currentScript) Returns null if the Document is not currently executing a script or SVG script element (e.g., because the running script is an event handler, or a timeout), or if the currently executing script or SVG script element represents a module script.

I'd say it's a little ambiguous about whether for micro tasks it should return null. Plus this section is labelled as "non-normative". But it's indeed unexpected that browsers handle this differently. I've filed an issue on Bugzilla here.

Though it's a potential bug on the Firefox side, but I think we have a chance to fix this on the webpack side.

When webpack generates an async chunk, we can evaluate document.currentScript synchronously upfront, and save it to a private variable like __webpack_current_script__ so that if developers have a chance to work this around by try accessing __webpack_current_script__ instead of document.currentScript.

Thanks for your time!

Other relevant information:
webpack version: 4.42.0
Node.js version: 12.13.1
Operating System: macOS 10.15.1
Additional tools: /

@sokra
Copy link
Member

sokra commented Mar 6, 2020

why do you need access to the currect script?

@Justineo
Copy link
Author

Justineo commented Mar 7, 2020

Currently when building with Vue CLI's lib mode, document.currentScript is used to help set publicPath for __webpack_require__ so that assets can be imported dynamically. When importing a lib built with such setup in webpack-based projects, we may reproduce this issue. A fix on Vue CLI's side is already proposed (vuejs/vue-cli#5247) but the fix is kind of cumbersome and other projects may come across same problem.

@sokra
Copy link
Member

sokra commented Mar 9, 2020

so that assets can be imported dynamically

So this helper need to imported before any async chunk. But why do you need document.currentScript in an async chunk?

@Justineo
Copy link
Author

Justineo commented Mar 9, 2020

For example, if a library built with Vue CLI is imported in a project and is later bundled inside an async chunk, document.currentScript will be evaluated inside an async chunk.

@webpack-bot
Copy link
Contributor

This issue had no activity for at least three months.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@webpack-bot
Copy link
Contributor

Issue was closed because of inactivity.

If you think this is still a valid issue, please file a new issue with additional information.

@aryaroudi
Copy link

For example, if a library built with Vue CLI () is imported in a project and is later bundled inside an async chunk, document.currentScript will be evaluated inside an async chunk.

Valid point, I'm facing the same issue now, any fix for that?

image

@Herz3h
Copy link

Herz3h commented Feb 8, 2021

Is there a way to get currentScript tag in webpack ? From what I read in async chunk, it'll always be null, so I tried putting it in the entrypoint, but it still is null, any alternative ? @sokra

@alexander-akait
Copy link
Member

@Herz3h Can you provide reproducible test repo and browser version where it is null?

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

No branches or pull requests

6 participants