vue-loader: cant work with typescript

structure of the project

image

webpack.config.js

module.exports = {
    entry: './src/js/app.js',
    output: {
        path: 'dist/',
        filename: './js/bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader'
            },
            {
                test: /\.vue$/,
                loader: 'vue'
            }
        ]
    }
}

app.ts

declare var require;
declare var Vue;

new Vue({
    el: 'body',
    components: {
        'nani': require('../components/nani.vue')
    }
})

nani.vue

<template><p>纳尼?你再说一次.</p></template>

<script lang="ts">
    export = {
        methods: {
            sayHello: function () {
                alert('hello')
            }
    }
</script>

each time I run webpack, it always report this error,

$ webpack                                                                                                                     ‹ruby-2.1.4›
ts-loader: Using typescript@1.6.2
Hash: 54f28de48a69455dfb02
Version: webpack 1.12.9
Time: 1239ms
         Asset     Size  Chunks             Chunk Names
./js/bundle.js  2.74 kB       0  [emitted]  main
   [0] ./src/js/app.js 178 bytes {0} [built]
    + 4 hidden modules

ERROR in ./~/ts-loader!./~/vue-loader/lib/selector.js?type=script&index=0!./src/components/nani.vue
Module build failed: Error: Could not find file: '/Users/tcstory/WebstormProjects/test/src/components/nani.vue'.
    at getValidSourceFile (/Users/tcstory/WebstormProjects/test/node_modules/typescript/lib/typescript.js:43586:23)
    at Object.getEmitOutput (/Users/tcstory/WebstormProjects/test/node_modules/typescript/lib/typescript.js:46680:30)
    at Object.loader (/Users/tcstory/WebstormProjects/test/node_modules/ts-loader/index.js:410:34)
 @ ./src/components/nani.vue 2:17-111

how to solve this problem?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 12
  • Comments: 37 (8 by maintainers)

Most upvoted comments

On another look, you may need to set the transpileOnly flag to true: https://github.com/TypeStrong/ts-loader#transpileonly-boolean-defaultfalse

Hey all, here’s a sample repo of TypeScript working with .vue files. It’s still a bit of a work in progress, but it’ll get the job done for you. https://github.com/DanielRosenwasser/typescript-vue-todomvc

It currently uses some augmented .d.ts files that I’ve been working on, and right now type checking requires that you write

export default Vue.extend({
  // ... component options here ...
});

instead of just

export default {
  // ... component options here ...
};

You’ll also always need an export default from a .vue file so that TypeScript knows that it’s a module.

If you use it, try it out with the Vetur VS Code plugin, which can actually give you some of the same experience TypeScript does in .ts files.


vue-loader specific things:

  • Of note: you’ll need to write <script lang="ts"> for your script tags

  • You’ll need to use the appendTsSuffixTo option

  • To import from .vue files, you’ll need a declare module “*.vue”-type thing. Specifically this:

    declare module '*.vue' {
      import Vue from 'vue';
      declare const component: typeof Vue;
      export default component;
    }
    

    which I realize could probably have just been written as

    declare module '*.vue' {
      import Vue from 'vue';
      export default Vue;
    }
    

@ARomancev maybe your code doesn’t work because you’re default-exporting the type of Vue, not Vue itself.

You can make vue-loader work with TS, if you put ts code in separate file.

myComponent.vue:

<template>
    ...
</template>
<style>
    ...
</style>
<script lang="ts" src="./myComponent.vue.ts"></script>

myComponent.vue.ts:

TS code goes here

You can use both ‘ts’ and ‘awesome-typescript’ loaders, just override ts lang option in vue-loader settings.

Sample usage here:

https://github.com/yegor-sytnyk/contoso-express/ branch alt/vue

@DanielRosenwasser I’ve noticed your example repo is using custom vue / vue-router dependencies, does it still require them? if so do you know when they’ll be able to work with the official vue/vue-router packages?

@doun It’s my fault. I gone well when I remove { modules: false } options in babel. Here is my webpack2 config.

module: {
        rules: [
            {
                test: /\.js/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    // presets: ['es2015', { modules: false }] <- fail
                    presets: ['es2015']
                }
            },
            {
                test: /\.ts$/,
                exclude: /node_modules|vue\/src/,
                use: [
                    {
                        loader: 'ts-loader',
                        options: {
                            appendTsSuffixTo: [/\.vue$/]
                        }
                    },
                ]
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    esModule: true,
                }
            },
        ]
    }

Does this compile the ts in components twice?

{
    test: /\.vue$/,
    loader: 'vue-loader', // doesn't want to be use for whatever reason
    options: {
        loaders: {
            scss: cssExtract(false),
            ts:  [{
                loader: 'babel-loader',
            }, {
                loader: 'ts-loader',
                options: {
                    appendTsSuffixTo: [/\.vue$/]
                }
            }]
        },
        options: {
            esModule: true
        }
    }
},
{ // ts
    test: /\.tsx?$/,
    use: [{
        loader: 'babel-loader',
    }, {
        loader: 'ts-loader',
        options: {
            appendTsSuffixTo: [/\.vue$/]
        }
    }],
    exclude: /node_modules/, // not sure if needed
}, 

Has anyone gotten vue2 + typescript2 working with hot reloading using .vue component files?

@druppy Yes, I just got it working when I was converting a project over from JavaScript to TypeScript.

See my comment on how I fixed this Error: Could not find file error with ts-loader and appendTsSuffixTo option.

Oh - I think I see. Loaders don’t have control over “generating” files. That file exists on its own and no new distinct files are created (even virtually). Is that correct?