详解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动态调整iframe高度的代码
Apr 10 Javascript
利用jquery操作select下拉列表框的代码
Jun 04 Javascript
JS中this上下文对象使用方式
Oct 09 Javascript
解析jQueryEasyUI的使用
Nov 22 Javascript
微信小程序 input输入框控件详解及实例(多种示例)
Dec 14 Javascript
Vue开发过程中遇到的疑惑知识点总结
Jan 20 Javascript
Bootstrap table表格简单操作
Feb 07 Javascript
js for循环倒序输出数组元素的实例
Mar 01 Javascript
详解Vue CLI3 多页应用实践和源码设计
Aug 30 Javascript
vue-cli 2.*中导入公共less文件的方法步骤
Nov 22 Javascript
Vue基本使用之对象提供的属性功能
Apr 30 Javascript
如何管理Vue中的缓存页面
Feb 06 Vue.js
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/08/08 PHP
PHP两个n位的二进制整数相加问题的解决
2018/08/26 PHP
Javascript Boolean、Nnumber、String 强制类型转换的区别详细介绍
2012/12/13 Javascript
时间戳转换为时间 年月日时间的JS函数
2013/08/19 Javascript
深入了解Node.js中的一些特性
2014/09/25 Javascript
使用JavaScript链式编程实现模拟Jquery函数
2014/12/21 Javascript
jquery插件ContextMenu设置右键菜单
2017/03/13 Javascript
JS监控关闭浏览器操作的实例详解
2017/09/12 Javascript
在Vue.js中使用Mixins的方法
2017/09/12 Javascript
基于jquery实现五星好评
2017/11/18 jQuery
react实现菜单权限控制的方法
2017/12/11 Javascript
webpack中使用iconfont字体图标的方法
2018/02/22 Javascript
AngularJS实现的自定义过滤器简单示例
2019/02/02 Javascript
解决微信小程序调用moveToLocation失效问题【超简单】
2019/04/12 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
2019/04/15 Javascript
JavaScript实现旋转木马轮播图
2020/03/16 Javascript
[10:21]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster 选手采访
2021/03/11 DOTA
使用Python的Twisted框架实现一个简单的服务器
2015/04/16 Python
python django使用haystack:全文检索的框架(实例讲解)
2017/09/27 Python
使用Python搭建虚拟环境的配置方法
2018/02/28 Python
python 读取txt中每行数据,并且保存到excel中的实例
2018/04/29 Python
Python3实现的简单三级菜单功能示例
2019/03/12 Python
python pygame实现方向键控制小球
2019/05/17 Python
使用 Python 快速实现 HTTP 和 FTP 服务器的方法
2019/07/22 Python
Django发送邮件和itsdangerous模块的配合使用解析
2019/08/10 Python
一篇文章搞定Python操作文件与目录
2019/08/13 Python
Django之使用celery和NGINX生成静态页面实现性能优化
2019/10/08 Python
Django使用Celery加redis执行异步任务的实例内容
2020/02/20 Python
jupyter实现重新加载模块
2020/04/16 Python
pycharm实现print输出保存到txt文件
2020/06/01 Python
给校长的建议书500字
2014/05/15 职场文书
优秀研究生主要事迹
2014/06/03 职场文书
群众路线四风自我剖析材料
2014/10/08 职场文书
交警作风整顿剖析材料
2014/10/11 职场文书
励志语录:时光飞逝,请学会珍惜所有的人和事
2020/01/16 职场文书
mysql数据库入门第一步之创建表
2021/05/14 MySQL