Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import Vue in Single File Component when using TypeScript?

I have a Single File Component and I need to import Vue:

<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
...
@Component({...})
export class Comp extends Vue {...}

I'm importing vue.js as module in the browser:

<script type="module" src="module/vue/vue.js"></script>

but I get the error

Uncaught TypeError: Class extends value undefined is not a constructor or null

somewhere inside of an eval() which vue-cli-service --target lib generates. I'm loading the SFC as a module, too:

<script type="module" src="module/comp/comp.js"></script>

As a workaround, I tried to add the imports at the top of comp.js:

import Vue from '/module/vue/vue.js'
import Component from '/module/vue-class-component/vue-class-component.js'
(function webpackUniversalModuleDefinition(root, factory) {
...

but that doesn't help.

How can I rewire the imports to the paths that will be used on the web server? I checked the options of webpack but only found resolve which seems to help webpack find stuff while it packages. I need an "output rewrite" kind of option.

Note that I'm using ES modules, not CommonJS or RequireJS. tsconfig.json:

compilerOptions: {"target": "ES2016", module: "ES2015" } 

Update I tried to put the final path into the .vue file and use configureWebpack.resolve.alias in vue.config.js to allow the Vue compiler to locate the module but that also doesn't work.

vue.config.js:

module.exports = {
    runtimeCompiler: true,
    configureWebpack: {
        externals: [
            'module/vue/vue',
            'module/vue-class-component/vue-class-component',
        ],
        resolve: {
            alias: {
                'module/vue/vue': 'vue/dist/vue.esm.js',
                'module/vue-class-component/vue-class-component': 'vue-class-component/dist/vue-class-component.esm.js'
            }
        },
    }
}

comp.vue:

...
import Vue from './module/vue/vue'
import Component from 'module/vue-class-component/vue-class-component'

just gives

ERROR in .../src/comp.vue
16:17 Cannot find module 'module/vue/vue'.
like image 804
Aaron Digulla Avatar asked Sep 17 '19 10:09

Aaron Digulla


People also ask

Can I use Vue with TypeScript?

Vue is written in TypeScript itself and provides first-class TypeScript support. All official Vue packages come with bundled type declarations that should work out-of-the-box.

How do I import Vue component into Vue component?

STEP 01: First, Import the Child Component into the Parent Component inside script tag but above export default function declaration. STEP 02: Then, Register the Child Component inside the Parent Component by adding it to components object. STEP 03: Finally, Use the Child Component in the Parent Component Template.

How do I register a component in Vue TypeScript?

To register the components SubOne and SubTwo in MyComponent , pass it to the @Component decorator: import { Component, Vue } from "vue-property-decorator"; @Component({ components: { SubOne, SubTwo, } }) export default class MyComponent extends Vue { … }


1 Answers

Overview

You can add configureWebpack in the vue.config.js to modify the Webpack configuration and in Webpack you can solve this issue using externals.

Handling Externals

Externals provide a way for you to import external libraries.

In your webpack configuration you will add a line that looks something like this.

let's take lodash for example as the import and the global variable are different.

// webpack.config
externals: {
  'lodash': '_'
}

_ is the global variable webpack can grab and lodash is the import it exposes.

At this point, you can do something like this.

import * as lodash from 'lodash'

Handling TypeChecking

To handle the type checking with this method you npm install @types/... and TypeScript will pick up the types for that import.

Modifying Webpack in vue.config.js

You can read about this here but simply add the following to the vue.config.js file.

// vue.config.js
module.exports = {
  configureWebpack: {
    externals: {
      'lodash': '_'
    }
  }
}
like image 115
Michael Warner Avatar answered Oct 01 '22 05:10

Michael Warner