详解webpack2+React 实例demo


Posted in Javascript onSeptember 11, 2017

1.目录结构

源文件在src目录下,打包后的文件在dist目录下。

详解webpack2+React 实例demo

2.webpack.config.js

说明:

1.涉及到的插件需要npm install安装;
2.html-webpack-plugin创建服务于 webpack bundle 的 HTML 文件;
3.clean-webpack-plugin清除dist目录重复的文件;
4.extract-text-webpack-plugin分离css文件。

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;

var config = {
 context: path.resolve(__dirname, './src'),
 entry: {
  app: './main.js'
 },
 output: {
  path: path.resolve(__dirname, './dist'),
  filename: '[name].bundle.js'
 },
 devtool: 'cheap-module-eval-source-map',
 module: {
  rules: [
   {
    test: /\.jsx?$/,
    exclude: /node_modules/,
    loader: 'babel-loader'
   },
   {
     test: /\.css$/,
     use: ExtractTextPlugin.extract({
      fallback: "style-loader",
      use: ["css-loader","postcss-loader"]
    })
   },
   {
    test: /\.less$/,
    use: ["style-loader","css-loader","less-loader"]
   },
   { 
     test: /\.(png|jpg)$/,
     loader: 'url-loader',
     options: {
      limit: 8129
     }
   }
  ]
 },
 devServer:{
   historyApiFallback: true,
   host:'0.0.0.0',
   hot: true, //HMR模式  
   inline: true,//实时刷新
   port: 8181 // 修改端口,一般默认是8080
 },
 resolve: {
   extensions: ['.js', '.jsx', '.css'],
   modules: [path.resolve(__dirname, './src'), 'node_modules']
 },
 plugins: [ 
  new webpack.HotModuleReplacementPlugin(),
  new UglifyJsPlugin({
   sourceMap: true
  }),
  new webpack.LoaderOptionsPlugin({
   minimize: true,
   debug: true
  }),
  new HtmlWebpackPlugin({
    template:'./templateIndex.html' 
  }),
  new ExtractTextPlugin({
    filename: '[name].[hash].css',
    disable: false,
    allChunks: true,
  }),
  new CleanWebpackPlugin(['dist'])
 ],

}
module.exports = config;

// webpack里面配置的bundle.js需要手动打包才会变化,目录可以由自己指定;
// webpack-dev-server自动检测变化自动打包的是开发环境下的bundle.js,打包路径由contentBase决定,两个文件是不一样的.

3.postcss.config.js(Autoprefixer)

module.exports = {
 plugins: {
  'autoprefixer': {browsers: 'last 5 version'}
 }
}

// 兼容最新的5个浏览器版本

4.新建.babelrc

{
 "presets": ['es2015','react','stage-3']
}

5.index.html

<!doctype html>
<html lang="en">
 <head>
  <meta charset="utf-8">
  <title>React Project</title>
 </head>
 <body>
  <div id="content"></div>

  <script src="app.bundle.js"></script>
 </body>
</html>

6.package.json

npm install 或 yarn -> 安装模块,npm run build -> 打包,npm start -> 启动localhost:8181

{
 "name": "reactproject",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "dependencies": {
  "jquery": "^3.1.1",
  "react": "^15.3.2"
 },
 "devDependencies": {
  "autoprefixer": "^7.1.2",
  "babel-core": "^6.14.0",
  "babel-loader": "^6.2.5",
  "babel-plugin-syntax-async-functions": "^6.13.0",
  "babel-plugin-transform-async-to-generator": "^6.16.0",
  "babel-preset-es2015": "^6.14.0",
  "babel-preset-react": "^6.11.1",
  "babel-preset-stage-3": "^6.17.0",
  "bootstrap": "^4.0.0-alpha.2",
  "clean-webpack-plugin": "^0.1.16",
  "css-loader": "^0.25.0",
  "extract-text-webpack-plugin": "^3.0.0-rc.2",
  "file-loader": "^0.9.0",
  "html-webpack-plugin": "^2.29.0", 
  "jshint": "^2.9.3",
  "jshint-loader": "^0.8.3",
  "json-loader": "^0.5.4",
  "less": "^2.7.1",
  "less-loader": "^2.2.3",
  "moment": "^2.15.1",
  "node-sass": "^3.10.0",
  "postcss-loader": "^2.0.6", 
  "react-bootstrap": "^0.30.5",
  "react-dom": "^15.3.2",
  "sass-loader": "^4.0.2",
  "style-loader": "^0.13.1",
  "url-loader": "^0.5.7",
  "webpack": "^3.3.0",
  "webpack-dev-server": "^2.5.1"
 },
 "scripts": {
  "start": "webpack-dev-server --hot --inline --progress --colors --content-base .",
  "build": "webpack --progress --colors"
 },
 "keywords": [
  "reactcode"
 ],
 "author": "xhh",
 "license": "ISC"
}

7.main.js:入口文件

import React from 'react'
import { render } from 'react-dom';
import $ from 'jquery';

import Demo1 from './js/demo1.js';
// import Demo2 from './js/demo2.js';


render(<Demo1 title="这是提示" />, $('#content')[0]);
// render(<Demo2 myName="园中桥" sex="female"/>, $('#content')[0]);

8.templateIndex.html

打包后的模板index文件,插件html-webpack-plugin的template指定的目录。

<!doctype html>
<html lang="en">
 <head>
  <meta charset="utf-8">
  <title>Template Index html</title>
 </head>
 <body>
  <div id="content"></div>
 </body>
</html>

9.demo

demo1.js

import React from 'react';
import '../css/demo1.css';

const arr = [
  {
    name:'name1',
    tel:'12343456783'
  },
  {
    name:'name2',
    tel:'12343456784'
  },
  {
    name:'name3',
    tel:'12343456785'
  }
];

export default class Demo1 extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
     content: true,
     value: 'inputText'
    };  
  }

  handleClick(){
    this.setState({
     content: !this.state.content
    })
    // this.refs.myInput.focus();
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  renderArr() {
    return arr.map((item,index)=>{
        return <li key={index}>name:{item.name},tel:{item.tel}</li>
      })
  }

  render(){
    let btnStyle = {
      border: '1px solid #ccc',
      background:'#fff',
      color: '#a106ce'
    }
    return (
        /* 注释 */
        <div>
          <button style={btnStyle} className="btn" type="button" onClick={()=>this.handleClick()}>change state</button><br/>
          <p title={this.props.title} style={{ color:'#A349A4' }}>Hello { this.props.textCont}!</p>
          <p>{this.state.content ? 'initial value' : 'later value'}</p>
          { /* 标签里面的注释外面要用花括号 */ }
          <input type="text" value={this.state.value} ref="myInput" onChange={this.handleChange.bind(this)} /> 
          <h4>{this.state.value}</h4>
          <DemoChild><p>lalala</p></DemoChild>
          <ul>
            { this.renderArr() }
          </ul>
        </div>
      )
  }
}

Demo1.propTypes = {
  title: React.PropTypes.string.isRequired
}
Demo1.defaultProps = {
  textCont: 'React'
}

class DemoChild extends React.Component {
  constructor(props) {
    super(props);
  }

  render(){
    return (
        <div>我是子组件{this.props.children}</div>
      )
  }
}

demo1.css

ul {
  list-style: none;
  padding: 0;
  margin:0;
  display: flex;
}
.btn:focus {
  outline: none;
}

demo2.js:父子组件生命周期

import React, { Component, PropTypes } from 'react';
import '../css/demo2.css';

export default class Demo2 extends Component {
  constructor(props){
    super(props);
    this.state = {
      stateName: this.props.myName + ',你好',
      count: 0,
    }
    console.log('init-constructor');
  }
  static get defaultProps() {
    return {
      myName: "xhh",
      age: 25
    }
  }
  doUpdateCount(){
    this.setState({
      count: this.state.count+1
    })
  }
  componentWillMount() {
   console.log('componentWillMount');
  }
  componentDidMount() {
   console.log('componentDidMount')
  }
  componentWillReceiveProps(nextProps){
   console.log('componentWillReceiveProps')
  }
  shouldComponentUpdate(nextProps, nextState){
    console.log('shouldComponentUpdate');
    // return nextProps.id !== this.props.id;
    if(nextState.count > 10) return false;
    return true;
  }
  componentWillUpdate(nextProps,nextState){
    console.log('componentWillUpdate');
  }
  componentDidUpdate(prevProps, prevState){
    console.log('componentDidUpdate');
  }
  componentWillUnmount(){
    console.log('componentWillUnmount');
  }
  render(){
    console.log('render');
    return (
    <div>
      <p className="colorStyle">姓名:{this.props.myName}</p>
      <p>问候:{this.state.stateName}</p>
      <p>年龄:{this.props.age}</p>
      <p>性别:{this.props.sex}</p>
      <p>父元素计数是:{this.state.count}</p>
      <button onClick={ this.doUpdateCount.bind(this) } style={{ padding: 5,backgroundColor: '#ccc' }}>点我开始计数</button>
      <SubMyPropType count1={this.state.count} />
    </div>
    )
  }
}

Demo2.propTypes = {
  myName: PropTypes.string,
  age: PropTypes.number,
  sex: PropTypes.string.isRequired
}

class SubMyPropType extends Component {
  componentWillMount() {
   console.log('subMyPropType-componentWillMount');
  }
  componentDidMount() {
   console.log('subMyPropType-componentDidMount')
  }
  componentWillReceiveProps(nextProps){
   console.log('subMyPropType-componentWillReceiveProps')
  }
  shouldComponentUpdate(nextProps, nextState){
    console.log('subMyPropType-shouldComponentUpdate');
    if(nextProps.count1 > 5) return false;
    return true;
  }
  componentWillUpdate(nextProps, nextState){
    console.log('subMyPropType-componentWillUpdate');
  }
  componentDidUpdate(prevProps, prevState){
    console.log('subMyPropType-componentDidUpdate');
  }
  componentWillUnmount(){
    console.log('subMyPropType-componentWillUnmount');
  }
  render(){
    console.log('subMyPropType-render');
    return(
        <p>子元素计数是:{this.props.count1}</p>
      ) 
  }
}

demo2.css

.colorStyle {
  color: #0f0;
}

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

Javascript 相关文章推荐
jquery 常用操作方法
Jan 28 Javascript
JS中的public和private对象,即static修饰符
Jan 18 Javascript
借助script进行Http跨域请求:JSONP实现原理及代码
Mar 19 Javascript
如何让浏览器支持jquery ajax load 前进、后退功能
Jun 12 Javascript
给js文件传参数(详解)
Jul 13 Javascript
JS获取IMG图片高宽的简单实例
May 17 Javascript
又一枚精彩的弹幕效果jQuery实现
Jul 25 Javascript
利用js查找数组中指定元素并返回该元素的所有索引示例
Mar 29 Javascript
Vue 打包体积优化方案小结
May 20 Javascript
JS获取当前时间戳方法解析
Aug 29 Javascript
详解JavaScript 的执行机制
Sep 18 Javascript
JavaScript如何利用Promise控制并发请求个数
May 14 Javascript
react-native 完整实现登录功能的示例代码
Sep 11 #Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
Sep 11 #Javascript
Vuejs 页面的区域化与组件封装的实现
Sep 11 #Javascript
js封装成插件的步骤方法
Sep 11 #Javascript
vue.js移动端app之上拉加载以及下拉刷新实战
Sep 11 #Javascript
Chrome调试折腾记之JS断点调试技巧
Sep 11 #Javascript
JS中的Replace()传入函数时的用法详解
Sep 11 #Javascript
You might like
很实用的一个完整email发送程序
2006/10/09 PHP
PHP中文处理 中文字符串截取(mb_substr)和获取中文字符串字数
2011/11/10 PHP
使用php+apc实现上传进度条且在IE7下不显示的问题解决方法
2013/04/25 PHP
Yii中render和renderPartial的区别
2014/09/03 PHP
php实现判断访问来路是否为搜索引擎机器人的方法
2015/04/15 PHP
PHP入门教程之上传文件实例详解
2016/09/11 PHP
PHP读取word文档的方法分析【基于COM组件】
2017/08/01 PHP
用javascript获取当页面上鼠标光标位置和触发事件的对象的代码
2009/12/09 Javascript
javascript使用eval或者new Function进行语法检查
2010/10/16 Javascript
js 获取元素在页面上的偏移量的方法汇总
2015/04/13 Javascript
JQuery球队选择实例
2015/05/18 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
分享javascript实现的冒泡排序代码并优化
2016/06/05 Javascript
微信小程序 轮播图swiper详解及实例(源码下载)
2017/01/11 Javascript
jQuery分页插件jquery.pagination.js使用方法解析
2017/02/09 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
vuex实现购物车功能
2020/06/28 Javascript
antd中table展开行默认展示,且不需要前边的加号操作
2020/11/02 Javascript
在Python中使用itertools模块中的组合函数的教程
2015/04/13 Python
python机器学习之决策树分类详解
2017/12/20 Python
Python使用pip安装报错:is not a supported wheel on this platform的解决方法
2018/01/23 Python
python实现单目标、多目标、多尺度、自定义特征的KCF跟踪算法(实例代码)
2020/01/08 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
解决keras加入lambda层时shape的问题
2020/06/11 Python
爱尔兰家电数码商城:Currys PC World爱尔兰
2016/07/23 全球购物
高三自我鉴定范文
2013/10/19 职场文书
学生自我评价范文
2014/02/02 职场文书
电大本科自我鉴定
2014/02/05 职场文书
小学生检讨书大全
2014/02/06 职场文书
葬礼司仪主持词
2014/03/31 职场文书
人力资源管理毕业求职信
2014/08/05 职场文书
小学生十佳少年事迹材料
2014/08/20 职场文书
研修心得体会
2014/09/04 职场文书
2014年最新版离婚协议书范本
2014/11/25 职场文书
小学公民道德宣传日活动总结
2015/03/23 职场文书
室外天线与收音机天线杆接合方法
2022/04/05 无线电