搭建react项目

转载:https://www.cnblogs.com/baqiphp/p/7647912.html

1 初始化项目

npm init

2 安装依赖

安装webpack和webpack-dev-server

npm install webpack --dev

  • 安装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 --save

  • @types开头的包是typescript的声明文件
安装TypeScript,ts-loader和source-map-loader

npm install typescript ts-loader source-map-loader

  • ts-loader 可以让webpack使用typescript的标准配置文件tsconfig.json编译typescript代码
  • source-map-loader 生成自己的sourcemaps

3 添加typescript配置文件

当前根目录下创建tsconfig.json文件

   
{
  "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.js

  • 打开index.html查看页面
  • ! 如果webpack -v 出错,需安装webpack-cli

编写webpack开发环境配置文件

安装webpacl-dev-server

npm install webpack-dev-server --dev

  • 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.js

  • 打开网页,进入localhots:8080就可以看到我们的页面了。

  • 打开浏览器的开发者工具,在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" }

转载于:https://juejin.im/post/5c77fb89f265da2da8358a29

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值