I am migrating JS files to Typescript and my goal is, to be able to use both JS and Typescript classes in Vue. I know, I can convert Vue scripts into Typescript, but I don't want to do it right now.
The problem arises in a component.vue file:
this.exceptionHandler = app.resolve('ExceptionHandler');
The errror I get in the browser's console is this (compilation is ok):
"TypeError: Cannot call a class as a function"
ExceptionHandler is defined in a TypeScript .ts file.
The question is: Is it possible to first transpile the TS code to JS ES6, then put the code together and then run Babel on everything to compile it to ES5?
I use these options in the TS configuration:
"lib": ["es7", "es6", "es5", "dom"],
"types": ["reflect-metadata"],
"module": "commonjs",
"target": "es6",
And Webpack 4 config:
{
test: /\.ts(x?)$/,
loader: 'babel-loader?presets[]=es2015!ts-loader',
exclude: [
"node_modules",
"vendor",
"app",
"public"
]
},
When I use just ts-loader, the code works well, but the version of the compiled JS code is ES6 and not ES5.
This may be useful to those of you new to Webapack 4. My working webpack config file looks like this:
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
let devMode = process.env.NODE_ENV === 'development';
let webUrl = 'http://my-project.localhost/';
if (process.env.NODE_ENV === 'production') {
webUrl = 'https://my-project.com/';
}
else if (process.env.NODE_ENV === 'development') {
webUrl = 'http://my-project.localhost/';
}
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: {
'frontApps': './resources/assets/js/frontApps.ts',
'backAppsAdmin': './resources/assets/js/backAppsAdmin.ts',
'styles' : './resources/assets/sass/styles.scss',
'adminBack' : './resources/assets/sass/admin back/adminBack.scss',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: [{
loader: "babel-loader",
options: {
presets: ['@babel/preset-env']
}
}]
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
js: 'babel-loader',
css: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options : {
url: false
}
}
],
fallback: 'vue-style-loader',
}),
}
}
},
{
test: /\.ts(x?)$/,
loader: 'babel-loader?presets[]=@babel/preset-env!ts-loader',
exclude: [
"node_modules",
"vendor",
"app",
"public"
]
},
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options : {
url : false,
sourceMap: devMode
}
},
{
loader: 'sass-loader',
options : {
processCssUrls : false,
sourceMap: devMode
}
}
],
}
]
},
output : {
filename : 'js/[name].js',
chunkFilename: 'js/[name].js',
path: path.resolve(__dirname, 'public'),
publicPath: webUrl,
},
optimization: {
splitChunks: {
cacheGroups: {
vendor : {
test : '/node_modules/',
chunks: 'all',
name: 'vendor',
priority: 10,
enforce: true
}
}
},
},
resolve: {
extensions: [ '.tsx', '.ts', '.js', '.vue' ],
alias: {
vue: 'vue/dist/vue.esm.js'
}
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: "css/[name].css",
chunkFilename: "css/[id].css"
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
new webpack.ProvidePlugin({
'regeneratorRuntime': 'regenerator-runtime/runtime'
}),
]
};
If you want to use SCSS inside a single file Vue components, then use this:
<style lang="scss" type="text/scss" scoped>
</style>