详解webpack2+node+react+babel实现热加载(hmr)


Posted in Javascript onAugust 24, 2017

前端工程化开发的一个重要标志就是热替换技术,它大大的提高开发效率,使我们专注于写代码,webpack2中的热替换相比较1更加简洁。

1. 先看效果

详解webpack2+node+react+babel实现热加载(hmr)

2.目录结构

详解webpack2+node+react+babel实现热加载(hmr)

3.项目目录结构文件描述

bin 执行文件

node_modules node包

public 静态资源文件

  • static 静态资源
  • dist 编译后文件

src 项目js文件

.bablrc babel配置文件

webpack.config.dev.js开发模式webpack配置

webpack.config.pro.js生产模式webpack配置

3.技术依赖

  • node
  • react
  • babel
  • ES6/ES2015
  • react-hmre
  • webpack

babel-loader,css-loader,sass-loader,style-loader,webpack-hot-middleware,webpack-hot-middleware

热加载最重要的几个配置是packge.json/devserver.js/webpack.config.dev.js/webpack.config.prod.js/.babelrc

packge.json

{
 "name": "react-hmr-demo",
 "version": "1.0.0",
 "description": "react-hmr-demo",
 "main": "index.js",
 "scripts": {
  "dev": "node bin/devserver.js",
  "build":" webpack --config webpack.config.prod.js ",
  "start":"node bin/server.js"
 },
 "repository": {
  "type": "git",
  "url": "git+https://github.com/leinov/react-hmr-demo.git"
 },
 "author": "leinov",
 "license": "ISC",
 "dependencies": {
  "express": "^4.15.4",
  "react": "^15.6.1",
  "react-dom": "^15.6.1"
 },
 "devDependencies": {
  "babel-core": "^6.26.0",
  "babel-loader": "^7.1.2",
  "babel-polyfill": "^6.26.0",
  "babel-preset-es2015": "^6.24.1",
  "babel-preset-react": "^6.24.1",
  "babel-preset-react-hmre": "^1.1.1",
  "css-loader": "^0.28.5",
  "eventsource-polyfill": "^0.9.6",
  "node-sass": "^4.5.3",
  "sass-loader": "^6.0.6",
  "style-loader": "^0.18.2",
  "webpack": "^3.5.5",
  "webpack-dev-middleware": "^1.12.0",
  "webpack-hot-middleware": "^2.18.2"
 }
}

scripts的几个命令

$ npm run dev //开发模式
$ npm run build //编译打包
npm start //正式环境运行

webpack.config.dev.js

var path = require('path');
var webpack = require('webpack');
 
module.exports = {

  devtool: 'cheap-module-eval-source-map',//打包构建信息
  
  entry: [

    'eventsource-polyfill',//for IE
    'webpack-hot-middleware/client',//webpack服务连接到浏览器接收更新
    
    './src/index.js'
  ],
  
  output: {
    filename: 'boundle.js',
    publicPath: '/dist/js/' 
  },
  
  module: {

    loaders: [{
        test: /\.js$/,
        loaders: ['babel-loader'],
        exclude: /node_modules/ //哪些文件下的需要用到babel
      }, {
        test: /\.css$/,
        loaders: ['style-loader', 'css-loader'],
      },
      {
        test: /\.scss$/,
        loaders: ['style-loader', 'css-loader', 'sass-loader'],
      },
      {
        test: /\.(png|jpg|gif)$/,
        loaders: ['url?limit=8192&name=images/[name].[ext]'],
      }
    ]
  } ,
  
  resolve:{
  
    alias: {
    
      css: path.resolve(__dirname, 'public/static/css/'), //css目录别名
    }
  },
  
  plugins: [
  
    new webpack.HotModuleReplacementPlugin(),//热替换插件
    new webpack.NoEmitOnErrorsPlugin()
  ]
};

.babelrc

{
 "presets": ["react", "es2015"],
 "env": {
    "development": {
  
      "presets": ["react-hmre"]
    }
 }
}

devserver.js

var path = require('path');
var express = require('express');
var webpack = require('webpack');
var config = require('../webpack.config.dev');

var app = express();
var compiler = webpack(config);

var webpackDevMiddleware = require("webpack-dev-middleware");

app.use(webpackDevMiddleware(compiler, {

  noInfo: false, //true将打印编译信息(建议false,true会打印很多信息)
  publicPath: config.output.publicPath //绑定middleware
}));

var webpackHotMiddleware = require('webpack-hot-middleware');
app.use(webpackHotMiddleware(compiler));
 

app.get('*', function(req, res) {

  res.sendFile(path.resolve(__dirname, '../index.html')); //
});

app.listen(3100, function(err) {

  if (err) {
    console.log(err);
    return;
  }
  console.log('Listening at http://localhost:3100');
});

这样就可以实现热加载了,在项目根目录执行

$ npm run dev

详解webpack2+node+react+babel实现热加载(hmr)

webpack.config.prod.js

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

module.exports = {
  devtool: 'cheap-module-eval-source-map',
  entry: [
    './src/index.js'
  ],
  output: {

    path: path.join(__dirname, 'public/dist/js'),
    filename: 'boundle.js',
  
  },
  module: {

    loaders: [{
        test: /\.js$/,
        loaders: ['babel-loader'],
        exclude: /node_modules/ 
      }, {
        test: /\.css$/,
        loaders: ['style-loader', 'css-loader'],
      },
      {
        test: /\.scss$/,
        loaders: ['style-loader', 'css-loader', 'sass-loader'],
      },
      {
        test: /\.(png|jpg|gif)$/,
        loaders: ['url?limit=8192&name=images/[name].[ext]'],
      }
    ]
  } ,
  resolve:{
    alias: {
      css: path.resolve(__dirname, 'public/static/css/'),
      img: path.resolve(__dirname, 'public/static/img/'),
    }
  },

  plugins: [
  
     new webpack.HotModuleReplacementPlugin(),
     new webpack.NoEmitOnErrorsPlugin(),
     new webpack.optimize.UglifyJsPlugin({
         compress: {
          warnings: false
        }
      })
     
    ]
  };

生产的webpack主要完成开发后的编译打包,在plugins里多了压缩插件,在项目根目录执行

$ npm run build

详解webpack2+node+react+babel实现热加载(hmr)

bin/server.js

生产环境启动文件

var path = require('path');
var express = require('express');
var app = express();
 
var oneYear = 60 * 1000 * 60 * 24 * 30;

app.use(express.static(path.resolve(__dirname, '../public'), { maxAge: oneYear }));

app.get('*', function(req, res) {

  res.sendFile(path.resolve(__dirname,'../index.html'));
});

app.listen(3200, function(err) {

  if (err) {
    console.log(err);
    return;
  }
 console.log('Listening at http://localhost:3200');
 
});
$ npm start //运行生产环境

这里是项目地址 https://github.com/leinov/react-hmr-demo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript Archive Network 集合
May 12 Javascript
文本有关的样式和jQuery求对象的高宽问题分别说明
Aug 30 Javascript
node.js中的console.log方法使用说明
Dec 09 Javascript
jquery中object对象循环遍历的方法
Dec 18 Javascript
js阻止浏览器默认行为的简单实例
May 15 Javascript
JavaScript实现Java中Map容器的方法
Oct 09 Javascript
解决Mac下安装nmp的淘宝镜像失败问题
May 16 Javascript
Vue 让元素抖动/摆动起来的实现代码
May 31 Javascript
vue项目引入Iconfont图标库的教程图解
Oct 24 Javascript
vue 移动端适配方案详解
Nov 15 Javascript
viewer.js一个强大的基于jQuery的图像查看插件(支持旋转、缩放)
Apr 01 jQuery
html5中sharedWorker实现多页面通信的示例代码
May 07 Javascript
Vue网页html转换PDF(最低兼容ie10)的思路详解
Aug 24 #Javascript
JS对象序列化成json数据和json数据转化为JS对象的代码
Aug 23 #Javascript
Angular 2 利用Router事件和Title实现动态页面标题的方法
Aug 23 #Javascript
angular2路由切换改变页面title的示例代码
Aug 23 #Javascript
通俗解释JavaScript正则表达式快速记忆
Aug 23 #Javascript
bootstrap fileinput实现文件上传功能
Aug 23 #Javascript
jQuery Position方法使用和兼容性
Aug 23 #jQuery
You might like
php隐藏实际地址的文件下载方法
2015/04/18 PHP
php实现源代码加密的方法
2015/07/11 PHP
详谈php ip2long 出现负数的原因及解决方法
2017/04/05 PHP
PHP正则表达式函数preg_replace用法实例分析
2020/06/04 PHP
前淘宝前端开发工程师阿当的PPT中有JS技术理念问题
2010/01/15 Javascript
Extjs在exlipse中设置自动提示的方法
2010/04/07 Javascript
javascript中的float运算精度实例分析
2010/08/21 Javascript
javascript图像处理—仿射变换深度理解
2013/01/16 Javascript
javascript实现无限级select联动菜单
2015/01/02 Javascript
基于javascript代码实现通过点击图片显示原图片
2015/11/29 Javascript
你不知道的高性能JAVASCRIPT
2016/01/18 Javascript
jquery表单验证插件formValidator使用方法
2016/04/01 Javascript
jQuery插件datatables使用教程
2016/04/21 Javascript
AngularJS应用开发思维之依赖注入3
2016/08/19 Javascript
Bootstrap源码解读排版(1)
2016/12/23 Javascript
解决eclipse中没有js代码提示的问题
2018/10/10 Javascript
layui实现数据表格隐藏列的示例
2019/10/25 Javascript
关于vue路由缓存清除在main.js中的设置
2019/11/06 Javascript
微信小程序中target和currentTarget的区别小结
2020/11/06 Javascript
vue项目中js-cookie的使用存储token操作
2020/11/13 Javascript
[01:05:00]2018国际邀请赛 表演赛 Pain vs OpenAI
2018/08/24 DOTA
python实现在无须过多援引的情况下创建字典的方法
2014/09/25 Python
用Python编写脚本使IE实现代理上网的教程
2015/04/23 Python
为Python程序添加图形化界面的教程
2015/04/29 Python
python 实现语音聊天机器人的示例代码
2018/12/02 Python
TensorFlow实现批量归一化操作的示例
2020/04/22 Python
Python爬虫实例——爬取美团美食数据
2020/07/15 Python
Static Nested Class 和 Inner Class的不同
2013/11/28 面试题
生产现场工艺工程师岗位职责
2013/11/28 职场文书
开会迟到检讨书
2014/01/08 职场文书
2014三八妇女节活动总结范文四篇
2014/03/09 职场文书
保险经纪人求职信
2014/03/11 职场文书
计算机相关专业自荐信
2014/07/02 职场文书
高中同学会活动方案
2014/08/14 职场文书
大连星海广场导游词
2015/02/10 职场文书
2016年端午节校园广播稿
2015/12/18 职场文书