用 express + webpack-dev-middleware/webpack-hot-middleware 替换 webpack-dev-server

Posted

技术标签:

【中文标题】用 express + webpack-dev-middleware/webpack-hot-middleware 替换 webpack-dev-server【英文标题】:Replacing webpack-dev-server with express + webpack-dev-middleware/webpack-hot-middleware 【发布时间】:2016-05-25 04:21:12 【问题描述】:

我目前正在尝试将使用 webpack-dev-server 的旧设置替换为基于 express + webpack-middleware 的更强大的解决方案。 所以我曾经像这样运行它:“webpack-dev-server --content-base public/--history-api-fallback”,但现在我想像这样使用它:“node devServer.js”。 以下是我当前设置的详细信息。

webpack.config.dev.js:

var path = require('path');
var webpack = require('webpack');
var debug = require('debug');

debug.enable('app:*');

var log = debug('app:webpack');

log('Environment set to development mode.');
var NODE_ENV = process.env.NODE_ENV || 'development';
var DEVELOPMENT = NODE_ENV === 'development';

log('Creating webpack configuration with development settings.');
module.exports = 
  devtool: 'cheap-module-eval-source-map',
  entry: [
    'eventsource-polyfill', // necessary for hot reloading with IE
    'webpack-hot-middleware/client',
    './src/index',
    './src/scss/main.scss',
  ],
  output: 
    path: path.join(__dirname, 'public/js'),
    filename: 'bundle.js',
    publicPath: '/'
  ,
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],
  module: 
    loaders: [
      test: /\.jsx?/,
      loaders: ['babel'],
      include: path.join(__dirname, 'src')
    ,
    
      test: /\.scss$/,
      loader: 'style!css!sass',
    ]
  ,
  compiler: 
    hash_type: 'hash',
    stats: 
      chunks: false,
      chunkModules: false,
      colors: true,
    ,
  ,
;

devServer.js:

var path = require('path');
var express = require('express');
var webpack = require('webpack');
var debug = require('debug');
// var history = require('connect-history-api-fallback');
var config = require('./webpack.config.dev');
var browserSync = require('browser-sync');

debug.enable('app:*');

var app = express();
var compiler = webpack(config);
var log = debug('app:devServer');

// app.use(history( verbose: false ));

log('Enabling webpack dev middleware.');
app.use(require('webpack-dev-middleware')(compiler, 
  lazy: false,
  noInfo: true,
  publicPath: config.output.publicPath,
  quiet: false,
  stats: config.compiler.stats,
));

log('Enabling Webpack Hot Module Replacement (HMR).');
app.use(require('webpack-hot-middleware')(compiler));


log('Redirecting...');
app.get('/', function(req, res) 
    res.sendFile(path.join(__dirname, '/public/', 'index.html'));
);

app.get('/js/bundle.js', function(req, res) 
    res.sendFile(path.join(__dirname, '/public/js/', 'bundle.js'));
);


var port = 3000;
var hostname = 'localhost';

app.listen(port, hostname, (err) => 
  if (err) 
    log(err);
    return;
  
  log(`Server is now running at http://$hostname:$port.`);
);

var bsPort = 4000;
var bsUI = 4040;
var bsWeInRe = 4444;

browserSync.init(
  proxy: `$hostname:$port`,
  port: bsPort,
  ui: 
    port: bsUI,
    weinre:  port: bsWeInRe ,
  ,
);

你能告诉我哪里出错了吗?我的印象是我已经涵盖了所有基础,但显然我错过了一些东西,因为尽管能够访问 html 和 js,但页面没有显示。 :(

【问题讨论】:

【参考方案1】:

你不需要这部分:

app.get('/js/bundle.js', function(req, res) 
    res.sendFile(path.join(__dirname, '/public/js/', 'bundle.js'));
);

webpack-dev-server 中间件会为你做这件事。所以,我认为只要删除它就可以解决它。

【讨论】:

【参考方案2】:

尝试静态资产的相对路径,例如,使用 /public/ 代替 ./public/,如图所示:

app.get('/', function(req, res) 
    res.sendFile(path.join(__dirname, '/public/', 'index.html'));
);

app.get('/js/bundle.js', function(req, res) 
    res.sendFile(path.join(__dirname, '/public/js/', 'bundle.js'));
);

而且我猜你肯定这个devServer.js在哪里,在完全相同的位置有一个并行文件夹public存在

你打的是localhost:3000/而不是localhost:3000

如果这不起作用,试试这个

app.use(express.static(path.resolve(__dirname, './public'),
    index: 'index.html'
));

【讨论】:

【参考方案3】:

这样的东西对我有用:

改变:

app.use(require('webpack-dev-middleware')(compiler, 

到:

var middleware = require('webpack-dev-middleware');
app.use(middleware)(compiler, 

然后将您的 app.get(s) 更改为:

app.get('/js/bundle.js', function(req, res)
  res.write(middleware.fileSystem.readFileSync(req.url));
  res.end();
);

app.get('*', function(req, res)
  res.write(middleware.fileSystem.readFileSync(path.join(__dirname, '/public/', 'index.html'))));
  res.end();
);

我无法测试您的特定配置,所以我想知道您是否会对第一个 app.get 有问题,因为您请求的 url 与您提供的不同,即“/js/bundle.js” '/public/js/bundle.js' 如果是这样,试试path.join(__dirname, '/public/js/bundle.js') 而不是req.url

第二个 app.get 应该为任何未解决的请求提供 index.html,这对 React 路由非常有用。

【讨论】:

以上是关于用 express + webpack-dev-middleware/webpack-hot-middleware 替换 webpack-dev-server的主要内容,如果未能解决你的问题,请参考以下文章

用Express简单创建一个Mock服务

用express做图片预览后台

怎么让新建的express包用公共的node

express 4.0x 用ejs妫傻腶pp.js没有app.configure,怎么弄

复习node中加载静态资源--用express+esj

用express搭建一个简单的博客系统