详解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 相关文章推荐
能说明你的Javascript技术很烂的五个原因分析
Oct 28 Javascript
javascript获取选中的文本的方法代码
Oct 30 Javascript
javascript中文本框中输入法切换的问题
Dec 10 Javascript
js获取select默认选中的Option并不是当前选中值
May 07 Javascript
js星星评分效果
Jul 24 Javascript
jQuery插件制作的实例教程
May 16 Javascript
JavaScript中0和&quot;&quot;比较引发的问题
May 26 Javascript
总结js中的一些兼容性易错的问题
Dec 18 Javascript
anime.js 实现带有描边动画效果的复选框(推荐)
Dec 24 Javascript
浅谈Node.js 中间件模式
Jun 12 Javascript
vue 1.0 结合animate.css定义动画效果
Jul 11 Javascript
vue 保留两位小数 不能直接用toFixed(2) 的解决
Aug 07 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
php如何调用webservice应用介绍
2012/11/24 PHP
深入探讨:Nginx 502 Bad Gateway错误的解决方法
2013/06/03 PHP
十分钟打造AutoComplete自动完成效果代码
2009/12/26 Javascript
jquery 表格分页等操作实现代码(pagedown,pageup)
2010/04/11 Javascript
js修改input的type属性及浏览器兼容问题探讨与解决
2013/01/23 Javascript
JS获得URL超链接的参数值实例代码
2013/06/21 Javascript
jQuery中find()方法用法实例
2015/01/07 Javascript
jQuery EasyUI datagrid实现本地分页的方法
2015/02/13 Javascript
javascript将DOM节点添加到文档的方法实例分析
2015/08/04 Javascript
jquery实现的Accordion折叠面板效果代码
2015/09/02 Javascript
谈谈AngularJs中的隐藏和显示
2015/12/09 Javascript
Jquery和Js获得元素标签名称的方法总结
2016/10/08 Javascript
Vue render深入开发讲解
2018/04/13 Javascript
javascript中join方法实例讲解
2019/02/21 Javascript
Python使用sorted排序的方法小结
2017/07/28 Python
Python将多个excel表格合并为一个表格
2021/02/22 Python
解决PyCharm的Python.exe已经停止工作的问题
2018/11/29 Python
Python流行ORM框架sqlalchemy安装与使用教程
2019/06/04 Python
Python对Excel按列值筛选并拆分表格到多个文件的代码
2019/11/05 Python
python带参数打包exe及调用方式
2019/12/21 Python
python range实例用法分享
2020/02/06 Python
Python列表嵌套常见坑点及解决方案
2020/09/30 Python
建筑工程管理专业自荐信范文
2013/12/28 职场文书
《灯光》教学反思
2014/02/08 职场文书
党员群众路线承诺书
2014/05/20 职场文书
计算机售后服务承诺书
2014/05/30 职场文书
销售队伍口号
2014/06/11 职场文书
公司领导九九重阳节发言稿2014
2014/09/25 职场文书
人事代理委托书
2014/09/27 职场文书
上班迟到检讨书范文300字
2014/11/02 职场文书
铁路安全反思材料
2014/12/24 职场文书
行政司机岗位职责
2015/04/10 职场文书
钱学森观后感
2015/06/04 职场文书
涨工资申请书应该怎么写?
2019/07/08 职场文书
Nginx缓存设置案例详解
2021/09/15 Servers
vue中控制mock在开发环境使用,在生产环境禁用方式
2022/04/06 Vue.js