Import custom Vue Component fails in TypeScript - laravel

The code works, but why does TypeScript not understand my custom Component? And why does it add the .js extension to the filename?
Could not find a declaration file for module ..
I am using Laravel 9, Vue 3, Vite 3, InertiaJS
After hours of searching, I did not find a solution.
Component file
<template> </template>
<script>
export default {};
</script>
tconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": [
"esnext",
"dom"
],
"types": [
"vite/client"
],
"baseUrl": ".",
"paths": {
"#/*": ["resources/js/*"]
}
},
"include": ["resources/**/*"]
}

If you are using Options API or setup(), define your component using defineComponent method:
<template> </template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
// type inference enabled
setup(), // if using setup()
})
</script>
And if using <script setup>, define it like so:
<template> </template>
<script setup lang="ts">
</script>
https://vuejs.org/guide/typescript/overview.html
https://vuejs.org/api/general.html#definecomponent

Related

Laravel mix is not building Vue 3 TS assets

I have a fresh Laravel 9 app with Vue 3 SPA built with TS (using Metronic 8.1 template) and I'm using webpack. Whenever I try to build the assets, it stays stuck at 12% and then does absolutely nothing.
Running Laravel using Sail on WSL2. After doing some research I found out that it could be a memory issue, so I tried to change this like so:
.wslconfig
[wsl2]
memory=10GB
localhostForwarding=true
And then running Restart-Service LxssManager as administrator.
However, nothing I've tried so far seems to work. I have another Laravel 9 app in a different container, which does not use any framework and uses vanillaJS and that compiles no problem. Any help here?
webpack.mix.js
const mix = require("laravel-mix");
const path = require("path");
mix.ts("resources/ts/app.ts", "public/js")
.vue({ version: 3 })
.webpackConfig({
module: {
rules: [
{
test: /.mjs$/i,
resolve: {
byDependency: { esm: { fullySpecified: false } },
},
},
],
},
resolve: {
alias: {
"#": path.resolve(__dirname, "resources/ts/src/"),
},
},
});
.tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"noImplicitAny": false,
"target": "es5",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"paths": {
"#/*": [
"resources/ts/src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"resources/ts/src/**/*.ts",
"resources/ts/src/**/*.tsx",
"resources/ts/src/**/*.vue"
],
"exclude": [
"node_modules"
]
}

Typescript not working in vue SFC

Well, after spending literally all day and 10 hours trying to get up and running with typescript, I'm at a loss why this isn't working.
NOTES:
- using Laravel and webpack, fresh install, nothing fancy that would have broken any of the 50+ guides I've looked at in setting this up
- all normal .ts files compile, but I cannot use in my vue components.
Webpack.mix.js file:
mix.js('resources/assets/js/app.ts', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
mix.webpackConfig({
devtool: mix.inProduction() ? '' : 'inline-source-map',
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
},
exclude: /node_modules/,
}
],
},
resolve: {
extensions: ['*', '.js', '.jsx', '.vue', '.ts', '.tsx'],
alias: {
styles: path.resolve(__dirname, 'resources/assets/sass'),
'#': path.resolve(__dirname, 'resources/assets/js'),
},
},
});
tsconfig.json:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"experimentalDecorators": true,
"module": "es2015",
"moduleResolution": "node",
"noImplicitAny": false,
"strict": true,
"strictPropertyInitialization": false,
"target": "es2015",
"lib": [
"dom",
"es2017"
],
"paths": {
"#/*": [
"resources/assets/js/*"
]
}
},
"include": [
"resources/assets/js/**/*.ts",
"resources/assets/js/**/*.vue"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
sfc.d.ts file:
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
Any help would be greatly appreciated, I'll continue looking around but I feel as though I've exhausted most of the routes I can take.
I hope you are using vue-loader or something similar to be able to write single-file components(SFCs) in the first place.
This sfc.d.ts should be renamed to a vue.shims.d.ts or index.d.ts where type definitions are held. You don't need to import this file anywhere. Typescript will use it this whenever it encounters a .vue file
Now you can create an SFC with lang attribute set to ts.
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
Here is a Microsoft Doc that explains the same. In our project, I have defined it as index.d.ts.

Typescript outFile, Angular2 and Visual Studio 2015

tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "dom", "es6" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"outFile": "tsbundle.js"
},
"compileOnSave": true
}
I manually include tsbundle.js to my html page.
I've got an angular module, called NavigationModule which is #NgModule and its main.ts looks like this:
main.ts
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { NavigationModule } from './navigation.module';
import { enableProdMode } from '#angular/core';
enableProdMode();
platformBrowserDynamic().bootstrapModule(NavigationModule);
My question is: how to configure systemjs.config.js
Current setup (not working)
systemjs.config.js
packages: {
rxjs: {
defaultExtension: 'js'
},
Navigation: {
format: 'register',
defaultExtension: 'js',
main: '/tsbundle.js'
}
}
I import the module like this:
index.html
System.import('Navigation/main').catch(function (err) { console.error(err); });
It still looks for the module not from the tsbundle.js, but from
/en/Navigation/main.js (which of does not exist and fails)
How to tell it, that everything for the Navigation module is inside the tsbundle.js and it should download only that file.

How to debug tsx files when using webpack

I'm new to front-end development.
I write some reactjs component in tsx format. this is one of my tsx files:
import * as React from "react";
import {observer} from "mobx-react";
import {observable} from "mobx";
import {TileGrid, Tile} from "./GridStack"
#observer
export class Dashboard extends React.Component<any, any>{
addTiles() {
this.props.data.push(
{title: "I'm a !"}
);
}
render() {
return (
<div>
<h1>I'm dashboard !</h1>
<button onClick={this.addTiles.bind(this)}>Add some tiles</button>
<TileGrid columnCount="12">
{this.props.data.map((x) => {
return (
<Tile x="1" minWidth="2" minHeight="3">
{x.title}
</Tile>
)
})}
</TileGrid>
</div>
)
}
}
As you can see it has Node Module format. and it has dependency to GridStack module.
It's my tsconfig.json file:
{
"compileOnSave": true,
"compilerOptions": {
"sourceMap": true,
"target": "es5",
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"experimentalDecorators": true,
"noLib": false,
"jsx": "react"
},
"exclude": [
"node_modules",
"static"
]
}
the output js files contain commands like reuqire(...) that is undefinded for browsers.
to achieve this problem I decided to use webpack .
It fix that issue but now I faced with a new problem.
I can't debug GridStack.tsx file because webpack just allow me to debug root level tsx file.
this is my webpack.config.js file:
module.exports = {
entry: './TS/controllers/App.tsx',
output: {
filename: './dist/app.js'
},
devtool: 'source-map',
resolve: {
extensions: ['', '.Webpack.js', '.web.js', '.ts', '.js', '.tsx']
},
module: {
loaders: [
{
test: /\.tsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'ts-loader'
}
],
preLoaders: [
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ test: /\.tsx$/, loader: "source-map-loader" }
]
}
}
Bundling and packing isn't my current issue I just need to have js files that are browser friendly and be able to debug each tsx files.
Your help will be appreciated.
The answer for those who have the same problem.
The order of extensions is important.
I mentioned 'tsx' first and then other types.
when compileOnSave option set true, each tsx file will have a correspondence js file. in this situation when the .js extension comes earlier Webpack grab the js file instead of tsx file.

Gulp not generating inline sourcemaps

I have the following tsconfig.json file in an ASP.NET Core:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"inlineSourceMap": true,
"inlineSources": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noEmitOnError": false,
"noImplicitAny": false,
"removeComments": false,
"outDir": "wwwroot/client-app"
},
"exclude": [
"node_modules",
"wwwroot",
"typings"
]
}
When I build the project through Visual Studio the resulting js files have the inline source maps at the end of the file:
/// <reference path="../typings/index.d.ts" />
"use strict";
var platform_browser_dynamic_1 = require('#angular/platform-browser-dynamic');
var client_application_module_1 = require('./client-application.module');
platform_browser_dynamic_1.platformBrowserDynamic().bootstrapModule(client_application_module_1.ClientApplicationModule);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL0NsaWVudEFwcC9ib290LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhDQUE4Qzs7QUFFOUMseUNBQXVDLG1DQUFtQyxDQUFDLENBQUE7QUFDM0UsMENBQXdDLDZCQUE2QixDQUFDLENBQUE7QUFFdEUsaURBQXNCLEVBQUUsQ0FBQyxlQUFlLENBQUMsbURBQXVCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuLi90eXBpbmdzL2luZGV4LmQudHNcIiAvPlxyXG5cclxuaW1wb3J0IHsgcGxhdGZvcm1Ccm93c2VyRHluYW1pYyB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXItZHluYW1pYyc7XHJcbmltcG9ydCB7IENsaWVudEFwcGxpY2F0aW9uTW9kdWxlIH0gZnJvbSAnLi9jbGllbnQtYXBwbGljYXRpb24ubW9kdWxlJztcclxuXHJcbnBsYXRmb3JtQnJvd3NlckR5bmFtaWMoKS5ib290c3RyYXBNb2R1bGUoQ2xpZW50QXBwbGljYXRpb25Nb2R1bGUpOyJdfQ==
But when I build the js files with Gulp, the inline sourcemap is not being generated, like if it was ignoring the tsconfig.json
Here is my Gulp task for transpiling TypeScript to JavaScript:
var tsProject = ts.createProject('tsconfig.json');
gulp.task('transpile', function ()
{
var tsResult = gulp.src(["ClientApp/**/*.ts"])
.pipe(ts(tsProject), undefined, ts.reporter.fullReporter()).js
.pipe(gulp.dest('./wwwroot/client-app'));
});
Do I need any extra configuration in Gulp so the inline sourcemaps can be generated?
I'm using TypeScript 1.8.10
I never managed to get it working with the simple typescript gulp task, I always use the gulp-sourcemaps plugin to do this.
Usually something like this:
var sourcemaps = require('gulp-sourcemaps');
var typescript = require('gulp-typescript');
gulp.task('typescript', function () {
gulp.src(["ClientApp/**/*.ts"])
.pipe(sourcemaps.init())
.pipe(typescript())
.pipe(sourcemaps.write())
.pipe(gulp.dest('./wwwroot/client-app'))
});

Resources