2

I am trying to import a local JS file into a single file component in a Vue application. My application is a scaffold generated by vue-CLI (ver 3.8.2).

Here are my relevant code snippets (all other code in application is unchanged from generated code):

/path/to/app-vue/src/components/HelloWorld.vue

<template>
  <div class="hello">
    <Module1/>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import Module1 from './Module1.vue';

@Component({
  components: {
    Module1,
  }
})
export default class HelloWorld extends Vue {
  @Prop() private msg!: string;
}

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

/path/to/vue-app/src/components/Module1.vue

<template>
    <div class="module1">
        Module2
    </div>
</template>

<script>
import { Component, Prop, Vue } from 'vue-property-decorator';
import Module2 from './Module2.vue';

@Component({
  components: {
    Module2,
  },
})
export default class Module1 extends Vue {
}
</script>

/path/to/vue-app/Module2.vue

<template>
    <div id='demo'>
    </div>
</template>

<script>
import foo from '../assets/js/foo';

foo.writeSomething('#demo');
</script>

/path/to/vue-app/src/assets/js/foo.js

function writeSomething(el) {
  elem = window.document.getElementById(el);
  elem.innerHTML = 'Hello World!';
}

export default {
    writeSomething
}

When I run npm run serve and navigate to '/' in the browser, I get the following error messages in the console:

"export 'default' (imported as 'mod') was not found in '-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Module2.vue?vue&type=script&lang=js&'

And in the browser DevTools console, I get the following stack trace:

Uncaught TypeError: _assets_js_foo__WEBPACK_IMPORTED_MODULE_0__.writeSomething is not a function
    at eval (Module2.vue?df9f:9)
    at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/Module2.vue?vue&type=script&lang=js& (app.js:1078)
    at __webpack_require__ (app.js:767)
    at fn (app.js:130)
    at eval (Module2.vue?35cf:1)
    at Module../src/components/Module2.vue?vue&type=script&lang=js& (app.js:3448)
    at __webpack_require__ (app.js:767)
    at fn (app.js:130)
    at eval (Module2.vue?6104:1)
    at Module../src/components/Module2.vue (app.js:3436)

How do I load local javascript files into a Single File Component, and use functions defined in the loaded Javascript (within the component)?

2 Answers 2

1

You need to explicitely export the function and import it using its name.

Module2.vue

import { writeSomething } from '../assets/js/foo.js';
writeSomething('#demo');

export default { ...

foo.js

export function writeSomething(el) {
  elem = window.document.getElementById(el);
  elem.innerHTML = 'Hello World!';
}

If you are using typescript, make sure that you can import js modules

you can also export a default module

function writeSomething(el) {
  elem = window.document.getElementById(el);
  elem.innerHTML = 'Hello World!';
}


export default {
    writeSomething
}

and import it as

import foo from '../assets/foo.js';

// ...
foo.writeSomething('#demo');
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. When I make the modifications you suggested, I get the following error in the browser dev console: Module2.vue?df9f:8 Uncaught TypeError: _assets_js_foo__WEBPACK_IMPORTED_MODULE_0___default.a.writeSomething is not a function. I have modified my question with your suggestion though.
Make sure your component Module 2 has a default export! (Look at the last line of the first codeblock in my answer. In Module1, you are importing Module2. But it seems Module2 is not exporting a component. If you want your script to run, it needs to export something even ‘export default {}’. Also, it looks like you want to use the mounted hook in Module2 to call ‘writeSomething’
There's literally dozens of answers on SO and Vue forum for how to do this, and didn't get any of those to work. This is the best one, clean readable very straight forward. Nice, thank you
Glad it helped @GeneBo!
0

Export default should specify a name like below:

export default writeSomething;

Named Exports

  • Can export multiple values
  • MUST use the exported name when importing

Default Exports

  • Export a single value
  • Can use any name when importing

You can see more about Named Export and Default Export here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.