1. 程式人生 > >一份極其簡單的基於webpack4搭的react專案

一份極其簡單的基於webpack4搭的react專案

webpack.config.js( 基於webpack4.x )

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');//匯入生成html檔案的外掛
const MiniCssExtractPlugin = require("mini-css-extract-plugin") //獨立打包css檔案外掛

//建立一個外掛例項
const htmlPlugin = new HtmlWebpackPlugin({
    template: path.join(__dirname, 'src/index.html'),//模板檔案
    filename: 'index.html'//生成檔名
});

const cssPlugin = new MiniCssExtractPlugin({//選項與htmlPlugin類似
    filename: "index.css"
})

//向外暴露一個配置物件,commonjs規範(因為webpack是基於node構建)
//webpack預設只能打包處理.js字尾的檔案,像.jpg .vue等檔案無法主動處理,所以需要配置第三方loader
module.exports = {
    mode: 'development', //development  production ( 生產環境會將程式碼壓縮 )
    //在webpack4中有一大特性是約定大於配置,預設打包入口路徑是'src/index.js',打包輸出路徑是'dist/main.js'
    plugins: [
        htmlPlugin,
        cssPlugin
    ],
    module: {//第三方loader
        rules: [
            {
                test: /\.(js|jsx)$/,
                use: 'babel-loader',
                exclude: /node_modules/ // 在使用babel-loader時候一定要加上exclude,排除node_modules資料夾 
            },
            // 解析css檔案  
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader']// use從右往左寫  
            },
            // 解析less  
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            }
        ]
    }
}

package.json

{
  "name": "day1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --open --port 3000"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "css-loader": "^0.28.11",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.0.2",
    "less-loader": "^4.1.0",
    "mini-css-extract-plugin": "^0.4.0",
    "style-loader": "^0.21.0",
    "webpack": "^4.6.0",
    "webpack-cli": "^2.1.2",
    "webpack-dev-server": "^3.1.4"
  },
  "dependencies": {
    "prop-types": "^15.6.1",
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-router-dom": "^4.2.2",
    "react-transition-group": "^1.2.1"
  }
}

.babelrc

{
    "presets": [
        "env",
        "stage-0",
        "react"
    ],
    "plugins": [
        "transform-runtime"
    ]
}

index.js

這裡要注意一點,react-router4後巢狀路由要寫在元件裡面

import React from 'react';
import ReactDOM from 'react-dom';
import {
    HashRouter as Router,
    Route,
    Link
} from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import TabNav from './components/TabNav'

import './css/base.css'

class App extends React.Component{
    render(){
        return (
            <div>
                <Route exact path="/" component={Home}/>
                <Route path="/about" component={About}/>
                <TabNav/>
            </div>
        )
    }
}

ReactDOM.render((
    <Router>
        <App/>
    </Router>
), document.getElementById('root'));

about.js,這是一個頁面元件,在跟元件上註冊了路由

import React from 'react';
import {Link, Route} from 'react-router-dom';
import Haha from '../components/Haha'

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

    render(){
        return (
            <div id="about">
                {/* 獲取路由傳參id */}
                <h2>這是關於我們頁面,暗號是{this.props.match.params.id}</h2>
                <Link to="/about/haha">haha</Link>
                {/* react-router4後巢狀路由寫在元件裡面 */}
                <Route path="/about/haha" component={Haha}/>
                {/* {this.props.children} */}
            </div>
        )
    }
}

export default About

home.js,這是展示首頁檔案,裡面實現了一個簡單的todolist小功能

import React from 'react'
import Todo from '../components/Todo'
import '../css/home.less'
import { CSSTransitionGroup } from 'react-transition-group';//引進react動畫組

class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            todos: [1, 2, 3]
        }
    }

    addList = val => {
        let { todos } = this.state;
        todos.unshift(val);
        this.setState({ todos });
    }

    render() {
        let list = this.state.todos.map((item, index) => <li key={index}>{item}</li>)
        return (
            <div id="home">
                <Todo add={this.addList} />
                <ul>
                    {/* react動畫 */}
                    <CSSTransitionGroup
                        transitionName="example"
                        transitionEnterTimeout={500}
                        transitionLeaveTimeout={300}>
                        {list}
                    </CSSTransitionGroup>
                </ul>
            </div>
        )
    }
}

export default Home

todo.js,上面home頁面實現todolist功能的元件,這裡值得注意的是在組建中定義的props屬性值使用prop-types包來設定引數

import React from 'react';
import PropTypes from 'prop-types';

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

    add = () => {
        if(this.input.value === ''){
            alert('不能為空')
        }else{
            this.props.add(this.input.value);
        }
    }

    render(){
        return (
            <div>
                <input type="text" ref={input => this.input = input}/>
                <button onClick={this.add}>新增</button>
            </div>
        )
    }
}

//指定屬性資料型別和必要性
Todo.propTypes = {
    add: PropTypes.func.isRequired
}

export default Todo

因為沒寫什麼功能,只作為簡單的react專案配置搭建。