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.
2 Answers 2
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>
Comments
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
.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.
<script>tag? And I suppose you are using VueCLI?MyUtil: separate propertiesfunc1,func2with a,.import my_util from '@/assets/my_util.js'