Posted By: Anonymous
I’m using Typescript & Webpack. My code is below. I’m running it in chrome and it gives the error:
Uncaught TypeError: vue_1.default is not a constructor
at Object.defineProperty.value (Index.ts:3)
at __webpack_require__ (bootstrap f29fbbb047d131556dcf:19)
at Object.defineProperty.value (bootstrap f29fbbb047d131556dcf:62)
at bootstrap f29fbbb047d131556dcf:62
I have added the import, also did the resolve -> alias -> vue part. And tried a whole bunch of other stuff but it didn’t work. I also played around with the tsconfig file but no luck.
How do I solve this?
webpack.config.js
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
module.exports = {
context: __dirname,//another dir +"/app"
// devtool: debug ? "inline-sourcemap" : null,
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
entry: "./code/client/scripts/Index.ts",
output: {
path: __dirname + "/code/client/views",
filename: "scripts.min.js"
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({mangle: false, sourcemap: false}),
new webpack.IgnorePlugin(/fs/),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
})
],
node: {
fs: 'empty',
child_process: 'empty',
},
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
alias: {
vue: 'vue/dist/vue.js'
},
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /.tsx?$/, loader: "awesome-typescript-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /.js$/, loader: "source-map-loader" }
]
},
};
tsconfig.js
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"noImplicitThis": true,
"sourceMap": true,
"strictNullChecks": true,
"removeComments": false,
"moduleResolution": "node",
"types": [
"node",
"mocha",
"chai"
],
"typeRoots": [
"node_modules/@types"
]
},
"exclude": [
"node_modules"
]
}
index.ts
import Vue from "vue"
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
}
})
console.log(app)
html
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
</div>
Solution
The vue/dist/vue.js
file does not have a default export, but Vue also provides an ES module version: vue/dist/vue.esm.js
. You want to use this one, since you are using it as an ES module with the import
statement.
Your alias should be:
alias: {
'vue': 'vue/dist/vue.esm.js'
},
Answered By: Anonymous
Related Articles
- Worker Script Failing to Load for Vue Webpack Built App
- Correctly configure webpack-dev-middleware with vuejs…
- disable vue-cli webpack encoding image base64
- TypeError: Cannot read property ‘webpackJsonp’ of undefined
- webpack-dev-server npm run dev throwing TypeError: Cannot…
- How to set up webpack-hot-middleware in an express app?
- Login with facebook android sdk app crash API 4
- Aurelia, navigate is not updating viewport
- Svelte application not working on android version 6.0.1 or…
- Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or…
Disclaimer: This content is shared under creative common license cc-by-sa 3.0. It is generated from StackExchange Website Network.
Приветствую всех профи и начинающих.
Затягивать «слишком» долго не буду, поэтому перейду к сути:
Дело в том, что я создал .vue компонент, сделал main.js файл, ну и .html, в которых «вроде бы» всё сделал правильно, но не работает как надо)
Когда я нажимаю на остальные роуты, по типу «+ Бренды, Блог…» — то они вроде бы работают как надо.
Я создал новый компонент «TEST.vue», но он как бы не отображается от слова совсем, я уже более 7-ми часов сижу над этой дилеммой, и не понимаю почему не работает.
Кстати, когда закомментировал всё содержимое main.js — роутер продолжал работать, но вот тот же TEST.vue — так же нет.
Вот код:
Index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue-router</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<header>
<div class="header-wrapper">
<img src="http://acmelogos.com/images/logo-8.svg" alt="" class="logo">
<nav>
<router-link to="/brands">+ Бренды</router-link>
<router-link to="/blog" active-class="grey">+ Блог</router-link>
<router-link to="/projects">+ Проекты</router-link>
<router-link to="/contacts">+ Контакты</router-link>
<router-link to="/capes">+ TEST</router-link>
</nav>
</div>
</header>
<router-view></router-view>
</div>
<script src="build/bundle.js"></script>
</body>
</html>
main.js:
var Vue = require('vue')
// var VueRouter = require('vue-router') // BUG: Вызывает ошибку "TypeError: o is not a constructor"
// Чтобы исправить данную ошибку необходимо использовать один из следующих вариантов подключения
var VueRouter = require('vue-router').default
// import VueRouter from 'vue-router'
var capes = require('./views/TEST.vue')
var Brands = require('./views/Brands.vue')
var Contacts = require('./views/Contacts.vue')
var Projects = require('./views/Projects.vue')
var Blog = require('./views/Blog.vue')
var Post = require('./views/Post.vue')
Vue.use(VueRouter)
var router = new VueRouter({
routes: [
{ path: '/capes', component: capes },
{ path: '/brands', component: Brands },
{ path: '/contacts', component: Contacts },
{ path: '/projects', component: Projects },
{ path: '/blog', component: Blog },
{ path: '/post/:id', name: 'post', component: Post }
]
})
new Vue({
el: '#app',
router: router
})
Ну и тот самый TEST.vue:
<template>
<div id='okey'>
<h1>А где вообще сам роут?????</h1>
</div>
</template>
<script>
export default {
}
</script>
<style>
#okey {
color: black;
}
</style>
P.s. я более чем уверен, что проблема таится в самом лёгком, но такового я не знаю.
Если Вы мне поможете — то я, а так же возможно другие, столкнувшиеся с этой проблемой — будут знать как это решить, и будут благодарны Вам.
Dec 9, 2020
Vue 3 has made some slight changes to how Vue components work. The basic syntax for creating Vue components hasn’t changed much, but there’s a lot
of new features for you to take advantage of. Here’s an overview of how components have changed
in Vue 3.
Components are Scoped to Apps
If you drop Vue 3 into an existing Vue 2 codebase, odds are the first error you’ll see is TypeError: Vue is not a constructor
. That’s because the Vue
global is now no longer a class. Instead of using
new Vue()
to create a new app, you should use Vue.createApp()
. And, instead of registering
components globally using Vue.component()
, you register components on apps using app.component()
.
For example, below is a component in Vue 2:
Vue.component('hello', {
data: () => ({
name: 'World'
}),
template: `
<div>
<div>
<input v-model="name"></input>
</div>
<h1>Hello, {{name}}</h1>
</div>
`
});
// Displays "Hello, World" initially, changes based on input
const app = new Vue({
template: '<hello></hello>'
});
app.$mount('#content');
Below is how you would rewrite it for Vue 3:
// Create an app using `createApp()` that uses the `hello` component
const app = Vue.createApp({
// Displays "Hello, World" initially, changes based on input
template: '<hello></hello>'
});
// Register the `hello` component
app.component('hello', {
data: () => ({
name: 'World'
}),
template: `
<div>
<div>
<input v-model="name"></input>
</div>
<h1>Hello, {{name}}</h1>
</div>
`
});
app.mount('#content');
That’s it! There are 4 necessary changes:
- Use
createApp()
instead ofnew Vue()
- Use
app.component()
instead ofVue.component()
- Switch the order of definition, so you define the
app
before the component - Use
mount()
instead of$mount()
$emit()
Changes
The basics still work: you still define props
the same way, and you can still $emit()
events
from your component. The only difference is that you now need to explicitly define what events your
component emits like how you explicitly define a list of props
.
Below is an example of how you can use $emit()
with Vue 2:
Vue.component('input-name', {
data: () => ({ name: 'World' }),
// When you click the "Update" button, Vue will emit an event `update`
// to the parent, with the current state of 'name'.
template: `
<div>
<input type="text" v-model="name">
<button v-on:click="$emit('update', name)">
Update
</button>
</div>
`
});
const app = new Vue({
data: () => ({ name: 'World' }),
// To listen to the 'update' event, you create the `input-name`
// component with a `v-on:update` attribute. `$event` contains
// the value of the 2nd parameter to `$emit()`.
template: `
<div>
<div>
<input-name v-on:update="setName($event)"></input-name>
</div>
<h1>Hello, {{name}}</h1>
</div>
`,
methods: {
// Define a method that Vue will call to handle the 'update' event.
setName: function(v) {
this.name = v;
}
}
});
app.$mount('#content');
Below is how you would change the above example to work with Vue 3. Besides the usual createApp()
and app.component()
changes, this example also adds a list of events the component emits
.
const app = Vue.createApp({
data: () => ({ name: 'World' }),
// To listen to the 'update' event, you create the `input-name`
// component with a `v-on:update` attribute. `$event` contains
// the value of the 2nd parameter to `$emit()`.
template: `
<div>
<div>
<input-name v-on:update="setName($event)"></input-name>
</div>
<h1>Hello, {{name}}</h1>
</div>
`,
methods: {
// Define a method that Vue will call to handle the 'update' event.
setName: function(v) {
this.name = v;
}
}
});
app.component('input-name', {
data: () => ({ name: 'World' }),
// New property in Vue 3:
emits: ['update'],
// When you click the "Update" button, Vue will emit an event `update`
// to the parent, with the current state of 'name'.
template: `
<div>
<input type="text" v-model="name">
<button v-on:click="$emit('update', name)">
Update
</button>
</div>
`
});
app.mount('#content');
The setup()
Hook
The Composition API is one of the most touted improvements in Vue 3. And the Composition API starts with the setup()
function, which is similar to the created()
hook, but much more powerful. For example, you can use the Vue global’s onMounted()
function to add a new mounted()
hook to your component from the setup()
function:
const app = Vue.createApp({
data: () => ({ to: 'World' }),
template: '<hello v-bind:to="to"></hello>'
});
// Prints 'Mounted from component!' followed by 'Mounted from setup!'
app.component('hello', {
props: ['to'],
template: '<h1>Hello, {{to}}</h1>',
mounted: function() {
console.log('Mounted from component!');
},
setup: function(props) {
Vue.onMounted(() => console.log('Mounted from setup!'));
return {};
}
});
The most interesting part of the composition API is that it lets you define Vue components without explicitly instantiating a component using a syntax reminiscent of React hooks. For example, you can rewrite the above hello
component using just the setup()
function:
app.component('hello', {
props: ['to'],
setup: function() {
Vue.onMounted(() => console.log('Mounted!'));
return (props) => Vue.h('h1', 'Hello, ' + props.to);
}
});
Not only can you define hooks in setup()
, you can also return a render()
function and effectively define your template in the setup()
function as well as shown above.
The neat part of the Composition API is that you don’t have to use it. It’s just another tool in the
Vue utility belt. For example, we generally don’t recommend using JSX-like render()
functions because
we prefer plain old HTML templates for portability and versatility. But, in certain cases,
this pattern can be very useful, like if you’re migrating a legacy React app to Vue.
Vue School has some of our favorite Vue
video courses. Their Vue.js Master Class walks you through building a real
world application, and does a great job of teaching you how to integrate Vue
with Firebase.
Check it out!
More Vue Tutorials
- Methods in Vue
- Use the Ternary Operator for Conditionals in Vue
- Vue Email Validation
- How to Copy Content to the Clipboard in Vue
- Creating Computed Properties with Vue’s Composition API
- Toggle Visibility in Vue
- Add Global Variables to Vue JS Templates