详解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 相关文章推荐
学习面向对象之面向对象的术语
Nov 30 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
Mar 01 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
Aug 06 Javascript
JavaScript驾驭网页-获取网页元素
Mar 24 Javascript
点击按钮出现60秒倒计时的简单js代码(推荐)
Jun 07 Javascript
基于vue.js实现图片轮播效果
Dec 01 Javascript
Bootstrap模态框案例解析
Mar 05 Javascript
基于JS递归函数细化认识及实用实例(推荐)
Aug 07 Javascript
jquery 一键复制到剪切板的实例
Sep 20 jQuery
解决js相同的正则多次调用test()返回的值却不同的问题
Oct 10 Javascript
详解vue3.0 diff算法的使用(超详细)
Jul 01 Javascript
Vue如何实现变量表达式选择器
Feb 18 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设计模式 Chain Of Responsibility (职责链模式)
2011/06/26 PHP
PHP flock 文件锁详细介绍
2012/12/29 PHP
浅谈PHP与C#的值类型指向区别的详解
2013/05/21 PHP
处理(php-cgi.exe - FastCGI 进程超过了配置的请求超时时限)的问题
2013/07/03 PHP
Yii2选项卡的简单使用
2017/05/26 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
2018/08/21 PHP
PHP lcfirst()函数定义与用法
2019/03/08 PHP
jQuery中(function(){})()执行顺序的理解
2013/03/05 Javascript
JavaScript基础语法、dom操作树及document对象
2014/12/02 Javascript
nodejs中实现路由功能
2014/12/29 NodeJs
jQuery+ajax实现滚动到页面底部自动加载图文列表效果(类似图片懒加载)
2016/06/07 Javascript
KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定
2016/10/10 Javascript
Javascript 获取鼠标当前的位置实现方法
2016/10/27 Javascript
EasyUI学习之Combobox下拉列表(1)
2016/12/29 Javascript
jquery实现图片放大点击切换
2017/06/06 jQuery
基于Cookie常用操作以及属性介绍
2017/09/07 Javascript
Vue 组件传值几种常用方法【总结】
2018/05/28 Javascript
vue + typescript + 极验登录验证的实现方法
2019/06/27 Javascript
JS开发自己的类库实例分析
2019/08/28 Javascript
axios 实现post请求时把对象obj数据转为formdata
2019/10/31 Javascript
jQuery 函数实例分析【函数声明、函数表达式、匿名函数等】
2020/05/19 jQuery
vue 图片裁剪上传组件的实现
2020/11/12 Javascript
python处理二进制数据的方法
2015/06/03 Python
Python使用设计模式中的责任链模式与迭代器模式的示例
2016/03/02 Python
numpy中的delete删除数组整行和整列的实例
2018/05/09 Python
Pycharm配置远程调试的方法步骤
2018/12/17 Python
Python 3.x基于Xml数据的Http请求方法
2018/12/28 Python
python自定义线程池控制线程数量的示例
2019/02/22 Python
Python趣味入门教程之循环语句while
2020/08/26 Python
详解CSS3的box-shadow属性制作边框阴影效果的方法
2016/05/10 HTML / CSS
英国礼品和生活方式品牌:Treat Republic
2020/11/21 全球购物
Java的五个基础面试题
2016/02/26 面试题
五年级学生期末评语
2014/12/26 职场文书
道歉信怎么写
2015/05/12 职场文书
go开发alertmanger实现钉钉报警
2021/07/16 Golang