搭建react項目

轉載:https://www.cnblogs.com/baqiphp/p/7647912.htmlphp

1 初始化項目

npm initcss

2 安裝依賴

安裝webpack和webpack-dev-server

npm install webpack --devhtml

  • 安裝webpack和webpack-dev-server時要注意安裝版本,版本不兼容時webpack-dev-server指令運行出錯:(推薦版本) webpack-dev-server 2.9.1 webpack 3.6.0
  • webpack4中webpack和webpack-cli分開!!! 須要webpack、webpack-cli、webpack-dev-server全局和局部都安裝
安裝React和Types中React的聲明文件

npm install react react-dom @types/react @types/react-dom --savenode

  • @types開頭的包是typescript的聲明文件
安裝TypeScript,ts-loader和source-map-loader

npm install typescript ts-loader source-map-loaderreact

  • ts-loader 能夠讓webpack使用typescript的標準配置文件tsconfig.json編譯typescript代碼
  • source-map-loader 生成本身的sourcemaps

3 添加typescript配置文件

當前根目錄下建立tsconfig.json文件webpack

{
  "compilerOptions": {
    "outDir": "./dist/",  //輸出目錄
    "sourceMap": true,   //生成對應的sourceMap文件
    "noImplicitAny": true, //TypeScript 編譯器沒法推斷出類型時,它仍然會生成 JavaScript 文件
    "module": "commonjs",  //代碼規範,也能夠選amd
    "target": "es5",    //轉換成es5
    "jsx": "react"    //TypeScript具備三種JSX模式:preserve,react和react-native
  },
  "include": [
    "./src/**/*"  //須要編譯的目錄。
  ]
}
複製代碼

建立目錄,編寫代碼

建立目錄: components (src)
添加文件: Hero.tsx
import * as React from "react";

export interface ViewProps {
   name: string;
   age?: number;
}

export interface ViewState {}

export default class Hero extends React.Component<ViewProps,ViewState>{
   constructor(props: ViewProps){
       super(props);
       this.state = {};
   }

   render(){
       const { name, age = 1} = this.props;
       return (
           <div>
               <h6>英雄的信息:</h6>
               <p>姓名:{name}</p>
               <p>年齡:{age}</p>
           </div>
       );
   }
}

複製代碼
添加文件: index.tsx (src)
import * as React from "react";
import * as ReactDOM from "react-dom";

import Hero from "./components/Hero";

ReactDOM.render(
   <Hero name="安其拉" age={5}/>,
   document.getElementById("app") as HTMLElement
);
複製代碼
建立目錄: public(根目錄)
建立文件: index.html
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta http-equiv="X-UA-Compatible" content="ie=edge">
   <link rel="shortcut icon" href="./logo.jpg">
   <title>Model</title>
</head>
<body>
   <noscript>Script syntax is not currently supported</noscript>
   <div id="app"></div>
   <script src="../dist/bundle.js"></script>
</body>
</html>
複製代碼

編寫webpack配置文件

建立文件: webpack.common.config.js (根目錄)
  • 配置開發、生成的通用環境
module.exports = {
 entry: "./src/index.tsx",
 output: {
   filename: "bundle.js",
   path: __dirname + "/dist",
   publicPath: "./dist/" //打包生成文件訪問公共路徑
 },

 devtool: "source-map",

 resolve: {
   extensions: [".ts", ".tsx", ".js", ".json"]
 },

 module: {
   rules: [
     { test: /\.tsx?$/, loader: "ts-loader" },

     { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
   ]
 },

 plugins: [
 ],
};
複製代碼
根目錄下運行命令:

webpack --config webpack.common.config.jsweb

  • 打開index.html查看頁面
  • ! 若是webpack -v 出錯,需安裝webpack-cli

編寫webpack開發環境配置文件

安裝webpacl-dev-server

npm install webpack-dev-server --devtypescript

  • webpacl-dev-server提供的最基本也是最好用的熱更新功能
添加文件: webpack.dev.config.js
const webpack = require('webpack');
//引入公共配置
const config = require('./webpack.common.config'); 
//配置webpack-dev-server
config.devServer = {
 hot: true,  //開啓熱更新
 publicPath: '/dist/' //webpack-dev-server編譯後資源存放地址
}
config.plugins.push(new webpack.HotModuleReplacementPlugin());

module.exports = config;
複製代碼
運行命令:

webpack-dev-server --config webpack.dev.config.jsnpm

  • 打開網頁,進入localhots:8080就能夠看到咱們的頁面了。json

  • 打開瀏覽器的開發者工具,在console部分能看到如下兩句提示就說明熱更新啓動成功了。

    [HMR] Waiting for update signal from WDS... [WDS] Hot Module Replacement enabled.

  • 在package.json的scripts下添加 "start": "webpack-dev-server --config webpack.dev.config.js"

  • 輸入npm start 啓動服務。

添加簡單的redux

安裝依賴

npm install redux react-redux @types/react-redux --save

建立目錄: types (src)
建立文件: index.tsx (存放store的接口聲明)
export interface StoreState {
    languageName: string;
    enthusiasmLevel?: number;
}
複製代碼
建立目錄: constants (src)
建立文件: index.tsx (定義action和reducer使用的常量)
export const INCREMENT_ENTHUSIASM = "INCREMENT_ENTHUSIASM";
export type INCREMENT_ENTHUSIASM = typeof INCREMENT_EMTHUSIASM;

export const DECREMENT_ENTHUSIASM = "DECREMENT_ENTHUSIASME";
export type DECREMENT_ENTHUSIAM = typeof DECREMENT_ENTHUSIASM;
複製代碼
建立目錄: actions (src)
建立文件: index.tsx (存放action)
import * as constants from "../constants";

export interface IncrementEnthusiasm {
    type: constants.INCREMENT_ENTHUSIASM;
}

export interface DecrementEnthusiasm {
    type: constants.DECREMENT_ENTHUSIASM;
}

export type EnthusiasmAction = IncrementEnthusiasm | DecrementEnthusiasm;

export function incrementEnthusiasm():IncrementEnthusiasm {
    return {
        type: constants.INCREMENT_ENTHUSIASM
    }
}

export function decrementEnthusiasm():DecrementEnthusiasm {
    return {
        type: constants.DECREMENT_ENTHUSIASM
    }
}
複製代碼
建立目錄: reducers (src)
建立文件: index.tsx (存放reducer)
import { EnthusiasmAction } from "../actions";
import { StoreState } from "../types/index";
import { INCREMENT_ENTHUSIASM, DECREMENT_ENTHUSIASM } from "../constants/index";

export function enthusiasm(state: StoreState,action: EnthusiasmAction):StoreState {
    switch (action.type){
        case INCREMENT_ENTHUSIASM:
            return { ...state, enthusiasmLevel:state.enthusiasmLevel + 1 };
        case DECREMENT_ENTHUSIASM:
            {  ...state, enthusiasmLevel: Math.max(1,state.enthusiasmLevel - 1)};
        default: 
            return state;
    }
}
複製代碼
修改Hello組件
import * as React from "react";

export interface Props {
    name: string;
    enthusiasmLevel?: number;
    onIncrement?: () => void;
    onDecrement?: () => void;
}

export default function Hello ({name, enthusiasmLevel = 1, onIncrement, onDecrement}: Props){
    if(enthusiasmLevel <= 0) {
        throw new Error("error");
    }
    
    return (
       <div className="hello">
            <div className="greeting">
                Hello {name + getExclamationMarks(enthusiasmLevel)}
            </div>
            <div>
                <button onClick={onDecrement}>-</button>
                <button onClick={onIncrement}>+</button>
             </div>
        </div>
    );
}

function getExclamationMarks(numChars: number) {
    return Array(numChars + 1).join("!");
}
複製代碼
建立目錄: containers (src)
建立文件: Hello.tsx (Hello組件鏈接到redux的store中)
import Hello from "../components/Hello";
import * as actions from "../actions";
import { StoreState } from "../types/index";
import { connect,Dispatch } from "react-redux";

export function mapStateToProps({enthusiasmLevel,languageName}:StoreState){
    return {
        enthusiasmLevel,
        name: languageName
    };
}

export function mapDispatchToProps(dispatch: Dispatch<actions.EnthusiasmAction>){
    return {
        onIncrement: () => dispatch(actions.incrementEnthusiasm()),
        onDecrement: () => dispatch(actions.decrementEnthusiasm())
    };
}

export default connect (mapStateToProps,mapDispatchToProps)(Hello);
複製代碼
建立目錄: store (src)
建立文件: initState.tsx (定義store的初始值)
export default {
    enthusiasmLevel: 1,
    languageName: "TypeScript"
}
複製代碼
建立文件: configureStore.tsx (建立store)
import { createStore } from "redux";
import { enthusiasm } from "../reducers/index";
import { StoreState } from "./initState";

export default function() {
    const store = createStore<StoreState>(enthusiasm,initState);
    export store;
}
複製代碼
修改文件: index.tsx (src)
import * as React from "react";
import * as ReactDOM from "react-dom";
import Hello from "./containers/Hello";
import { Provider } from "react-redux";
import configureStore from "./store/configureStore";

const store = configureStore();
ReactDOM.render(
   <Provider store={store}>
       <Hello />
   </Provider>,
   document.getElementById("root") as HTMLElement
);
複製代碼

完善Redux

修改Hello組件

》》》待完善

添加React-Router

添加React-Router-Redux

添加開發必備配置

css-loader

安裝依賴

npm install css-loader style-loader --dev

  • css-loader 用來加載css文件
  • style-loader 把加載好的文件放入html中
編寫匹配規則:

{ test: /.css$/, loader: "style-loader!css-loader?modules" }

  • 沒有引用組件庫

{ test: /.css$/,loader: "style-loader!css-loader", include: /node_modules/ }

{ test: /.css$/,loader: "style-loader!css-loader?modules", exclude: /node_modules/ }

  • 引用了組件庫

file-loader

安裝依賴

npm install file-loader --dev

編寫匹配規則:

{ test: /.(png|jpe?g|gif)/, loader: "file-loader" }

相關文章
相關標籤/搜索