I have a simple project structure:
/src/app2/main.ts /src/app2/components/lib.ts /src/app2/components/stuff.vue
With webpack, vue-loader, and ts-loader.
main.ts has:
import Vue = require('vue');
import  Component from './components/lib'
new Vue({
  el: '#app2'
});
When trying to build this with 1 webpack entry for /src/app2/main.ts, the error generated is:
ERROR in C:\temp\vuetest2\proj\src\app2\components\lib.ts
(2,25): error TS2307: Cannot find module './stuff.vue'.
ERROR in ./src/app2/main.ts
Module not found: Error: Can't resolve './components/lib' in 'C:\temp\vuetest2\proj\src\app2'
 @ ./src/app2/main.ts 3:12-39
If I change the entry point to src/app2/components/lib.ts, it will build.  I'm at a loss as to why main.ts won't build.
Contents of lib.ts:
import Vue = require('vue');
import Stuff  = require('./stuff.vue');
let o = {
   Stuff
}
let componentLibrary = {
  components: o,
  registerExternal: function(v:any) {
    for(var k in o) {
        v.component(o[k].name, o[k]);
    }
  },
  registerInternal: function() {
    for(var k in o) {
        Vue.component(o[k].name, o[k]);
    }
  }
}
export default componentLibrary;
Stuff.vue is just a simple single file vue component.
According to : https://github.com/vuejs/vue-class-component/blob/master/example/webpack.config.js
Try adding appendTsSuffixTo ts-loader option in your webpack.config.js
webpack2
{
    test: /\.ts$/,
    exclude: /node_modules|vue\/src/,
    use: [{
            loader: 'ts-loader',
            options: {
                appendTsSuffixTo: [/\.vue$/]
            }
        }]
},
                        You can reference on this PR on github. Actually that's not a bug, just a usage problem.
I assume that you want to write SFC with <script lang="ts">, <script lang="tsx">, *.ts for utils functions & classes, and *.tsx for functional pure component.
ts-loader accpets only *.ts or *.tsx files to compile (otherwise it would cause an error that file not found). So ts-loader has two options: appendTsSuffixTo and appendTsxSuffixTo. These two options accept an array of regexp to match which files you want to compile. (Here we give ts-loader the *.vue files that already processed by vue-loader to compile).
I assume that you use *.ts.vue for <script lang="ts"> SFC vue file while *.tsx.vue for <script lang="tsx"> SFC vue file. ts-loader should be configured as below:
  {
    test: /\.tsx?$/,
    use: [
      {
        loader: 'babel-loader'
      },
      {
        loader: 'ts-loader',
        options: {
          appendTsSuffixTo: [/\.ts\.vue$/],
          appendTsxSuffixTo: [/\.tsx\.vue$/]
        }
      }
    ],
    exclude: /node_modules/
  },
This means, normal *.ts and *.tsx files pass to ts-loader will transpiled and then be sent to babel-loader for further compile. And other files end with .ts.vue will be suffixed .ts as *.ts.vue.ts, and end with .tsx.vue to be *.tsx.vue.tsx. These files all passed from vue-loader. Remember ts-loader only accept .ts and .tsx files.
But vue-loader is not smart enough, <script lang="xxx"> will trigger vue-loader append xxx-loader for further compile, and <script lang="tsx"> will make vue-loader append tsx-loader, which is not exist in the world.
Fortunately we can configure vue-loader's options:
  const loaders = {}
  loaders.tsx = ['babel-loader', 'ts-loader']
  loaders.ts = loaders.tsx
  {
    test: /\.vue$/,
    loader: 'vue-loader',
    options: { loaders }
  },
After that webpack config is completed. For tsx support, you should install some JSX types and write a related .d.ts file
You can check this repo on github for more details.
Good luck!
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