React开发~满满的干货

原创 黎云锐 教程 前端 5986阅读 28 天前 举报

一. Node.js开发环境的搭建及配置

二、React开发

三、Webpack打包机

四、TypeScript简单介绍

TypeScript类型的定义

五、辅助工具

六、其它

React开发

一. Node.js开发环境的搭建及配置

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。

下载安装和配置

下载安装

下载:http://nodejs.cn/download/

安装成功后,打开CMD窗口,键入

node -v

如果提示Node命令不存在,请手动修改环境变量,将nodejs安装目录添加至path目录

包管理工具

常用的有3种

npm Node自带,速度较慢

yarn 推荐使用,速度快。

cnpm 淘宝弄得

配置

设置代理(NPM默认代理很卡,需设置为淘宝镜像)

npm config set registry

安装yarn模块(强烈推荐),-g 表示全局模块

npm install yarn -g

常用的命令

安装模块

npm install <模块名> <-g> <–save或者–save-dev>

yarn add <模块名> <–save或者–save-dev>

卸载模块

npm uninstall <模块名> <-g>

yarn remove <模块名>

开始使用Node

常见第一个Node项目

在D盘创建一个文件夹webapp,通过命令行创建webapp项目

D:\webapp>npm init -y

项目创建成功后,目录中多出了一个package.json文件

配置文件package.json

{
"name": "webapp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}前端交流
裙hao582735936

name:表示项目名称

version:版本号

description:描述

main:加载时的入口文件,当你把项目分享给别人引用时,就是别人导入的模块。

scripts:脚本。

命令行键入 npm test 等同于键入 echo “Error: no test specified” && exit 1

dependencies:依赖的模块

devDependencies:开发环境依赖的模块

license:开源协议

二、React开发

React是用于构建用户界面的 JavaScript 库。

官网:https://doc.react-china.org/

构建第一个React项目

添加全局模块create-react-app(官方项目模板)

npm install -g create-react-app

创建React项目,名为webapp

D:>create-react-app my-app –scripts-version=react-scripts-ts

运行

D:\webapp>yarn start

运行成功后,浏览器会自动打开该项目。

简单分析官方的项目模板里的内容

目录结构

node_modules目录:存放的是项目依赖的模块(包括dependencies和devDependencies)

@type目录:typescript类型文件(有些模块源码不是用typescript写的,因此需要额外的添加类型文件)

script目录:带有script字眼的目录,通常是封装好的命令脚本。

其它:引入的模块

public目录:静态文件或者图片。

html文件,React会通过Js代码将项目添加到id为root的div下

可以新增一个css文件,进行全局样式的配置

src目录:我们的项目

项目入口文件是index.tsx

registerServiceWorker.ts是端口服务配置文件(涉及到NodeJs的API)

package.json,NodeJs依赖关系配置文件

tsconfig.json,typescript配置文件

tslint.json,代码规范配置文件(暂时不敢用,要求很严格)

package.json文件分析

{
"name": "webapp",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts-ts": "2.13.0"
},
"scripts": {
"start": "react-scripts-ts start",
"build": "react-scripts-ts build",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject"
},
"devDependencies": {
"@types/jest": "^22.2.0",
"@types/node": "^9.4.7",
"@types/react": "^16.0.40",
"@types/react-dom": "^16.0.4",
"typescript": "^2.7.2"
dependencies:依赖了三个模块react和react-dom是必须的核心模块,react-scripts-ts是react封装的webpack脚本模块。

devDependencies:主要是依赖了typescript模块,因为React源码是用flow(类似TypeScript)写的,因此需要添加Type类型支持。

scripts:常用的几个脚本。可以通过 npm start执行。

tsconfig.json文件分析
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
},
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
关键的几个配置介绍

outDir编译后的文件路径。

module模块化方式,(commonjs等)

target编译后的js版本

lib开发所有的Js版本

rootDir是ts项目的路径。

exclude和include,包含或不包含的文件夹。

其它的根据英文字面意思即可。

开始编写我们自己的代码

开发一个如下图的网页,点击添加,会将内容追加到下面:

src目录下添加 APP.tsx ListComponent.tsx AddComponent.tsx

}前端交流
裙hao582735936

APP.tsx
import as React from 'react';
import AddComponent from "./AddComponent";
import ListComponent from "./ListComponent";
export default class App extends React.Component<any, { data: string[] }> {
private _styles = {
container: {
width: "100%",
height: "100%",
}
};
constructor(prop:any,context){
super(prop, context);
this.state = {
data:[]
}
}
render() {
console.log("App render");
return (
<div style={this._styles.container}>
<AddComponent add={(text) => this.setState({data:[...this.state.data,text]})}/>
<ListComponent data={this.state.data}/>
</div>
);
}
}
AddComponent.tsx
import
as React from "react";
export default class AddComponent extends React.Component<{ add(text): void; }, any> {
private _height = "40px";
private _currValue = "";
private _styles= {
container: {
width: "300px",
height: this._height,
display: "flex",
flexDirection: "row",
margin: "100px",
},
input: {
height: "100%",
flex: 1,
},
add: {
height: "100%",
padding: "0 10px",
margin: "5px 10px"
}
};
render() {
console.log("AddComponent render");
return (
<div style={this._styles.container}>
<input
style={this._styles.input}
type="text"
placeholder="请输入要添加的内容"
onChange={(event) => this._currValue = event.target.value}/>
<input
style={this._styles.add}
type="button"
value="添加"
onClick={() => {
this.props.add(this._currValue);
}}/>
</div>
);
}
}
ListComponent.tsx
import * as React from "react";
export default class ListComponent extends React.Component<{ data: string[] }, any> {
private _styles = {
container: {
width: "100%",
flex: 1,
},
};
render() {
console.log("ListComponent render");
return (
<ul style={this._styles.container}>
{
this.props.data.map((value, index, array) => {
return (
<li>{"第" + index + "条记录," + value}</li>
);
})
}
</ul>
);
}
}
React实现了 JavaScript 中写 HTML , HTML 中写 JavaScript

JavaScript 中写 HTML ,是通过括号包裹的,可以写成如下:

let element = (<div><div>)

HTML 中写 JavaScript ,是通过大括号包裹的,可以写成如下

let element = (<div>{"你好"+"!"}<div>)

React组件必须继承React.Component,HTML布局通过render方法返回。

React动态的更新组件式通过setState方法执行的。

React可以通过外部传入属性,如:ListComponent组件中的data参数,获取方式是:this.props.data。

样式文件直接使用JSON来写即可,通过style引入。

React是单向数据流单页面组件,每次刷新都会调用render方法,手动刷新是通过调用setState方法。

烦恼:

由于刷新组件只能通过setState进行,意味着只能在组件内部进行更新页面。

由于是单向数据流,因此无法修改父组件传过来的属性,但是有时候就是要修改。

这时候数据绑定模块就出现了,主要有两种mobx和redux,redux虽然是主流,但是使用起来非常繁琐,Mobx是后起之秀,结合了redux的理念,操作简单,容易上手,网上也有相关的对比。

Mobx的使用

项目引入Mobx模块

修改package.json文件,在dependencies节点添加

"mobx": "^3.6.1",

"mobx-react": "^4.4.2",

执行命令行安装

yarn install

修改App.tsx和ListComponent.tsx文件

import as React from 'react';
import AddComponent from "./AddComponent";
import ListComponent, {appState} from "./ListComponent";
export default class App extends React.Component<any, { data: string[] }> {
private _styles = {
container: {
width: "100%",
height: "100%",
}
};
constructor(prop:any,context){
super(prop, context);
this.state = {
data:[]
}
}
render() {
console.log("App render");
return (
<div style={this._styles.container}>
<AddComponent add={(text) => appState.add(text)}/>
<ListComponent/>
</div>
);
}
}
import
as React from "react";
import {observer} from "mobx-react";
import {observable} from "mobx";
class AppState {
@observable data: string[] = [];
add(text:string){
this.data = [...this.data, text];
}
}
export const appState = new AppState();
@observer
export default class ListComponent extends React.Component<any, any> {
private _styles = {
container: {
width: "100%",
flex: 1,
},
};
render() {
console.log("ListComponent render");
return (
<ul style={this._styles.container}>
{
appState.data.map((value, index, array) => {
return (
<li>{"第" + index + "条记录," + value}</li>
);
})
}
</ul>
);
}
}
yarn start 运行即可

原理简单分析

observable 被观察者,mobx实时监测被观察者的变化,如果发生变化,就会通知observer更新。

observer 观察者,收到observable的更新通知后,observer会检查这个observable自己有没有在使用,如果在使用,就会更新(调用render方法)

单页面跳转必备-路由器 router

官网:https://react-guide.github.io/react-router-cn/

项目引入react-router模块

修改package.json, 在dependencieshe和节点添加

执行命令行安装

yarn install

开始编写路由器

修改APP.tsx

import React from "react";
import {Route, Router} from "react-router";
import {createBrowserHistory} from "history";
export const browserHistory = createBrowserHistory();
export default class App extends React.Component{
render(){
return(
<div style={{width:"100%",height:"100%",display:"flex",flexDirection:"column"}}>
<ul>
{
["nav1","nav2"].map((value, index, array)=>{
return(
<li onClick={()=>{
if(index ===0){
browserHistory.push("/first")
}else if(index ===1){
browserHistory.push("/second")
}
}}>{value}</li>
);
})
}
<Router history={browserHistory}>
<div>
<Route exact path="/" component={Home}/>
<Route path="/first" component={First}/>
<Route path="/second" component={Second}/>
</div>
</Router>
</ul>
</div>
);
}
}
class Home extends React.Component{
render(){
return(
<div>
Home界面
</div>
);
}
}
class First extends React.Component{
render(){
return(
<div>
First界面
</div>
);
}
}
class Second extends React.Component{
render(){
return(
<div>
Second界面
</div>
);
}
}
yarn start 运行即可

原理简单分析

待定,未知。

三、Webpack打包机

他可以轻松的处理 JavaScript 依赖关系和加载顺序,并按规则打包或压缩成指定格式。

原理介绍

有了打包机:

项目可以使用更高级的JS语法(ES6以上)。

项目可以使用更牛逼的TS语法

项目可以轻松的压缩成单js css文件

项目可以编译成指定ES版本的JS语法(目前浏览器完美支持es5)

项目可以把HTML写进JS文件,在根据loader转换成HTML(React)

很多很多。。。。只有你有对应loader。

webpack语法的简单介绍

可以在根目录新增一个webpack.config.js配置文件,通过webpack –config webpack.config.js 运行。

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
};
entry:入口文件。

output:输出路径

rules:规则配置,上面例子中配置了 当发现css文件时的处理方式。

plugins:插件,使用别人封装好的插件处理,比如发现html文件时使用的HtmlWebpackPlugin

第一个loader(less)

该例子背景是重新创建一个react-app

D:>create-react-app webapp –scripts-version=react-scripts-ts

修改package.json,增加两个dev依赖

“less”: “^3.0.1”,

“less-loader”: “^4.0.6”,

执行 yarn install 安装

打开路径node_modules/react-scripts-ts 这是react封装好的webpack

打开scripts/build看看build过程中,是引用了那个webpack.config配置。

const webpack = require('webpack');

const config = require('../config/webpack.config.prod');

function build(previousFileSizes) {

console.log('Creating an optimized production build...');

let compiler = webpack(config);

...省略...

}

由代码可知,build使用的config路径是”../config/webpack.config.prod”

打开这个webpack.config.prod文件,找到rules(打包规则)配置中关于css的解析,因为less本身属于css的范畴。

{
test: /.css$/,
loader: ExtractTextPlugin.extract(
Object.assign(
{
fallback: {
loader: require.resolve('style-loader'),
options: {
hmr: false,
},
},
use: [
{
loader: require.resolve('css-loader'),
},
{
loader: require.resolve('postcss-loader'),
},
],
},
)
),
},
}前端交流
裙hao582735936

test:目前只支持css文件,所以需要增加对less文件的支持,

test: /.(css|less)$/,

loader:目前只用了postcss-loader–>css-loader–>style-loader 需要增加ls-loader支持

loader: require.resolve(‘less-loader’)

修改后的配置

{
test: /.(css|less)$/,
loader: ExtractTextPlugin.extract(
Object.assign(
{
fallback: {
loader: require.resolve('style-loader'),
options: {
hmr: false,
},
},
use: [
{
loader: require.resolve('css-loader'),
},
{
loader: require.resolve('postcss-loader'),
},
{
loader: require.resolve('less-loader'),
}
],
},
)
),
},
同理,我们修改start脚本的配置(因为start脚本用的是另一个config)。

测试是否配置成功

将原来的 App.css 修改为 App.less

修改App.tsx文件中的 import ‘./App.css’; 修改为 import ‘./App.less’;

运行即可。

四、TypeScript简单介绍

官网:https://www.tslang.cn/

TypeScript是JavaScript的超集,它的存在并不是为了取代JavaScript,而是辅助JavaScript实现类型检查,直到ES支持强类型,TypeScript就是可以光荣退休了。

未来:TypeScript不存在淘汰的问题,因为它采用的是JavaScript语法,他所做的仅仅是增加了强类型。

比如:

let a:string = “test”;

编译成ES6

let a = “test”;

编译成ES5

var a = “test”;

所有的强类型在编译成JavaScript后都会消失。

TypeScript类型的定义

基础数据类型

  • string 字符串
  • number 数字
  • object 对象
  • undefined 未定义
  • {} 对象 可以指定成员
  • any 任意对象,懒人专用,定义后,typescript下岗了。

组合使用

  • {[key:string]:number} key为string value为number的对象

第一种:

interface IPerson{
name:string;
}
interface IStudent extends IPerson{
score?:string;
}
let student:Iprop;
第二种

type IStudent = {
name:string;
score?:string;
}
let student:Iprop;
第三种

let student:{name:string;score?:string;};

1

? 表示这个属性可有可无 student.score===undefined || string

五、辅助工具

cmder(推荐)

一款支持复制粘贴,支持linux命令的windows命令行工具,选用。

相关文章 http://blog.csdn.net/wnma3mz/article/details/78268463

WebStorm

WebStorm 的破解

license server http://idea.ibdyr.com

其它激活方式:

copy JetbrainsCrack-2.6.10-release-enc文件到Webstorm安装目录,点击下载JetbrainsCrack

修改 /bin/webstorm.exe.vmoptions 和 /bin/webstorm64.exe.vmoptions 文件,在最后面添加一行(注意修改路径)

-javaagent:D:/WebStorm 2017.3.5/JetbrainsCrack-2.6.10-release-enc.jar

获取注册码:http://idea.lanyus.com/

打开webstorm激活

WebStorm配置

开发语言的选择 File | Settings | Languages & Frameworks | JavaScript 默认的开发语言是ES6 修改为React JSX即可。

其它开发工具

VSCode(免费) VS的压缩版本

VS

Notepad+ 或 记事本

Xcode

六、其它

我的tsconfig配置文件

{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["esnext","dom"],
"jsx": "react",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"suppressImplicitAnyIndexErrors": true,
"removeComments": true,
"preserveConstEnums": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"noImplicitAny": false,
"allowSyntheticDefaultImports": true,
"noUnusedParameters": false,
"noUnusedLocals": false,
"strictNullChecks": true,
"noImplicitThis": true,
"sourceMap": true,
"allowJs": false,
"allowUnreachableCode": true,
"allowUnusedLabels": true,
"checkJs": false,
"baseUrl": "."
},
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
],
"include": [
"src"
],
"compileOnSave": true
}
outDir:编译后 build/dist目录下会出现编译后的文件。

module:模块化规范(commonjs等),好几种。

target:编译后的es版本,通常就是es5,浏览器支持es5,es6没有普及。

lib:开发过程中使用的es版本,看心情。

jsx:react或者react-native,native是移动端混合APP开发用的。

rootDir:项目所在位置。

sourceMap:如果没有souceMap,浏览器出现的一堆压缩过后的Js文件,很难受。没法调试。

其它有道词典走一波即可。

React的编程思想

响应式

组件化

React更新组件的算法

倘若git采用的算法叫做逐行算法,那么React采用的算法是同行算法。

欢迎大家来交流学习

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复