title: Webpack and TypeScript can't resolve declaration file for Vue
body: <p>I have a project where I introduced Vue for some frontend stuff but I still have a lot of legacy code in TypeScript and jQuery. All the legacy code is in a 'ts' folder and the new Vue single file components and some bootstrapping ts files are in 'src'. It looks all OK in VSCode and even directly calling 'tsc' on the command line works fine but WebPack keeps complaining as soon as I import a declaration/definition (module) from the 'ts' folder.</p>
  
  <p><strong>Project folder structure</strong></p>
  
  <pre><code>+ root
    + php/css/etc
    + ts
      + models
        - LegacyTypeScriptModules.ts
        - PlanDate.ts
      + js-defs
        - tools.d.ts
      - tsconfig.json (to be able to build only legacy code)
    + src
      + components
        - RecentChanged.vue
      + pages
        - Welcome.vue
      - App.vue
      - main.ts
      - tsconfig.json (main configuration)
    - package.json
    - tsconfig.json (only fixing experimentalDecorators issue in VSCode)
    - tslint.json
    - webpack.config.js
  </code></pre>
  
  <p><strong>Error message npm build</strong></p>
  
  <blockquote>
    <p>ERROR in ./ts/models/PlanDate.ts
    Module not found: Error: Can't resolve 'js-defs/tools' in '/Users/username/dev/project-root/ts/models'
     @ ./ts/models/PlanDate.ts 1:0-45
     @ ./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&amp;index=0!./src/components/RecentChanged.vue
     @ ./src/components/RecentChanged.vue
     @ ./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&amp;index=0!./src/pages/Welcome.vue
     @ ./src/pages/Welcome.vue
     @ ./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&amp;index=0!./src/App.vue
     @ ./src/App.vue
     @ ./src/main.ts</p>
  </blockquote>
  
  <p><strong>Main tsconfig.json in 'src' folder</strong></p>
  
  <pre><code>{
      "compilerOptions": {
          "target": "es5",
          "strict": true,
          "module": "es2015",
          "moduleResolution": "node",
          "lib": [
              "dom",
              "es2015",
              "es2015.iterable"
          ],
          "experimentalDecorators": true,
          "emitDecoratorMetadata": true,
          "baseUrl": ".",
          "paths": {
              "*": [
                  "*",
                  "./*",
                  "../ts/*"
              ]
          }
        },
        "include": [
            "**/*",
            "../ts/**/*"
        ]
  }
  </code></pre>
  
  <p><strong>webpack.config.js</strong></p>
  
  <pre><code>module.exports = {
    entry: './src/main.ts',
    output: {
      path: path.resolve(__dirname, './dist'),
      publicPath: '/dist/',
      filename: 'build.js'
    },
    module: {
      rules: [
        {
          test: /\.ts$/,
          loader: "ts-loader",
          exclude: /node_modules|vue\/src/,
          options: {
            appendTsSuffixTo: [/\.vue$/]
          }
        },
  ...
    resolve: {
      alias: {
        'vue$': 'vue/dist/vue.esm.js',
      },
      extensions: ['.js', '.vue', '.json', '.ts'],
      modules: [
        'node_modules', 
        path.resolve(__dirname, 'src'),
        path.resolve(__dirname, 'ts')
      ],
  ...
  </code></pre>
  
  <p><strong>First Vue file importing a legacy ts module</strong></p>
  
  <pre><code>import Vue from 'vue'
  import { ChangedItem } from '../../ts/models/ChangedItem'
  import { PlanDate } from "../../ts/models/PlanDate"
  import { Customer } from "../../ts/models/Customer"
  import { Component, Prop } from 'vue-property-decorator'
  
  @Component
  export default class RecentChanged extends Vue {
  ...
  </code></pre>
  
  <p><strong>Class/module giving the error</strong></p>
  
  <pre><code>import { IDate, IDateSink, IDateSource} from "./interfaces/IDate";
  import { addDays, pad } from "js-defs/tools";
  
  export class PlanDate implements IDate {
  ...
  </code></pre>
  
  <p><strong>Module which can't be found</strong></p>
  
  <pre><code>import { IMainOptions } from "models/interfaces/IOptions";
  
  export declare function addDays(d: IDate, n: number, keepTime?: boolean): IDate;
  export declare function pad(inputString: any, width: number, paddingCharacter?: string): string;
  </code></pre>
  
  <p>Notice that the first problem already is that I can't seem to get the absolute paths working in Vue SFC so I already had to compromise to an ugly relative path. (maybe already a first sign of a problem?) This absolute path problem in Vue is consistent over VSCode, tsk and WebPack but I have seperate question on this.
  I also had problems with <strong>some</strong> absolute paths in the legacy typescript classes but I can imagine this because it only seems to work from the 'ts' folder and deeper but I don't think this is related as WebPack doesn't seem to complain about the import 'IDate'.</p>
  
  <p>As the bare typescript compiler doesn't have a problem with finding the declaration modules and also VSCode language server isn't complaining I assume it is a problem in the configuration file for WebPack but maybe I'm missing/overlooking something. </p>
  
  <p>I tried both absolute and <strong>relative</strong> paths to the declaration module but both fail. Also tried other legacy classes that don't depend on other legacy modules and they <strong>do</strong> seem to work. So it looks like the module resolution fails on the declaration file.
  In webpack.config.js I already tried things like <em>resolve.alias</em> and <em>resolve.modules</em> but they didn't work or I don't know how to define the path.</p>
  
  <p><strong>Update</strong></p>
  
  <p>After the first comments and answers given below I'm pretty sure it has to do with how my own declaration file is defined, how I should import it or how I configure WebPack to properly find it. Can someone tell me how to use declaration files in Vue+WebPack+TypeScript without getting a 'module not found' or a 'no output emitted' error?</p>