.tsx webpack 编译失败:Unexpected token <

Posted

技术标签:

【中文标题】.tsx webpack 编译失败:Unexpected token <【英文标题】:.tsx webpack compile fails: Unexpected token < 【发布时间】:2016-03-19 15:45:11 【问题描述】:

我的应用程序使用 .ts、.js 和 .jsx 文件编译并运行。现在我尝试将 .jsx 文件更改为 .tsx 并且它会中断。

如何解决这个编译错误:

ts-loader: Using typescript@1.6.2 and C:\users\ruser\Desktop\Downloads\divinote\site\tsconfig.json                                                                                                                                                    67% 226/234 build modulesModuleParseError: Module parse failed: C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\ts-loader\index.js?cacheDirectory!C:\users\ruser\Desktop\Downloads\divinote\site\src\app\views\header\DiviAppBar.tsx 
Line 15: Unexpected token <
You may need an appropriate loader to handle this file type.
|     
|     DiviAppBar.prototype.render = function () 
|         return (<AppBar />);
|     ;
|     return DiviAppBar;
    at DependenciesBlock.<anonymous> (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack\lib\NormalModule.js:113:20)
    at DependenciesBlock.onModuleBuild (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:310:10)
    at nextLoader (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:275:25)
    at C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:292:15
    at context.callback (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:148:14)
    at Object.loader (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\ts-loader\index.js:431:5)
    at WEBPACK_CORE_LOADER_EXECUTION (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:155:71)
    at runSyncOrAsync (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:155:93)
    at nextLoader (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:290:3)
    at C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:259:5
    at Storage.finished (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:38:16)
    at C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\graceful-fs\graceful-fs.js:76:16
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:404:3)                                                                                                                                                                                     69% 337/338 build moduleschild_process.js:484

当我编译这段代码时:

"use strict";
import React = require('react');
import AppBar = require('material-ui/lib/app-bar');

class DiviAppBar extends React.Component

    render()
    
        return (
            <AppBar  />
        );
    


export = DiviAppBar;

使用这个 webpack 配置文件:

'use strict';

var webpack = require('webpack');
var htmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var path = require('path');
var rootPath = __dirname; //site
var srcPath = path.join(rootPath, 'src'); //site/src

module.exports =

    bail: true,
    cache: true,
    context: rootPath,
    debug: true,
    devtool: 'inline-source-map', //'eval-cheap-module-source-map','inline-source-map'
    target: 'web',
    devServer:
    
        contentBase: './dist',
        historyApiFallback: true
    ,
    entry:
    
        app: path.join(srcPath, 'app/main.jsx'),
        lib: ['react', 'react-router']
    ,
    output:
    
        path: path.join(rootPath, 'dist'),
        publicPath: '',
        filename: '[name].js',
        library: ['[name]', '[name]'],
        pathInfo: true
    ,
    resolve:
    
        root: srcPath,
        extensions: ['', '.js', '.jsx', '.ts', '.tsx'],
        modulesDirectories: ['node_modules', 'src', 'typings']
    ,
    module:
    
        loaders:
        [
            test: /\.js$/, loader: 'babel-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ ,
            test: /\.jsx$/, loader: 'babel-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ ,
            test: /\.ts$/, loader: 'ts-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ ,
            test: /\.tsx$/, loader: 'ts-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ ,
            test: /\.scss$/, loaders: ['style', 'css', 'sass'],
            test: /\.png$/, loader: 'file-loader',
            test: /\.jpg$/, loader: 'file-loader',
            test: /\.jpeg$/, loader: 'file-loader',
            test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?mimetype=image/svg+xml',
            test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff",
            test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff",
            test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/octet-stream",
            test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader",
        ]
    ,
    plugins:
    [
        new CopyWebpackPlugin
        ([
             from: 'src/images', to: 'images' 
        ]),
        new webpack.optimize.CommonsChunkPlugin('lib', 'lib.js'),
        new HtmlWebpackPlugin
        (
            inject: true,
            template: 'src/index.html'
        ),
        new webpack.NoErrorsPlugin()
    ]
;

还有这个 tsconfig.json 文件:


    "compilerOptions":
    
        "jsx": "preserve",
        "noImplicitAny": true,
        "module": "commonjs",
        "removeComments": false,
        "sourceMap": true,
        "target": "es5"
    ,
    "files": [],
    "exclude":
    [
        "node_modules",
        "dist"
    ]

【问题讨论】:

更改"jsx": "preserve" -> "jsx": "react" 会发生什么? 似乎更好,现在这一行 class DiviAppBar extends React.Component 给了我错误 TS2314: Generic type 'Component

' requires 2 个类型参数。但肯定它不应该有所作为吗? preserve 表示 .tsx 将变为 .jsx,然后 Babel 会将其转换为 .js,就像以前一样。 react 表示 ts-loader 会将 .tsx 直接转为 .js。

我会先尝试将 TS 升级到 TS 1.7 (github.com/Microsoft/TypeScript/releases) 以避免它只是 TS 中的一个错误。 完成。 TS 1.7.3 给出了同样的错误。我想我可以将它保留为 react,但我真的会编译以任何一种方式工作,并知道它为什么会失败:-( 【参考方案1】:

第一个问题与 Martin 提到的“jsx”配置有关。将“jsx”设置为“react”。

第二个问题与您的代码有关。改成这样:

class DiviAppBar extends React.Component<Props, State> ...

为您的道具创建一个界面,为您的状态创建另一个界面。如果您没有任何使用空对象。

class DiviAppBar extends React.Component<, > ...

【讨论】:

因为“preserve”会输出“jsx”文件而不是“js”。你要把那个输出传递给 babel 吗?如果是,请使用 preserve 和 "target": "es6"。如果没有,请使用"jsx": "react", "target": "es5"。我在您的问题中看不到相关代码。 啊,在 tsconfig.json 文档中我没有看到这两个设置必须结合使用。谢谢。 它们不相关。这就是您希望输出的方式。大多数浏览器不支持“es6”,这就是我们选择“es5”的原因。如果您打算只使用特定的浏览器,比如 chrome 扩展程序或 phonegap 应用程序,那么您会选择 target: "es6", jsx: "react" 哦,那我还是不明白为什么“preserve”会导致编译步骤失败,而“react”会成功。烦人的新奇技术。我想要 Turbo Pascal 回来。 我认为这是一个 webpack 问题。 “你可能需要一个合适的加载器来处理这种文件类型。”您将 jsx 文件作为 js 传递给另一个加载器(不是 ts-loader)。它可能是一个内部加载程序。要解决此问题,请将行 test: /\.tsx$/, loader: 'ts-loader?cacheDirectory' 更改为 test: /\.tsx$/, loader: 'ts-loader?cacheDirectory!babel-loader',它应该可以工作。

以上是关于.tsx webpack 编译失败:Unexpected token <的主要内容,如果未能解决你的问题,请参考以下文章

Webpack通过“模块解析失败,出现意外令牌”

使用 webpack 的 Proxyquire 无法编译

使用 Chrome 调试 React TypeScript .tsx 文件 - Webpack

通过webpack生产模式编译时如何忽略打字稿错误

Visual Studio 2019 编译.Net Core Console项目出现MSB4018 The "CreateAppHost" task failed unexpec(

OKHttp java.lang.IllegalArgumentException: Unexpec