详解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 相关文章推荐
JS创建类和对象的两种不同方式
Aug 08 Javascript
JavaScript动态创建link标签到head里的方法
Dec 22 Javascript
JavaScript实现添加、查找、删除元素
Jul 02 Javascript
jquery表单验证插件formValidator使用方法
Apr 01 Javascript
微信小程序之仿微信漂流瓶实例
Dec 09 Javascript
JavaScript Uploadify文件上传实例
Feb 28 Javascript
Angular实现的内置过滤器orderBy排序与模糊查询功能示例
Dec 29 Javascript
JS实现的文件拖拽上传功能示例
May 21 Javascript
vue中使用protobuf的过程记录
Oct 26 Javascript
Vue组件内部实现一个双向数据绑定的实例代码
Apr 04 Javascript
微信小程序从注册账号到上架(图文详解)
Jul 17 Javascript
原生js拖拽功能制作滑动条实例代码
Feb 05 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类
2006/10/09 PHP
centos 5.6 升级php到5.3的方法
2011/05/14 PHP
php+mysqli预处理技术实现添加、修改及删除多条数据的方法
2015/01/30 PHP
php array_key_exists() 与 isset() 的区别
2016/10/24 PHP
防止jQuery ajax Load使用缓存的方法小结
2014/02/22 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
JavaScript函数详解
2014/11/17 Javascript
运行Node.js的IIS扩展iisnode安装配置笔记
2015/03/02 Javascript
JS 作用域与作用域链详解
2015/04/07 Javascript
js实现类似MSN提示的页面效果代码分享
2015/08/24 Javascript
解决前端跨域问题方案汇总
2016/11/20 Javascript
通过修改360抢票的刷新频率和突破8车次限制实现方法
2017/01/04 Javascript
基于JavaScript实现验证码功能
2017/04/01 Javascript
Easyui在treegrid添加控件的实现方法
2017/06/23 Javascript
JavaScript中document.referrer的用法详解
2017/07/04 Javascript
JS小球抛物线轨迹运动的两种实现方法详解
2017/12/20 Javascript
深入学习js函数的隐式参数 arguments 和 this
2019/06/24 Javascript
JavaScript变量Dom对象的所有属性
2020/04/30 Javascript
vuex 多模块时 模块内部的mutation和action的调用方式
2020/07/24 Javascript
vue中axios封装使用的完整教程
2021/03/03 Vue.js
Python实现截屏的函数
2015/07/25 Python
Python的pycurl包用法简介
2015/11/13 Python
Python实现树的先序、中序、后序排序算法示例
2017/06/23 Python
使用k8s部署Django项目的方法步骤
2019/01/14 Python
Python3 批量扫描端口的例子
2019/07/25 Python
Python json读写方式和字典相互转化
2020/04/18 Python
小结Python的反射机制
2020/09/28 Python
KARATOV珠宝在线商店:俄罗斯珠宝品牌
2019/03/13 全球购物
计算机专业推荐信范文
2013/11/27 职场文书
运动会开幕式邀请函
2014/02/03 职场文书
医院搬迁方案
2014/06/14 职场文书
鲁迅故居导游词
2015/02/05 职场文书
培训师岗位职责
2015/02/14 职场文书
大学生暑假实习总结
2015/07/13 职场文书
2019垃圾分类宣传口号汇总
2019/08/16 职场文书
Python入门之基础语法详解
2021/05/11 Python