2

I already spent more than a day searching for a solution. I am new to JavaScript, so maybe I missed the solutions adressed to experienced JS devs. The 3rd party script I need to use in a single file vue component (or globally in my app if that's the only way) has the following pattern:

(function (win) {
  win.MyUtil = {
    "func1": function func1() { ... },
    "func2": function func1() { ... }
  }
}(window));

This extends the browser's Window object, so that MyUtil is globally visible, right?

Then I added a script tag to my index.html file's head:

The script file was in /my_project_folder/src/assets. I also tried many different paths in the src attribute (e.g. "./assets/my_util.js" or "<%= BASE_URL %>/assets/my_util.js" and moved the file to different actual folders. I read somewhere there should be a folder "/my_project/static". I tried that.

The result was always the same. The browser shows this warning (translated to English myself): "The script 'http://localhost:8080/@/assets/my_util.js' was loaded, although its MIME type (text/html) was not a valid MIME type for JavaScript." I think this indicates that the script was actually loaded. Of course I also tried with specifying the correct MIME type without success. However when I add alert("my_util") to the script, no message is shown.

The code in my vue component then throws an error "ReferenceError: MyUtil is not defined". This happens in the "mounted" hook, but also later in a button click, so it is not a matter of loading order.

What is going wrong here? How can I fix it?

By the way it works fine in plain html.

7
  • How are you loading the script? Are you importing it in your VueJS component, or including it as <script> tag? And I suppose you are using VueCLI? Commented Apr 6, 2020 at 13:47
  • You have a syntax error in the definition of MyUtil: separate properties func1, func2 with a ,. Commented Apr 6, 2020 at 13:49
  • import my_util from '@/assets/my_util.js' Commented Apr 6, 2020 at 13:57
  • And then using in the template, make sure to create a computed prop for the imported object. Otherwise, template doesn't understand what you imported. Commented Apr 6, 2020 at 14:04
  • @collapsar thank you, I have the comma added. Commented Apr 6, 2020 at 18:43

2 Answers 2

1

There seems to be no real solution, which means no solution without modifying the original 3rd party script. The reason is that the 3rd party script consists of an "Immediately Invoked Function Expression" (IIFE):

(function (win) {
  win.MyUtil = {
    "func1": function func1() { ... },
    "func2": function func1() { ... }
  }
}(window));

So I had to modify the third party script, which is what I wanted to avoid. Thanks to Rishinder (VPaul) who pointed to the right direction. Now it is a "Module" that exports an object:

var MyUtil
export default MyUtil = {
  func1: function() { ... },
  func2: function() { ... }
}

In the Vue.js single file component file (*.vue) it can be imported like this (if it is in the same folder as the *.vue file):

<script>
    import MyUtil from "./my_util.js"
    // code using MyUtil goes here
</script>
Sign up to request clarification or add additional context in comments.

Comments

1

I think you're trying to work with VueJS in the most naive way, where you import vuejs in the script tag in your html.

Not saying that there's something wrong with it. However, this way limits you to avail the flexibility that Vue provides. The best way is to install vue using NPM or vue-cli (https://v2.vuejs.org/v2/guide/installation.html).

Once you have a project setup using vue-cli or NPM (or vuejs with babel or webpack), it lets you use the es6 import syntax, especially when using single file components (https://v2.vuejs.org/v2/guide/single-file-components.html). In this style, your components live in their own files and each component has a <script> block where you can import stuff.

However, you need to learn how to create your first Vue component before reaching the point where you can ues VueJS like it's used in the industry. You can follow VueJS docs (https://v2.vuejs.org/v2/guide/) for doing the same.

Once you create components, you'll need to know about computed props ()https://v2.vuejs.org/v2/guide/computed.html and how to use imported files/classes in the template using computed props. There's a lot to learn :)

I hope this helps.

8 Comments

Thank you. I am using vueCLI with all the default and recommended plug-ins: babel, eslint, prettier, router, cli-service. I am already learning for a few weeks and I understood the basics. My problem is the poor and confusing documentation on vuejs.org. For example your link to the single-file component page shows a <script> tag with src attribute. It does not tell that more than one script tag is allowed. So the reader will conclude that there may be a single script tag with either code or a src tag.
in you previous comment you recommended an "import" statement. In this answer you recommend a "script" block to import stuff. Which is the correct way in a single file component?
Rishinder, the pages you linked do not clarify the connection beween "computed props" and "imported object". Could you please elaborate and maybe give some lines of code? Another question is, do I still have to add a script tag to the index.html file?
Glad to hear that you've setup the project the right way. So there's just one script tag in a component. You name your components with extension .vue. There's no need change the html file. The one created by vue-cli only has a container to let vue mount itself. The app is mounted in main.js and the root container is App.vue. This is the file where you can try what I recommended. The structure of a vue file consists of <template>, <script> and if required <style> tags. Just one of each. You import your library in <script> tag as mentioned in vue docs. I hope it helps.
I added "import myutil from '@/assets/my_util.js'" to the <script> tag. Now I get the error TypeError: "_assets_myutil_js__WEBPACK_IMPORTED_MODULE_0___default.a.func1 is not a function" Rishinder, you wrote something about adding the imported object to a computed property. Perhaps this will solve the error. How do I do that? And please note that the 3rd party script does not return the object. It adds it to the Window object.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.