Parcel: Cannot use functions in HTML from referenced script

Created on 26 Jun 2018  路  16Comments  路  Source: parcel-bundler/parcel

馃悰 bug report

When attempting to use a function (in an onclick and onload, specifically) from an imported script in HTML (i.e <script src="test.js"></script>), I get ReferenceError: x is not defined for every function. This has been tested only when running locally in the default parcel dev mode.

馃帥 Configuration (.babelrc, package.json, cli command)

{
  "scripts": {
    "build": "parcel build src/index.html --detailed-report",
    "dev": "parcel src/index.html"
  },
  "dependencies": {},
  "devDependencies": {
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.7.0",
    "parcel-bundler": "^1.9.2"
  },
  "babel": {
    "presets": [
      [
        "env",
        {
          "targets": {
            "browsers": [
              "last 3 versions",
              "not ie < 11"
            ]
          }
        }
      ]
    ],
    "plugins": [
      "transform-runtime"
    ],
    "comments": false
  },
  "browserlist": [
    "last 3 versions",
    "not ie < 11"
  ]
}

馃 Expected Behavior

When I call a function in HTML that is defined in an imported file, I should run that function

馃槸 Current Behavior

Uncaught ReferenceError: login is not at HTMLButtonElement.onclick ((index):27)

馃拋 Possible Solution

Not really sure. I've tried using export on my functions as well. Only directly inlining the script seems to work.

馃敠 Context

I'd like to be able to define some simple JS functions in a separate file from my HTML. Currently, I'm building a static login page, but the login logic is complex enough that I'd like for it to live in a separate file.

馃捇 Code Sample

https://github.com/JonathanTroyer/Parcel-html-import

馃實 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.9.3
| Node | 8.11.1 OR 10.5.0
| npm/Yarn | 5.6.0/1.7.0
| Operating System | Windows 10 Pro Version 1803 Build 17134.112

Bug

Most helpful comment

All 16 comments

We can expose functions or variables to window object if

  • JS file is included by a script tag in html
  • function/variable has been exported

For example, in index.html we have:

<script src="main.js"></script>

in main.js we have:

export function foo() {}

Then we should be able to invoke foo anywhere in index.html.

The change can be made in prelude.js where we can copy over from mainExports to this which is window.

@DeMoorJasper do you have any thoughts on this?

Isn鈥檛 this already possible with 鈥攇lobal <some variable name> ?

Sent with GitHawk

I think --global <variable name> defines a namespace on window object. For example, --global entry will set foo to window.entry object. In the html, we need to call entry.foo instead of foo. IMO, calling a method in HTML from referenced JS is a valid use-case and should be just working without any extra effort from an application developer's point of view.

Seems to work as expected to me. (no object gets created)

https://github.com/DeMoorJasper/parcel-global-var-test

Thanks @DeMoorJasper for your example! But I still cannot figure out how to extend it to the case where we have multiple functions defined in the JS file, since global variable can only be assigned to one function?

In that case you'd have to use an object, similar to how you'd do it when developing a library.
It's sort of a standard for creating bundles that expose global variables.

I tried this, but no luck "build": "parcel ./src/SpaceInvaders --public-url ./dist --target=browser --out-file=SpaceInvaders.js --global SpaceInvaders"


I originally tried:
How do you expose exports from a parcel bundle globally?

I want access to it from the window:

Ie I import the parcel bundle here:
https://github.com/QuantumInformation/youtube-space-invaders/blob/development/demo/index.html#L6

and try to use it here:
https://github.com/QuantumInformation/youtube-space-invaders/blob/development/demo/index.html#L52

but SpaceInvaders is undefined

note: SpaceInvaders is exported from:
https://github.com/QuantumInformation/youtube-space-invaders/blob/development/src/SpaceInvaders.ts#L14

note2: the build command is "build": "parcel ./src/SpaceInvaders --public-url ./dist --target=browser --out-file=SpaceInvaders.js"

Could you refer to this example: https://github.com/buronnie/parcel-global-var-test? The class name is sitting in the namespace of SpaceInvaders. Still not exactly what you want, but at least it is working 馃槃

@buronnie thanks for the example! However, it does not seem to work when there's CSS imports. I've updated the repo to display this behavior. This may be a separate issue, so let me know if I should open a new issue and close this one.

I use postcss imports

@buronnie I tried your example, it works:

image

In my example, adding .ts seems to have fixed the initial issue:

image

I'm having the same issue of @JonathanTroyer when I'm using CSS.

This has actually resurfaced in parcel@next now that the --global flag is gone.

Hi there,
Has this issue been resolved now?
I have come here because I have the same issue, I have create a SO question, perhaps you can take a look!

Hello. I have encountered a similar issue. Is there any update on this please?

Was this page helpful?
0 / 5 - 0 ratings