Unexpected token tsx
В приложении использую vue + webpack + typescript.
icons.tsx
export let searchIcon = <svg class="w-4 h-4 text-gray-500" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
</svg>
export const emailIcon = <svg class="h-4 w-4 text-gray-500" viewBox="0 0 24 24" stroke-width="2"
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z"/>
<rect x="3" y="5" width="18" height="14" rx="2"/>
<polyline points="3 7 12 13 21 7"/>
</svg>
export const keyIcon = <svg class="h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/>
</svg>
При обработке tsx возникает ошибка:
ERROR in ./assets/static/icons.tsx 1:24
Module parse failed: Unexpected token (1:24)
File was processed with these loaders:
* ./node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
> export let searchIcon = <svg class="w-4 h-4 text-gray-500" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
| <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
| </svg>;
Моя конфигурация webpack:
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const config = {
entry: './assets/index.ts',
mode: 'development',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js(x)?$/,
use: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader',
'postcss-loader',
]
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'postcss-loader',
'sass-loader',
]
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [
/\.vue$/
],
transpileOnly: true,
}
},
]
},
resolve: {
extensions: [
'.js',
'.vue',
'.tsx',
'.ts'
]
},
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: './assets/index.html',
})
],
devServer: {
historyApiFallback: true,
}
};
module.exports = config;
Мой tsconfig.json
{
"extends": "@vue/tsconfig/tsconfig.json",
"compilerOptions": {
/* Emit */
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
"verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
@vue/tsconfig/tsconfig.json
{
"compilerOptions": {
// Most non-library projects don't need to emit declarations.
// So we add this option by default to make the config more friendly to most users.
"noEmit": true,
// When type-checking with solution-style tsconfigs, though with `noEmit: true`, there won't
// be any `.d.ts` files emitted, but tsc still writes a `.tsbuildinfo` file to the `outDir`
// for each project. If we don't explicitly set the `outDir`, it will be in the same folder
// as the `tsconfig.json` file, which would look messy.
// Setting it to `./dist/` isn't ideal either, because it would pollute the `dist` folder.
// So we set it to a hidden folder in `node_modules` to avoid polluting the project root.
// FIXME:
// This caused a regression: https://github.com/vuejs/tsconfig/issues/27
// Need to find a better solution.
// "outDir": "./node_modules/.cache/vue-tsbuildinfo",
// As long as you are using a build tool, we recommend you to author and ship in ES modules.
// Even if you are targeting Node.js, because
// - `CommonJS` is too outdated
// - the ecosystem hasn't fully caught up with `Node16`/`NodeNext`
// This recommendation includes environments like Vitest, Vite Config File, Vite SSR, etc.
"module": "ESNext",
// We expect users to use bundlers.
// So here we enable some resolution features that are only available in bundlers.
"moduleResolution": "bundler",
"resolveJsonModule": true,
// `allowImportingTsExtensions` can only be used when `noEmit` or `emitDeclarationOnly` is set.
// But `noEmit` may cause problems with solution-style tsconfigs:
// <https://github.com/microsoft/TypeScript/issues/49844>
// And `emitDeclarationOnly` is not always wanted.
// Considering it's not likely to be commonly used in Vue codebases, we don't enable it here.
// Required in Vue projects
"jsx": "preserve",
"jsxImportSource": "vue",
// `"noImplicitThis": true` is part of `strict`
// Added again here in case some users decide to disable `strict`.
// This enables stricter inference for data properties on `this`.
"noImplicitThis": true,
"strict": true,
// <https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#verbatimmodulesyntax>
// Any imports or exports without a type modifier are left around. This is important for `<script setup>`.
// Anything that uses the type modifier is dropped entirely.
"verbatimModuleSyntax": true,
// A few notes:
// - Vue 3 supports ES2016+
// - For Vite, the actual compilation target is determined by the
// `build.target` option in the Vite config.
// So don't change the `target` field here. It has to be
// at least `ES2020` for dynamic `import()`s and `import.meta` to work correctly.
// - If you are not using Vite, feel free to overwrite the `target` field.
"target": "ESNext",
// For spec compilance.
// `true` by default if the `target` is `ES2020` or higher.
// Explicitly set it to `true` here in case some users want to overwrite the `target`.
"useDefineForClassFields": true,
// Recommended
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
// See <https://github.com/vuejs/vue-cli/pull/5688>
"skipLibCheck": true,
}
}
Есть ли способы исправить ошибку? Обязательно ли для tsx использовать babel-loader, либо можно все сделать через ts-loader