【问题标题】:Webpack doesn't recognise jsx syntaxWebpack 无法识别 jsx 语法
【发布时间】:2019-05-18 22:48:19
【问题描述】:

我有以下 Webpack 配置:

... 
module: {
    rules: [
        {
            test: /.js$/,
            loader: 'babel-loader',
            include: path.resolve(__dirname, 'src'),
            exclude: /node_modules/,
            options: {
                presets: [['@babel/preset-env', { modules: false }], '@babel/preset-react'],
                plugins: [
                    ['@babel/plugin-proposal-object-rest-spread', { useBuiltIns: true }],
                    '@babel/plugin-proposal-class-properties'
                ]
            }
        },
        {
            test: /\.scss$/,
            loader: 'ignore-loader'
        },
        {
            test: /\.css$/,
            loader: 'ignore-loader'
        },
        {
            test: /\.(jpg|png|svg|gif|pdf)$/,
            loader: 'file-loader',
            options: {
                name: '[path][name].[ext]'
            }
        }
    ]
}

但我收到以下错误:

        <StaticRouter location={path} context={context}>
        ^

SyntaxError: Unexpected token <

我在渲染器中使用它:

const renderer = (html, path, context) => {
    const serverHtml = ReactDOM.renderToString(
        <StaticRouter location={path} context={context}>
            <Layout />
        </StaticRouter>
    );
    const regex = /(<div id="root">)(<\/div>)/;
    return html.replace(regex, function(original, div1, div2) {
        return div1 + serverHtml + div2;
    });
};

我在这里称它为一个简单的测试:

app.get("*", function(req, res) {
    fs.readFile("./src/server/html/index.html", "utf8", function(err, data) {
        const context = {};
        const html = renderer(data, req.path, context);
        console.log(html);
        res.send(html);
    });
});

这些是我的开发依赖项(package.json):

  "devDependencies": {
    "@babel/cli": "^7.4.4",
    "@babel/core": "^7.4.4",
    "@babel/plugin-proposal-class-properties": "^7.4.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.4.4",
    "@babel/plugin-syntax-dynamic-import": "^7.2.0",
    "@babel/preset-env": "^7.4.4",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.4",
    "css-loader": "^2.1.1",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.6.0",
    "node-sass": "^4.12.0",
    "nodemon": "^1.18.11",
    "sass-loader": "^7.1.0",
    "webpack": "^4.30.0",
    "webpack-cli": "^3.3.2",
    "webpack-dev-middleware": "^3.7.0",
    "webpack-hot-middleware": "^2.25.0",
    "webpack-hot-server-middleware": "^0.6.0",
    "webpack-node-externals": "^1.7.2"
  }

@babel/preset-react 预设不应该处理它吗?

事实上,纯粹在配置文件上执行 webpack 不会抛出任何错误。
我要做的是执行热重载和 SSR,为此我使用 package.json 中提到的包。

启动应用程序并使用以下中间件时出现错误:

const app = express();

if (process.env.NODE_ENV !== 'production') {
    const webpack = require('webpack');
    const webpackDevMiddleware = require('webpack-dev-middleware');
    const webpackHotMiddleware = require('webpack-hot-middleware');
    const webpackHotServerMiddleware = require('webpack-hot-server-middleware');
    const config = require('../../webpack.development.config'); //Contains both client and server webpack config

    // Webpack dev hot reload middleware
    const compiler = webpack(config);
    app.use(webpackDevMiddleware(compiler, {
        serverSideRender: true,
        stats: {colors: true}
    }));

    app.use(webpackHotMiddleware(compiler.compilers.find(compiler => compiler.name === 'client')));
    app.use(webpackHotServerMiddleware(compiler));

}

注意:
实际上,我得到这个错误的原因是因为我应该先用 Webpack 转译代码。导入不起作用,因为显然 NodeJS 无法理解 JSX 语法。
不过,这并不能真正解决我的问题。我正在使用的 npm 包在导入完成后在运行时执行 webpack。
所以要么你想办法解决这个问题,要么我猜我将无法使用 jsx 语法......

【问题讨论】:

  • 可能不是webpack,如果你使用&lt;StaticRouter&gt; 组件,你能复制文件吗
  • @ramirozap 刚刚添加 :)
  • IIRC,React 必须在范围内才能触发 jsx 转译器。您是在引发错误的文件中导入 react 吗?
  • 也许试试 test: /\.(js|jsx)$/ 而不是 test: /.js$/,
  • @ramirozap 我将其导入为:const ReactDOM = require("react-dom/server"); 并且应该可以工作。 jsx 语法似乎有问题。我正在伤害我的大脑以找出原因......

标签: javascript reactjs webpack


【解决方案1】:

cannot supply both rules 就像你在这里所做的一样:

include: path.resolve(__dirname, 'src'),
exclude: /node_modules/,

排除将覆盖包含。要拥有“两者”,您需要这样写:

exclude: /node_modules\/(?!react)/

您还需要将 entry 参数指定给您的 src/index.js

【讨论】:

  • 谢谢我试过这个,但它并没有真正起作用,因为我在我的 OP 的最后一部分中提到了这个原因。关于 webpack 配置,我确实定义了条目,但没有共享整个 webpack 配置。但是关于你关于不能一起使用规则的评论,这对我来说没有意义。我想转译包含的内容并省略 node_modules。
猜你喜欢
  • 2019-02-06
  • 2018-03-25
  • 2016-05-16
  • 2016-05-20
  • 1970-01-01
  • 2016-06-05
  • 2016-02-02
  • 2019-04-07
相关资源
最近更新 更多