【问题标题】:.tsx webpack compile fails: Unexpected token <.tsx webpack 编译失败: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,但我真的会编译以任何一种方式工作,并知道它为什么会失败:-(

标签: reactjs typescript webpack tsx


【解决方案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',它应该可以工作。
猜你喜欢
  • 2018-07-05
  • 1970-01-01
  • 2017-11-28
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 2015-10-16
  • 2020-10-12
相关资源
最近更新 更多