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


Ответы (0 шт):