Sitelet https://github.com/nodejs/node/issues/42504
Skip to content

import(data:text/javascript,) throw SyntaxError #42504

Description

@lovetingyuan

Version

v16.14.2

Platform

Darwin tingyuandeMacBook-Pro.local 21.1.0 Darwin Kernel Version 21.1.0: Wed Oct 13 17:33:23 PDT 2021; root:xnu-8019.41.5~1/RELEASE_X86_64 x86_64

Subsystem

No response

What steps will reproduce the bug?

const c = `
var config0 = {
  text: '{{ a => a === "aa" ? "bb" : "cc" }}'
};
var _configs = { "aa": config0 };
var configFiles = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  "default": _configs
}, Symbol.toStringTag, { value: "Module" }));
export { configFiles as default };
`;
import(`data:text/javascript,${c}`).then((res) => {
  console.log(res);
});

Just run the code with latest node, error is here:

data:text/javascript,var config0 = {  text: '{{ a => a === "aa" ?%20%22bb%22%20:%20%22cc%22%20}}'};var%20_configs%20=%20{%20%22aa%22:%20config0%20};var%20configFiles%20=%20/*%20@__PURE__%20*/%20Object.freeze(/*%20@__PURE__%20*/%20Object.defineProperty({%20%20__proto__:%20null,%20%20%22default%22:%20_configs},%20Symbol.toStringTag,%20{%20value:%20%22Module%22%20}));export%20{%20configFiles%20as%20default%20};:1
var config0 = {  text: '{{ a => a === "aa" 
                       ^^^^^^^^^^^^^^^^^^^^

SyntaxError: Invalid or unexpected token
    at ESMLoader.moduleStrategy (node:internal/modules/esm/translators:115:18)
    at ESMLoader.moduleProvider (node:internal/modules/esm/loader:289:14)
    at async link (node:internal/modules/esm/module_job:70:21)

but, in chrome, the code runs well, no error.
image

How often does it reproduce? Is there a required condition?

100% reproduce.

What is the expected behavior?

no error should be thrown, It seems related to ?(ternary operator).

What do you see instead?

node can not run the code, but chrome can run the same code.

Additional information

No response

Activity

  1. lovetingyuan commented on Mar 28, 2022

    @lovetingyuan
    Author

    A simpler example is here:

    const c = "const a = '?' === false;";
    import(`data:text/javascript,${c}`).then((res) => {
      console.log(res);
    });
  2. aduh95 commented on Mar 28, 2022

    @aduh95
    Contributor

    Yep, it looks like Node.js is acting differently than other JS runtimes. //cc @nodejs/loaders

    FWIW, you can workaround this by encoding special URL characters:

    const c = "const a = '?' === false;";
    import(`data:text/javascript,${encodeURIComponent(c)}`).then((res) => {
      console.log(res);
    });
  3. bmeck commented on Mar 28, 2022

    @bmeck
    Member

    Please encode special components and/or use base64 support in your data: URIs for cross environment stability, Firefox also fails in this case:

    image

    This failure is caused by a disagreement on if query parameters are valid on data: URIs. I'd note that according to new url() everything after the ? is a query parameter and is the main reason this behavior is as Node implemented it.

  4. lovetingyuan commented on Mar 29, 2022

    @lovetingyuan
    Author

    Yep, it looks like Node.js is acting differently than other JS runtimes. //cc @nodejs/loaders

    FWIW, you can workaround this by encoding special URL characters:

    const c = "const a = '?' === false;";
    import(`data:text/javascript,${encodeURIComponent(c)}`).then((res) => {
      console.log(res);
    });

    Thanks, It works on node16, but still failed on node14, but with base64 format, both will work well, like this:

    const c = "const a = '?' === false;";
    import(`data:text/javascript;base64,${Buffer.from(c).toString('base64')}`).then((res) => {
      console.log(res);
    });
  5. aduh95 commented on Mar 29, 2022

    @aduh95
    Contributor

    Yep, it looks like Node.js is acting differently than other JS runtimes. //cc @nodejs/loaders
    FWIW, you can workaround this by encoding special URL characters:

    const c = "const a = '?' === false;";
    import(`data:text/javascript,${encodeURIComponent(c)}`).then((res) => {
      console.log(res);
    });

    Thanks, It works on node16, but still failed on node14, but with base64 format, both will work well, like this:

    const c = "const a = '?' === false;";
    import(`data:text/javascript;base64,${Buffer.from(c).toString('base64')}`).then((res) => {
      console.log(res);
    });

    I think the fix was already backported to v14.18.0 (98259dc). Are you testing on an up-to-date version?

  6. lovetingyuan commented on Mar 29, 2022

    @lovetingyuan
    Author

    Yep, it looks like Node.js is acting differently than other JS runtimes. //cc @nodejs/loaders
    FWIW, you can workaround this by encoding special URL characters:

    const c = "const a = '?' === false;";
    import(`data:text/javascript,${encodeURIComponent(c)}`).then((res) => {
      console.log(res);
    });

    Thanks, It works on node16, but still failed on node14, but with base64 format, both will work well, like this:

    const c = "const a = '?' === false;";
    import(`data:text/javascript;base64,${Buffer.from(c).toString('base64')}`).then((res) => {
      console.log(res);
    });

    I think the fix was already backported to v14.18.0 (98259dc). Are you testing on an up-to-date version?

    yes yes, 14.18.0 is ok,👍 (the error occurs on 14.17.1)

  7. lovetingyuan commented on Mar 29, 2022

    @lovetingyuan
    Author

    The problem is solved, if there is no other questions, I will close this issue after a few days. Thank you very much.

  8. lovetingyuan commented on Mar 29, 2022

    @lovetingyuan
    Author

    The problem is solved, if there is no other questions, I will close this issue after a few days. Thank you very much.

    Always use encodeURIComponent with source code string in dynamic importing data url, and better to avoid using this(not a best practice)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions