首页 > 编程 > JavaScript > 正文

详解webpack2+React 实例demo

2019-11-19 15:29:22
字体:
来源:转载
供稿:网友

1.目录结构

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

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;}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表