无法设置 webpack-dev-server 来启动 React 应用程序 [英] Can't set up webpack-dev-server to start React app

查看:22
本文介绍了无法设置 webpack-dev-server 来启动 React 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前使用一个简单的脚本来启动 React 应用程序,但我需要以这种方式手动重新加载、重建和重新启动所有内容,这很乏味.现在我正在尝试设置 webpack-dev-server 来为我做这件事.不知何故,通过 ./node_modules/.bin/webpack-dev-server --inline --hot 启动 webpack-dev-server 只是从最顶层静态地提供文件文件夹而不是启动应用程序.以前我使用以下脚本来启动应用程序(运行良好):

#!/usr/bin/env 节点/*** 模块依赖.*/var app = require('../app');var debug = require('debug')('nodetest1:server');var http = require('http');/*** 从环境中获取端口并存储在 Express 中.*/var port = normalizePort(process.env.PORT || '3000');app.set('端口', 端口);/*** 创建 HTTP 服务器.*/var server = http.createServer(app);/*** 在所有网络接口上监听提供的端口.*/server.listen(端口);server.on('错误', onError);server.on('listening', onListening);/*** 将端口规范化为数字、字符串或 false.*/函数 normalizePort(val) {var port = parseInt(val, 10);如果(isNaN(端口)){//命名管道返回值;}如果(端口>= 0){//端口号返回端口;}返回假;}/*** HTTP 服务器错误"事件的事件监听器.*/函数 onError(error) {if (error.syscall !== 'listen') {抛出错误;}var bind = typeof port === 'string'?'管道' + 端口: '端口' + 端口;//用友好的消息处理特定的监听错误开关(错误代码){案例EACCES":console.error(bind + '需要提升权限');process.exit(1);休息;案例EADDRINUSE":console.error(bind + ' is already in use');process.exit(1);休息;默认:抛出错误;}}/*** HTTP 服务器监听"事件的事件监听器.*/函数 onListening() {var addr = server.address();var bind = typeof addr === '字符串'?'管道' + 地址: '端口' + addr.port;debug('监听' + 绑定);

webpack.config.js 看起来如下:

var path = require('path');模块.出口 = {入口: {应用程序:['babel-polyfill','./views/index.js']//供应商:["react","re​​act-dom"]},输出: {文件名:'bundle.js',路径:path.resolve(__dirname, './public')},开发工具:#eval-source-map",模块: {规则:[{测试:/\.jsx?$/,排除:/node_modules/,用: {loader: 'babel-loader?cacheDirectory=true',}},{测试:/\.css$/,loader: "style-loader!css-loader"},{测试:/\.(jpe?g|gif|png|svg)$/i,用: [{loader: 'url-loader',选项: {限制:10000}}]}]},节点:{fs: '空'},解决: {扩展名:['.js', '.jsx']},外部:{fs: '{}',tls: '{}',网: '{}',dns: '{}',阅读线:'{}'}};

使用 ./node_modules/.bin/webpack-dev-server --inline --hot 启动应用程序后,我看到以下输出:

任何建议将不胜感激.

<块引用>

更新

我将作为入口点的文件的名称从 app.html 更改为 public 文件夹中的 index.html 并且也更改了启动应用程序的命令 ./node_modules/.bin/webpack-dev-server --content-base public --inline --hot 和应用程序启动但对节点服务器的请求结果在 404 错误中,服务器没有以某种方式处理请求.我想这可能是因为 app.js 脚本没有运行,所以所有的中间件都没有设置,但我不确定如何预运行它或打包到 包中.js.不过我有两层:app.js 运行并显示登录页面,然后如果登录成功则重定向到实际的应用程序(当然开发不需要).

<块引用>

更新

我尝试使用 nodemon:

遵循此处的建议:

我找到了以下解决方案:https://github.com/babel/babel/issues/5268

但是在运行 npm install --save babel-standalone 后,错误仍然存​​在.

<块引用>

更新

我能够通过将 .json 添加到 extensions 来修复错误:https://github.com/discordjs/discord.js/issues/2656

现在 webpack 成功编译了项目并且没有任何错误,但是,当我使用 ./node_modules/.bin/webpack-dev-server --content-base public 启动它时 --inline --hot 在浏览器的控制台中我看到错误:Uncaught ReferenceError: require is not defined 并且没有加载任何东西.

<块引用>

更新

我试图关注:https://hackernoon.com/full-stack-web-application-using-react-node-js-express-and-webpack-97dbd5b9d708

它运行良好,但是当我更改 React 文件时,应用程序不会重新加载.另外 babel 在那里设置完全搞砸了我的项目,所以我现在无法构建项目.

解决方案

  1. 不知何故,通过 ./node_modules/.bin/webpack-dev-server --inline --hot 启动 webpack-dev-server 只是静态地从最顶层文件夹提供文件,而不是启动应用程序.

    正如您猜对的那样,这是因为您使用的是 app.html 而不是 index.html 并且 devServer 不知道默认加载哪个文件.您可以通过重命名文件来解决它,也可以在 webpack.config.js 中设置以下选项: devServer: {index: 'app.html'}- 有关详细信息,请参阅this.但我个人会像你一样重命名它.

  2. 应用已启动,但对节点服务器的请求导致 404 错误

    这可能有两个原因.首先,你的服务器没有启动,你必须像之前一样启动它(node ./bin/www),因为 devServer 只提供静态客户端资产,它没有你的任何服务器逻辑.其次,即使在您启动它之后,您也可能会遇到 404 错误.这取决于您如何指定 URL.如果您将它们指定为绝对路径(例如 http://localhost:3000/my-endpoint/path),那么它们应该正常访问您的主服务器,但如果您将它们指定为相对路径(/my-endpoint/path) 然后它们将被发送到 http://localhost:8080/my-endpoint/path(即 devServer 主机/端口而不是你的主服务器).要解决此问题,您可以在 webpack.config 中指定代理设置:

    devServer: {代理: [{context: ['/my-endpoint'],//要代理的端点target: 'http://localhost:3000'//你的主服务器地址}]}

    有关详细信息,请参阅.

好吧,您遇到的其他错误是因为您开始捆绑您的服务器(target: node)而不是您的客户端应用程序,正如您最初正确开始做的那样.当您成功捆绑服务器应用程序时,当然无法在浏览器中打开它,因为它是 Node.js 代码(例如,浏览器没有 require 方法,因此出现错误)

错过了关于 --content-base public 的评论.是的,如果您有一些预构建的资产,例如您的 app.html,您还必须指定您希望 devServer 提供服务的文件夹.另一种选择是使用 html-webpack-plugin将通过 webpack 动态生成 index.html,因此 devServer 知道从哪里获取它(从 devServer 保存所有生成资产的内存中).

I was using a simple script before to start a React app but I need to reload, rebuild, and restart everything manually this way which is tedious. Now I am trying to set up webpack-dev-server to do that for me. Somehow just starting the webpack-dev-server by ./node_modules/.bin/webpack-dev-server --inline --hot is just serving files statically from the topmost folder instead of launching the app. Previously I used the following script to start the app (it is working good):

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var app = require('../app');
var debug = require('debug')('nodetest1:server');
var http = require('http');

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);

The webpack.config.js looks the following way:

var path = require('path');

module.exports = {
  entry: {
    app: ['babel-polyfill', './views/index.js']
    //vendor: ["react","react-dom"]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './public')
  },
  devtool: "#eval-source-map",
  module: {
       rules: [{
           test: /\.jsx?$/,
           exclude: /node_modules/,
           use: {
               loader: 'babel-loader?cacheDirectory=true',
           }
       },
       {
         test: /\.css$/,
         loader: "style-loader!css-loader"
        },
        {
        test: /\.(jpe?g|gif|png|svg)$/i,
        use: [
        {
          loader: 'url-loader',
          options: {
            limit: 10000
          }
        }
      ]
        }]
  },
  node: {
    fs: 'empty'
  },
  resolve: {
    extensions: ['.js', '.jsx']
  },
      externals: {
        fs: '{}',
        tls: '{}',
        net: '{}',
        dns: '{}',
        readline: '{}'
      }
};

Upon starting the app with the ./node_modules/.bin/webpack-dev-server --inline --hot I see the following output:

Any suggestions would be greatly appreciated.

Update

I changed name of the file which is an entry point from app.html to index.html in the public folder and also changed the command to start the app to ./node_modules/.bin/webpack-dev-server --content-base public --inline --hot and the app started but the requests to the node server result in 404 errors, the server is not processing requests somehow. I guess that can be because app.js script was not run and so all the middleware was not set up, but I am not sure how to pre-run it or package into the bundle.js. I have two layers though: app.js runs and presents the login page and then redirects to the actual app if the login is successful (it is not needed for the development of course).

Update

I tried using nodemon: How to auto-reload files in Node.js?

By doing the following: nodemon ./bin/www where www is the server script. It is not watching for my changes at all. When I change some of .jsx files, no reloading happens.

Update

I tried to change the entry point in webpack.config.js from:

entry: {
    app: ['babel-polyfill', './views/index.js']
    //vendor: ["react","react-dom"]
  },

to:

entry: {
    app: ['babel-polyfill', './app.js']
    //vendor: ["react","react-dom"]
  },

But in this case when building the app it is giving me the error:

Following the advice here: https://github.com/webpack/webpack/issues/2142

I set target: node in the webpack.config.js. It started giving me another error:

I found the following solution: https://github.com/babel/babel/issues/5268

But after running npm install --save babel-standalone the error remained.

Update

I was able to fix the error by adding .json to the extensions: https://github.com/discordjs/discord.js/issues/2656

Now webpack compiled the project successfully and without any errors, however, when I started it with ./node_modules/.bin/webpack-dev-server --content-base public --inline --hot in the browsers' console I see the error: Uncaught ReferenceError: require is not defined and nothing loads.

Update

I was trying to follow: https://hackernoon.com/full-stack-web-application-using-react-node-js-express-and-webpack-97dbd5b9d708

And it is running fine but when I change the React files, the app is not reloaded. Also babel set ups there messed up my project completely, so I can not build the project now.

解决方案

  1. Somehow just starting the webpack-dev-server by ./node_modules/.bin/webpack-dev-server --inline --hot is just serving files statically from the topmost folder instead of launching the app.

    As you guessed correctly this was due to you had app.html instead of index.html and devServer didn't know which file to load by default. You can solve it as you did by renaming the file or you can set the following option in webpack.config.js: devServer: {index: 'app.html'} - see this for details. But I'd personally rename it as you did.

  2. the app started but the requests to the node server result in 404 errors

    This could be for 2 reasons. First, your server wasn't up, you had to start it as you started it before (node ./bin/www) since devServer just serves static client assets and it doesn't have any of your server logic. Second, even after you start it you will probably have 404 errors as well. This depends on how you specified URLs. If you specified them as an absolute path (like http://localhost:3000/my-endpoint/path) then they should hit your main server normally but if you specified them as a relative path (/my-endpoint/path) then they will be sent to http://localhost:8080/my-endpoint/path (i.e. devServer host/port instead of your main server). To solve this you can specify proxy settings in your webpack.config:

    devServer: {
      proxy: [{
        context: ['/my-endpoint'], // endpoints which you want to proxy
        target: 'http://localhost:3000' // your main server address
      }]
    }
    

    See this for details.

Well, other errors you had because you started to bundle your sever (target: node) instead of your client app as you correctly started to do at first. When you successfully bundled your server app of course you couldn't open it in a browser, since it is Node.js code (browser doesn't have require method for example, hence the error)

EDIT:

Missed a comment about --content-base public. Yes, you also have to specify the folder that you want devServer to serve if you have some prebuilt assets like app.html of yours. Another option is to use html-webpack-plugin which will generate index.html dynamically by webpack so devServer knows where to take it from (from the memory where devServer keeps all generated assets).

这篇关于无法设置 webpack-dev-server 来启动 React 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆