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.
Project folder structure
+ 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
Error message npm build
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&index=0!./src/components/RecentChanged.vue @ ./src/components/RecentChanged.vue @ ./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/pages/Welcome.vue @ ./src/pages/Welcome.vue @ ./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue @ ./src/App.vue @ ./src/main.ts
Main tsconfig.json in 'src' folder
{
"compilerOptions": {
"target": "es5",
"strict": true,
"module": "es2015",
"moduleResolution": "node",
"lib": [
"dom",
"es2015",
"es2015.iterable"
],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"baseUrl": ".",
"paths": {
"*": [
"*",
"./*",
"../ts/*"
]
}
},
"include": [
"**/*",
"../ts/**/*"
]
}
webpack.config.js
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')
],
...
First Vue file importing a legacy ts module
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 {
...
Class/module giving the error
import { IDate, IDateSink, IDateSource} from "./interfaces/IDate";
import { addDays, pad } from "js-defs/tools";
export class PlanDate implements IDate {
...
Module which can't be found
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;
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 some 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'.
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.
I tried both absolute and relative paths to the declaration module but both fail. Also tried other legacy classes that don't depend on other legacy modules and they do seem to work. So it looks like the module resolution fails on the declaration file. In webpack.config.js I already tried things like resolve.alias and resolve.modules but they didn't work or I don't know how to define the path.
Update
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?
When importing .d.ts
files make sure you use the type
keyword.
import type * as MyTypes from "./types"
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