原文链接这篇文章是同事写的,搭建Express结合Webpack。以下为正文,稍后附上我的解读。Express结合Webpack实现HMR。本文档主要讲结合Webpack和Express实现前后端热更新开发。如果你对webpack了解不多,建议阅读webpack官网文档什么是webpackdevserverwebpackdevserver是一个轻量级的node.jsexpressserver,实现webpack编译后代码的实时输出更新。常用于前后端分离的前端项目开发中。不过这篇文章不应该讲。webpackdev中间件Webpackdev中间件是WebPack的中间件。它用于在Express中分发需要通过WebPack编译的文件。可以单独使用,完成代码的热重载功能。特点:不会向硬盘写入任何文件,完全基于内存。如果你使用watch模式监控代码变化,Webpack会自动编译。如果在Webpack编译期间请求文件,Webpackdev中间件会延迟请求,直到编译完成后再发送编译好的文件。webpack热中间件Webpack热中间件订阅Webpack的编译更新,然后通过执行webpack的HMRapi将这些代码模块的更新推送到浏览器端。HMRHMR即HotModuleReplacement是Webpack的一个重要功能。它允许我们将更新代码实时应用到当前页面,而无需手动刷新浏览器页面。HMR的实现原理是在开发中的应用代码中加入HMRRuntime。它是HMR客户端(浏览器客户端)模块,用于与开发服务器通信并接收更新。服务端的工作就是前面提到的Webpack热中间件,它会在代码更新编译完成后,以json格式输出到HMRRuntime,动态更新相应的代码。webpack的配置首先在webpack的配置文件中引入varwebpack=require('webpack');varHotMiddleWareConfig='webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000'module.exports={context:__dirname,entry:[//添加与HotMiddleWare通信的客户端HotMiddleWareConfig,//添加web应用入口文件'./client.js'],output:{path:__dirname,publicPath:'/',filename:'bundle.js'},devtool:'#source-map',plugins:[newwebpack.optimize.OccurenceOrderPlugin(),//在webpack插件中引入webpack.HotModuleReplacementPluginnewwebpack.HotModuleReplacementPlugin(),newwebpack.NoErrorsPlugin()],};webpack-hot-中间件示例webpack.config.js在我们的开发环境中是这样配置的。getEntries根据我们的规则自动获取入口文件,并添加webpack热中配置。varwebpack=require('webpack');varpath=require('path')varmerge=require('webpack-merge')varbaseConfig=require('./webpack.base')vargetEntries=require('./getEntries')varpublicPath='http://0.0.0.0:7799/dist/';varhotMiddlewareScript='webpack-hot-middleware/client?reload=true';varassetsInsert=require('./assetsInsert')module.exports=merge(baseConfig,{entry:getEntries(hotMiddlewareScript),devtool:'#eval-source-map',output:{filename:'./[name].[hash].js',path:路径。resolve('./public/dist'),publicPath:publicPath},插件:[newwebpack.DefinePlugin({'process.env':{NODE_ENV:'"development"'}}),newwebpack.optimize.OccurenceOrderPlugin(),newwebpack.HotModuleReplacementPlugin(),newwebpack.NoErrorsPlugin(),newassetsInsert()]})Express中的配置Express中的配置主要有4个步骤:导入webpack的配置文件,生成webpack的编译器会compile链接编译器到webpackdev中间件链接编译器到webpack热中间件defineexpress配置varhttp=require('http');varexpress=require('express');varapp=express();app.use(require('morgan')('short'));//***************************************//这是这个例子的真正内容//*****************************************(function(){//第一步:导入webpack配置文件并生成webpack编译器//Step2:将编译器挂载到webpackdev中间件app.use(require("webpack-dev-middleware")(compiler,{noInfo:true,publicPath:webpackConfig.output.publicPath}));//Step3:将编译mountthedevicetowebpackhotmiddlewareapp.use(require("webpack-hot-middleware")(compiler,{log:console.log,path:'/__webpack_hmr',heartbeat:10*1000}));})();//定义快速配置app.get("/",function(req,res){res.sendFile(__dirname+'/index.html');});app.get("/multientry",函数(请求,资源){资源。sendFile(__dirname+'/index-multientry.html');});if(require.main===module){varserver=http.createServer(app);server.listen(process.env.PORT||1616,function(){console.log("Listeningon%j",server.address());});}webpack-hot-middleware示例server.js之间的区分开发和生产环境。注意一定要定义express在router之前定义webpack相关的中间件还有一点就是server.js只是在开发环境中使用,生产环境中我们不需要使用它们。所以在我们实际使用中,需要通过定义环境变量varNODE_ENV=process.env.NODE_ENV||来区分开发环境和生产环境。'production';varisDev=NODE_ENV==='development';if(isDev){varwebpack=require('webpack'),webpackDevMiddleware=require('webpack-dev-middleware'),webpackHotMiddleware=require('webpack-热中间件'),webpackDevConfig=require('./build/webpack.config.js');varcompiler=webpack(webpackDevConfig);app.use(webpackDevMiddleware(编译器,{publicPath:webpackDevConfig.output.publicPath,noInfo:true,stats:{colors:true}}));app.use(webpackHotMiddleware(编译器));routerConfig(app,{dirPath:__dirname+'/server/routes/',map:{'index':'/','api':'/api/*','proxy':'/proxy/*'}});varreload=require('重新加载');varhttp=require('http');varserver=http.createServer(app);重新加载(服务器,应用程序);app.use(express.static(path.join(__dirname,'public')));server.listen(port,function(){console.log('App(dev)isnowrunningonport'+port+'!');});}else{routerConfig(app,{dirPath:__dirname+'/server/routes/',map:{'index':'/','api':'/api/*','proxy':'/proxy/*'}});app.use(express.static(path.join(__dirname,'public')));app.listen(port,function(){console.log('App(dev)isnowrunningonport'+port+'!');});}supervisor在上面的前端,我们实现了hot前端文件的更新,但是当我们修改服务端文件时,Node不会自动重启,所以我们使用supervisor作为文件修改事件的监听器来自动重启Node服务需要全局安装supervisornpminstallsupervisor-g安装完成后,我们可以在命令行使用我们在package.json的scripts中写的常用命令,然后只用npmrunxxx来使用“scripts”:{"dev":"exportNODE_ENV=development&&supervisor-wserver,app.jsapp","build":"nodebuild/build.js","start":"nodeapp"},node-supervisorsupervisor[options]
