Trying to follow some Vue tutorials and I can't currently import Vue in a .js
file and then import this file in my index.html
. This is how I'm importing the script in my index.html
:
<script src="./js/main.js" type="module"></script>
If I do this in my main.js
file:
import Vue from 'vue';
I get the following error in the browser console:
Uncaught TypeError: Failed to resolve module specifier "vue". Relative references must start with either "/", "./", or "../".
If my import line to:
import Vue from '../../node_modules/vue';
Then I get a different error:
http://localhost:63342/vue-official-tutorial/node_modules/vue net::ERR_ABORTED 404 (Not Found)
What am I doing wrong?
The way you can use ES modules in your Browser directly (as of June 2020) is thus:
Use the ESM version of your dependencies (the one that has import
instead of require
). For example, Vue ESM version is available at: https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0-beta.14/vue.esm-browser.js
Make your browser work with the experimental importmap
feature. Import maps are a new web recommendation, not yet supported in mainstream browsers. https://wicg.github.io/import-maps/#import-map In Chrome this is under chrome://flags#enable-experimental-productivity-features
(latest Chrome versions moved this under chrome://flags#enable-experimental-web-platform-features
)
Create an importmap
in your HTML file. It only works with inline <script>
tags at the moment in Chrome. For example:
<script type="importmap">
{ "imports": {
"vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.37/vue.esm-browser.min.js",
"vue-router": "https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.16/vue-router.esm-browser.min.js"
} }
</script>
<script type="module" src="./main.js"></script>
Full example:
<html>
<body>
<script type="importmap">
{ "imports": {
"vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.37/vue.esm-browser.min.js",
"vue-router": "https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.16/vue-router.esm-browser.min.js"
} }
</script>
<script type="module">
import { createRouter, createWebHistory } from 'vue-router'
import { createApp } from 'vue'
const router = createRouter()
export default createApp({
router
})
</script>
</body>
</html>
Using ES6 modules without Webpack
If you are working with ES6 then you should NOT manually inserting your main.js
into index.html
- this will be handled by Webpack. Actually, the simplest tutorial for Vue goes like this:
./dist
folder of your projectAlso, you should import Vue like this
import Vue from 'vue';
and not like this
import Vue from '../../node_modules/vue';
Okay, if you insist on going through the beginners' path and not using Webpack and single-file Vue components - then you should start like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<title>My beginners project</title>
<link rel="stylesheet" type="text/css" href="/assets/css/styles.css" />
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<!-- templates for your components -->
<template id="login">
<div>test</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue-router.js"></script>
<!-- code for your components -->
<script type="text/javascript" src="/app/login.js"></script>
<!-- Vue Root component should be last -->
<script type="text/javascript" src="/app/app.js"></script>
</body>
</html>
And your /app/app.js
will look like this:
var badRoute = Vue.component('bad-route', {
template: '<div id="bad_route"><h1>Page Not Found</h1><p>Sorry, but the page you were trying to view does not exist.</p></div>'
});
var vue_router = new VueRouter({
base: '/app'
, mode: 'hash'
, routes: [{
path: '/'
, redirect: '/login'
}, {
path: '/login'
, component: loginForm
, name: 'LOGIN'
}, {
path: '*', // should be last, otherwise matches everything
component: badRoute
, name: 'NOT FOUND'
}]
});
// Main application
var vue_app = new Vue({
router: vue_router
, })
.$mount('#app');
And your /app/login.js
component will look like this:
var loginForm = Vue.component('login-form', {
template: '#login', // should match the ID of template tag
data: function() {
var a = {
username: ''
, password: ''
, };
return a;
}
, methods: {}
});
You can only use "import vue..." if you are using the CLI and webpack, etc.
If you are using Vue directly in a web page, you can follow the instructions at https://v2.vuejs.org/v2/guide/installation.html#Direct-lt-script-gt-Include and include a line like this in your HTML file:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
Do this before you import your own script, and then Vue
will be defined and you don't need to import it again. Import your script without the "module" attribute. In the script, you can run:
var x = new Vue({
el: '#myApp',
... all the other stuff ...
})
This assumes that somewhere on your HTML page you have:
<div id=myApp></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With