2017-03-02 93 views
0

首先,我真的試圖自己修復它,我在這裏發現了幾個類似的問題,但沒有人幫助我。Node + React + Babel + Webpack,意外的令牌錯誤

收到此錯誤:

ERROR in ./src/components/App.jsx 
Module parse failed: D:\JS projects\habr-app\src\components\App.jsx Unexpected token (54:6) 
You may need an appropriate loader to handle this file type. 
| render() { 
|  return (
|  <div className='App'> 
|   <h1>Hello World!</h1> 
|   <div> 
@ ./src/client.js 3:0-42 
@ multi (webpack)-dev-server/client?http://0.0.0.0:8050 webpack/hot/dev-server babel-polyfill ./src/client.js 

client.js文件:

import React  from 'react'; 
import ReactDOM from 'react-dom'; 
import App  from './components/App'; 

ReactDOM.render ("<App />", document.getElementById('react-view')); 

呈現App.jsx功能如下:

render() { 
    return (
     <div className='App'> 
     <h1>Hello World!</h1> 
     <div> 
      <p>Введите Ваше имя:</p> 
      <div><input onChange={this.handleNameChange} /></div> 
      {this.renderGreetingWidget()} 
     </div> 
     </div> 
    ); 
    } 

webpack.config.js文件:

global.Promise   = require('bluebird'); 

var webpack   = require('webpack'); 
var path    = require('path'); 
var ExtractTextPlugin = require('extract-text-webpack-plugin'); 
var CleanWebpackPlugin = require('clean-webpack-plugin'); 

var publicPath   = 'http://localhost:8050/public/assets'; 
var cssName   = process.env.NODE_ENV === 'production' ? 'styles-[hash].css' : 'styles.css'; 
var jsName    = process.env.NODE_ENV === 'production' ? 'bundle-[hash].js' : 'bundle.js'; 

var plugins = [ 
    new webpack.DefinePlugin({ 
    'process.env': { 
     BROWSER: JSON.stringify(true), 
     NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development') 
    } 
    }), 
    new ExtractTextPlugin(cssName) 
]; 

if (process.env.NODE_ENV === 'production') { 
    plugins.push(
    new CleanWebpackPlugin([ 'public/assets/' ], { 
     root: __dirname, 
     verbose: true, 
     dry: false 
    }) 
); 
    plugins.push(new webpack.optimize.DedupePlugin()); 
    plugins.push(new webpack.optimize.OccurenceOrderPlugin()); 
} 

module.exports = { 
    entry: ['babel-polyfill', './src/client.js'], 
    resolve: { 
    extensions:   ['.js', '.jsx'] 
    }, 
    plugins: [ 
    new ExtractTextPlugin("styles.css"), 
    new webpack.LoaderOptionsPlugin({ 
     debug: true, 
     options: { 
     eslint: { configFile: '.eslintrc' } 
     } 
    }) 
    ], 
    output: { 
    path: `${__dirname}/public/assets/`, 
    filename: jsName, 
    publicPath 
    }, 
    module: { 
    rules: [ 
     { 
     test: /\.css$/, 
     use: ExtractTextPlugin.extract({ 
      fallback: "style-loader", 
      use: "css-loader" 
     }) 
     } 
    ], 
    loaders: [ 
     { 
     test: /\.css$/, 
     loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader'}) 
     }, 
     { 
     test: /\.less$/, 
     loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader!less-loader'}) 
     }, 
     { test: /\.gif$/, loader: 'url-loader?limit=10000&mimetype=image/gif' }, 
     { test: /\.jpg$/, loader: 'url-loader?limit=10000&mimetype=image/jpg' }, 
     { test: /\.png$/, loader: 'url-loader?limit=10000&mimetype=image/png' }, 
     { test: /\.svg/, loader: 'url-loader?limit=26000&mimetype=image/svg+xml' }, 
     { test: /\.(woff|woff2|ttf|eot)/, loader: 'url-loader?limit=1' }, 
     { test: /\.jsx?$/, loaders: ['react-hot-loader', 'babel-loader?presets[]=react,presets[]=es2015'], 
          exclude: [/node_modules/, /public/] , query: {presets: ['es2015', 'react', 'react-hot']} }, 
     { test: /\.json$/, loader: 'json-loader' }, 
    ] 
    }, 
    devtool: process.env.NODE_ENV !== 'production' ? 'source-map' : null, 
    devServer: { 
    headers: { 'Access-Control-Allow-Origin': '*' } 
    } 
}; 

我能解決這個問題的唯一辦法 - 就是把引號包圍的HTML渲染中:

render() { 
    return (
     `<div className='App'> 
     <h1>Hello World!</h1> 
     <div> 
      <p>Введите Ваше имя:</p> 
      <div><input onChange={this.handleNameChange} /></div> 
      {this.renderGreetingWidget()} 
     </div> 
     </div>` 
    ); 
    } 

但在那之後我想趁自己在瀏覽器和nodemon這個錯誤:

Invariant Violation: App.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object. 

我檢查並重新檢查所有依賴項,模塊和我的文件。 不過,我找不到一個錯誤。請有人幫助我嗎?

P.S.對不起,我可怕的英語。

有趣的事情。當我在App.jsx中啓動沒有引號的nodemon時,我的頁面加載,但沒有css。之後,我在文件App.jsx中添加引號,現在webpack-devserver構建一切正常,頁面在刷新後獲取.css。 JS-script仍然不起作用,但看起來應該像它應該...直到我重新啓動nodemon ...它開始顯示相同的錯誤「不變的違規:App.render():一個有效的React元素(或null)必須返回,您可能返回了未定義的數組或其他無效對象。「

+0

哪條線是54? –

+0

@Gonzalo,它的第一行html渲染功能。它希望看到' - 這個引用,但它破壞了Reactjs的邏輯。 – JamesListener

+0

可能很愚蠢,但使用babel的在線jsx編譯器https://babeljs.io/repl似乎是編譯好的。你能看到它是否使用雙引號編譯,而不是className ='App'中的單引號?改爲使用className =「App」。只是猜測,儘管 –

回答

0

該錯誤告訴你,你沒有定義一個可以處理JSX的加載器,雖然它可能看起來像你在你的webpack配置中做的那樣。問題是您定義了module.rulesmodule.loaders。當webpack看到module.rules時,它完全忽略了module.loaders(儘管爲了兼容性原因它仍然存在)。修復很簡單,只需將所有裝載機放在module.rules之下。

而且也有在你的.jsx?規則問題,因爲query(其也已過時,與options代替)不能用於裝載機的排列,而是應該每加載器陣列中進行定義。既然你把它作爲字符串內聯,你根本不需要它。

爲了得到一個工作配置更換module部分具有:

module: { 
    rules: [ 
    { 
     test: /\.css$/, 
     loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader'}) 
    }, 
    { 
     test: /\.less$/, 
     loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader!less-loader'}) 
    }, 
    { test: /\.gif$/, loader: 'url-loader?limit=10000&mimetype=image/gif' }, 
    { test: /\.jpg$/, loader: 'url-loader?limit=10000&mimetype=image/jpg' }, 
    { test: /\.png$/, loader: 'url-loader?limit=10000&mimetype=image/png' }, 
    { test: /\.svg/, loader: 'url-loader?limit=26000&mimetype=image/svg+xml' }, 
    { test: /\.(woff|woff2|ttf|eot)/, loader: 'url-loader?limit=1' }, 
    { test: /\.jsx?$/, use: ['react-hot-loader', 'babel-loader?presets[]=react,presets[]=es2015'], 
     exclude: [/node_modules/, /public/] }, 
    { test: /\.json$/, loader: 'json-loader' }, 
    ] 
}, 

如果你決定使用options,這無疑更可讀的是,你的.jsx?規則是這樣的:

{ 
    test: /\.jsx?$/, 
    use: [ 
    'react-hot-loader', 
    { loader: 'babel-loader', options: { presets: ['react', 'es2015'] } }, 
    ], 
    exclude: [/node_modules/, /public/] 
} 

如文檔use所示。

+0

感謝您的全面解釋,我今晚會嘗試。我的問題是我使用了教程,其中使用了webpack 1,但試圖重新制作webpack 2. – JamesListener

+0

在這種情況下,您還應該閱讀官方的[遷移指南](https://webpack.js.org/guides/)遷移/)。 –