详解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 相关文章推荐
共享自己写一个框架DreamScript
Jan 20 Javascript
JS Pro-深入面向对象的程序设计之继承的详解
May 07 Javascript
利用js制作html table分页示例(js实现分页)
Apr 25 Javascript
jQuery用FormData实现文件上传的方法
Nov 21 Javascript
基于javascript实现数字英文验证码
Jan 25 Javascript
vue两个组件间值的传递或修改方式
Jul 04 Javascript
原生js实现碰撞检测
Mar 12 Javascript
JS实现进度条动态加载特效
Mar 25 Javascript
JS中准确判断变量类型的方法
Jun 01 Javascript
谈谈JavaScript中的函数
Sep 08 Javascript
JavaScript实现跟随鼠标移动的盒子
Jan 28 Javascript
简单聊聊TypeScript只读修饰符
Apr 06 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-cli简介(不会Shell语言一样用Shell)
2013/06/03 PHP
解析thinkphp基本配置 convention.php
2013/06/18 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
php比较相似字符串的方法
2015/06/05 PHP
php与阿里云短信接口接入操作案例分析
2020/05/27 PHP
showModelessDialog()使用详解
2006/09/07 Javascript
JS 实现完美include载入实现代码
2010/08/05 Javascript
JavaScript浏览器选项卡效果
2010/08/25 Javascript
基于jquery的button默认enter事件(回车事件)。
2011/05/18 Javascript
jquery validate在ie8下的bug解决方法
2013/11/13 Javascript
JavaScript 32位整型无符号操作示例
2013/12/08 Javascript
BootStrap制作导航条实例代码
2016/05/06 Javascript
最好用的Bootstrap fileinput.js文件上传组件
2016/12/12 Javascript
Vue.2.0.5过渡效果使用技巧
2017/03/16 Javascript
vue中遇到的坑之变化检测问题(数组相关)
2017/10/13 Javascript
React Native时间转换格式工具类分享
2017/10/24 Javascript
让你5分钟掌握9个JavaScript小技巧
2018/06/09 Javascript
Node.js一行代码实现静态文件服务器的方法步骤
2019/05/07 Javascript
[03:01]完美盛典趣味短片 DOTA2年度最佳&拉胯英雄
2019/12/07 DOTA
[00:56]PWL开团时刻DAY8——追追追追追!
2020/11/09 DOTA
盘点提高 Python 代码效率的方法
2014/07/03 Python
Python实现Linux命令xxd -i功能
2016/03/06 Python
简单了解Python中的几种函数
2017/11/03 Python
Python批处理删除和重命名文件夹的实例
2018/07/11 Python
python-django中的APPEND_SLASH实现方法
2019/06/21 Python
python集合的新增元素方法整理
2020/12/07 Python
哪些情况下不应该使用索引
2015/07/20 面试题
合同专员岗位职责
2013/12/18 职场文书
工业学校毕业生自荐书
2014/01/03 职场文书
矫正人员思想汇报
2014/01/08 职场文书
测绘工程专业求职信
2014/07/15 职场文书
新闻人物通讯稿
2014/10/09 职场文书
一年级数学上册复习计划
2015/01/17 职场文书
李强优秀员工观后感
2015/06/16 职场文书
运动会广播稿200字
2015/08/19 职场文书
详解Python生成器和基于生成器的协程
2021/06/03 Python