Typescript not working in vue SFC - laravel

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.

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 optional parameter not working - TS2554: Expected 2 arguments, but got 1

I develop an application using Vue and Typescript 4.2.4. I can't use optional parameters in functions. Eslint doesn't complain. My code works fine on TS Playground as well. Here is a sample:
const f = (a: object, b?: object): void => {
console.log(a);
if (b) {
console.log(b);
}
}
f({ lorem: 'ipsum' });
f({ foo: 'bar' }, { optional: 'test' });
Every time I want to compile I get
TS2554: Expected 2 arguments, but got 1.
in first call.
Is there some config to enable or something else I should do? I have no experience with Typescript. I appreciate any help.
Laravel mix:
const mix = require('laravel-mix');
const config = require('./webpack.config');
mix
.webpackConfig(config)
.setResourceRoot(config.output.publicPath)
.disableNotifications()
.ts('resources/assets/js/app.ts', 'public/js').vue().extract()
.sass('resources/assets/sass/app.scss', 'public/css').sourceMaps()
.copyDirectory('node_modules/layout/images/', 'public/images')
.copyDirectory('node_modules/layout/icons/', 'public/icons')
.version();
Webpack config for mix
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const path = require('path');
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: { esModule: true },
},
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'ts-loader',
options: { appendTsSuffixTo: [/\.vue$/] },
},
],
},
output: {
publicPath: `/${process.env.APP_ALIAS}/` || '/',
chunkFilename: 'chunks/[name].js?id=[chunkhash]',
},
plugins: [
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*', '!.htaccess', '!index.php', '!robots.txt'],
}),
],
resolve: {
alias: {
'#': path.resolve('resources/assets/js'),
},
},
};
tsconfig
{
"compilerOptions": {
"target": "es2015",
"module": "esnext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"strict": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"noImplicitAny": false,
"noImplicitReturns": false,
"noImplicitThis": false,
"noUnusedLocals": true,
"importHelpers": true,
"skipLibCheck": true,
"allowUnusedLabels": false,
"sourceMap": true,
"esModuleInterop": true,
"allowJs": true,
"baseUrl": ".",
"paths": {
"#/*": ["resources/assets/js/*"],
},
"lib": ["esnext", "dom"]
},
"include": [
"resources/assets/js/**/*"
],
"exclude": [
"node_modules",
]
}
EDIT:
Ok, I suppose Typescript in my Laravel project is not working properly. When I changed configuration to:
"noImplicitAny": true,
"noImplicitReturns": true,
my playground code causes another errors:
./resources/assets/js/app.ts 6:11-12
[tsl] ERROR in D:\Dev\Laravel\processes\resources\assets\js\app.ts(6,12)
TS7006: Parameter 'a' implicitly has an 'any' type.
ERROR in D:\Dev\Laravel\processes\resources\assets\js\app.ts
./resources/assets/js/app.ts 6:14-15
[tsl] ERROR in D:\Dev\Laravel\processes\resources\assets\js\app.ts(6,15)
TS7006: Parameter 'b' implicitly has an 'any' type.
ERROR in D:\Dev\Laravel\processes\resources\assets\js\app.ts
./resources/assets/js/app.ts 12:0-21
[tsl] ERROR in D:\Dev\Laravel\processes\resources\assets\js\app.ts(12,1)
TS2554: Expected 2 arguments, but got 1.
As you can see, function and parameters have their types defined.
What can be wrong there?
OK, thanks everyone, I have a solution. I figured out that webpack config for ts-loader and vue-loader causes some problems with Laravel Mix. I have just removed rules section from config and left Laravel Mix do the job. My playground code works fine now.

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.

TypeScript compilation extremely slow > 12s

Just putting this out there to see if someone else is having this issue...
I have building an angular 2 app with typescript using webpack as my build tool, it all works well, however I have noticed typescript compilation is super super slow, I am at 12 seconds right now...., and its pretty clear that is all due to the typescript compilation process....
I have used ts-loader or awesome-typescript-loader with a similar result, if I comment out this loader, my build time drops to around 1 sec....
After some research it seems like its 'normal' to have 'slow' times when compiling typescript, but is 12secs the normal??
Old posts hinted it might be due to a node version conflict, I am currently running v4.4.2...
Any how below is my webpack code in case anyone spots something wrong there.. the commented code in the Uglify section is due to some 'bug' on the angular 2 side...
const path = require('path');
const merge = require('webpack-merge');
const webpack = require('webpack');
const NpmInstallPlugin = require('npm-install-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TARGET = process.env.npm_lifecycle_event;
const PATHS = {
app: path.join(__dirname, 'app'),
dist: path.join(__dirname, 'dist')
};
const common = {
entry: {
vendor: ['./app/vendor.ts'],
main: ['./app/boot.component.ts']
},
output: {
filename: '[name].[hash].bundle.js',
path: PATHS.dist
},
resolve: {
extensions: ['', '.js', '.ts']
},
plugins: [
new HtmlWebpackPlugin({
title: 'Qarrot Performance',
template: 'index.template.ejs',
commonStyles: [
'/public/styles/vendor/normalize.css',
'/public/styles/main.css'
],
commonScripts: [],
baseHref: '/',
unsupportedBrowser: true,
mobile: true,
appMountId: 'app'
}),
],
module: {
loaders: [
{
test: /\.ts$/,
exclude: /node_modules/,
loaders: ['ts-loader']
},
{
test: /\.scss$/,
loader: 'raw-loader!sass-loader'
},
{
test: /\.html$/,
loader: "html"
}
]
}
}
// Dev Settings
if(TARGET === 'start' || !TARGET) {
module.exports = merge(common, {
devtool: 'eval-source-map',
devServer: {
contentBase: PATHS.build,
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
stats: 'errors-only',
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new NpmInstallPlugin({
save: true
})
]
});
}
// Prod Settings
if(TARGET === 'build') {
module.exports = merge(common, {
devtool: 'cheap-module-source-map',
plugins: [
// new webpack.optimize.UglifyJsPlugin({
// beautify: false,
// mangle: false,
// compress : { screw_ie8 : true },
// comments: false
// }),
new webpack.optimize.DedupePlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
new CopyWebpackPlugin([
{ from: 'public', to: 'public' }
]),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
]
});
}
I am also on a Mac, running Angular 2 beta.15 and webpack version 1.12, below is my tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"compileOnSave": false,
"exclude": [
"node_modules",
"typings/main",
"typings/main.d.ts"
]
}
I would stick to the awesome-typescript-loader. It has some performance options you can enable: a caching option and a transpile only option:
"awesomeTypescriptLoaderOptions": {
"useCache": true,
"transpileOnly": true
}
Both of these had a significant improvement on compile times.
Please share you tsconfig.json. Most likely you have noEmitOnError set to true which means that the compiler is forced to typecheck the whole codebase before any emitting.
Please set that to false.

Resources