I have a vue3/symfony project and i started implementing typescript but i came across an issue that i cannot solve. For building assets i'm using webpack encore and when i start the watcher the assets are compiled just fine, but when i change anything in my .vue files ( even adding a blank space to force webpack to recompile ) i get this error:
TS2614: Module '"resources/ts/helpers"' has no exported member 'TestClass'. Did you mean to use 'import TestClass from "resources/ts/helpers"' instead?
TS2339: Property '__file' does not exist on type '{}'.
Important notes: if i do any kind of change ( even a blank space ) on the helper.ts the compilation is again succesfully.
This only happens to .ts files imported into .vue files. The .js or .vue(with or without typescript) files that i've imported are fine
helpers.ts:
export class TestClass {
constructor(public test: string) {
}
}
Imported as import { TestClass } from "resources/ts/helpers";
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"noImplicitThis": true,
"jsx": "preserve",
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
],
"baseUrl": ".",
"paths": {
"resources/*": [
"resources/*"
]
}
},
"include": [
"resources/**/*.ts",
"resources/**/*.tsx",
"resources/**/*.vue",
],
"exclude": [
"node_modules"
]
}
webpack.config.js:
const Encore = require('@symfony/webpack-encore');
const path = require('path');
const webpack = require('webpack');
// Manually configure the runtime environment if not already configured yet by the "encore" command.
// It's useful when you use tools that rely on webpack.config.js file.
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')
.copyFiles({
from: './resources/assets/media',
to: 'media/[path][name].[ext]',
pattern: /\.(png|jpg|jpeg|svg)$/
})
.copyFiles({
from: './resources/assets/fonts',
to: 'fonts/[path][name].[ext]',
pattern: /\.(ttf)$/
})
/*
* ENTRY CONFIG
*
* Add 1 entry for each "page" of your app
* (including one that's included on every page - e.g. "app")
*
* Each entry will result in one JavaScript file (e.g. main.js)
* and one CSS file (e.g. app.css) if you JavaScript imports CSS.
*/
.addEntry('main', './resources/main.js')
// When enabled, Webpack "splits" your files into smaller pieces for greater optimization.
.splitEntryChunks()
// will require an extra script tag for runtime.js
// but, you probably want this, unless you're building a single-page app
.enableSingleRuntimeChunk()
/*
* FEATURE CONFIG
*
* Enable & configure other features below. For a full
* list of features, see:
* https://symfony.com/doc/current/frontend.html#adding-more-features
*/
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
// enables hashed filenames (e.g. app.abc123.css)
.enableVersioning(Encore.isProduction())
// enables @babel/preset-env polyfills
.configureBabel(() => {
}, {
useBuiltIns: 'usage',
corejs: 3
})
// enables Sass/SCSS support
.enableSassLoader()
// enables Vue support
.enableVueLoader(() => {
}, {
version: 3,
runtimeCompilerBuild: false //if using only single file components, this is not needed (https://symfony.com/doc/current/frontend/encore/vuejs.html#runtime-compiler-build)
})
// uncomment if you use TypeScript
.enableTypeScriptLoader()
// uncomment if you're having problems with a jQuery plugin
.autoProvidejQuery()
.addAliases({
'resources': path.resolve('./resources')
})
;
module.exports = Encore.getWebpackConfig();
package.json:
{
"devDependencies": {
"@symfony/webpack-encore": "^1.5.0",
"@types/jquery": "^3.5.5",
"@vue/compiler-sfc": "^3.0.2",
"babel-core": "^7.0.0-bridge.0",
"file-loader": "^6.0.0",
"https-proxy-agent": "^2.2.1",
"lorem-ipsum": "^2.0.3",
"sass": "^1.32.13",
"sass-loader": "^10.2.0",
"ts-loader": "^8.3.0",
"tslib": "^2.3.0",
"vue-loader": "^16.5.0",
"vue-template-compiler": "^2.6.12",
"webpack-notifier": "^1.6.0"
},
"license": "UNLICENSED",
"private": true,
"scripts": {
"dev-server": "encore dev-server",
"dev": "encore dev",
"watch": "encore dev --watch",
"build": "encore production --progress"
},
"dependencies": {
"@babel/polyfill": "^7.12.1",
"@ckeditor/ckeditor5-build-classic": "^25.0.0",
"@fortawesome/fontawesome-free": "^5.15.3",
"@popperjs/core": "^2.5.4",
"@tinymce/tinymce-vue": "^4.0.0",
"@vee-validate/rules": "^4.2.4",
"@vueform/multiselect": "^2.0.1",
"axios": "^0.21.1",
"bootstrap": "^5.0.2",
"chart.js": "^2.9.4",
"core-js": "^3.6.5",
"dropzone": "^5.9.2",
"element-plus": "^1.0.2-beta.36",
"es6-promise": "^4.2.8",
"inputmask": "^5.0.6",
"jquery": "^3.5.1",
"lodash": "^4.17.20",
"nprogress": "^0.2.0",
"perfect-scrollbar": "^1.5.0",
"select2": "^4.0.13",
"sweetalert2": "^10.10.0",
"typescript": "^4.3.4",
"vee-validate": "^4.5.0-alpha.2",
"vue": "^3.0.7",
"vue-inline-svg": "^3.0.0-beta.2",
"vue-router": "^4.0.3",
"vuex": "^4.0.0-rc.1",
"yup": "^0.29.3"
}
}