文章目录
第一步 通过官方的create-react-app,找个喜欢的目录,执行:
/** 最后面是项目根目录的名称 */
npx create-react-app react-app
第二步 暴露配置的文件,执行:
npm run eject
第三步 支持less
npm install less less-loader --save-dev
或
yarn add less less-loader
但安装完以后发现还是报错 TypeError: this.getOptions is not a function,这是因为less-loader的最新版本,与vue的less-loader配置不兼容
npm uninstall less-loader
npm install less-loader@5.0.0
或
yarn remove less-loader
yarn add less-loader@5.0.0
找到config/webpack.config.js
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
+ const lessRegex = /\.less$/;
+ const lessModuleRegex = /\.module\.less$/;
...(略)
// Opt-in support for SASS (using .scss or .sass extensions).
// By default we support SASS Modules with the
// extensions .module.scss or .module.sass
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules, but using SASS
// using the extension .module.scss or .module.sass
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
// 以下这里仿照上面sass的代码,配置下less。
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders({
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
}, 'less-loader'),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
{
test: lessModuleRegex,
use: getStyleLoaders({
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
},'less-loader'),
},
{
test: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
"less-loader"
),
},
第四步 创建路由
npm install react-router-dom --save
或
yarn add react-router-dom
在app.js使用路由
import React, { Fragment } from "react";
import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
import Login from './pages/Login';
import Home from './pages/Home';
import "./App.less";
function App() {
return (
<Fragment>
<HashRouter>
<Switch>
<Route path="/login" component={Login} />
<Route path="/home" component={Home} />
<Route exact path="/" component={Home} />
<Redirect to={"/home"} />
</Switch>
</HashRouter>
</Fragment>
);
}
export default App;
这里说明一下的属性:
path表示路径,这个很好理解。
component表示绑定的组件。
exact表示是否精确匹配。
第五步 解决跨域问题
npm install http-proxy-middleware --save-dev
或
yarn add http-proxy-middleware
在src下创建setupProxy.js,代码如下:
const proxy = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'^/mock',
proxy({
target: 'http://192.168.0.1:3000',
changeOrigin: true,
pathRewrite: { '^/mock': '' }
})
)
}
这代码的意思就是,只要请求地址是以"/mock"开头,那就反向代理到http://192.168.0.1:3000域名下,跨域问题解决!大家可以根据实际需求进行修改。
第六步 实现mockjs分离式开发
npm install mockjs --save
或
yarn add mockjs
在src下创建mock文件夹,然后创建mock.js文件
import Mock from "mockjs";
// eslint-disable-next-line
Mock.mock('http://test123.com', {//这里的url地址其实可以换成一个字段,比如msg,下边请求时候对应就可以
'name': '@cname',
'age|1-10': 10
})
Mock.mock('http://myname.com','post', {//这里的url地址其实可以换成一个字段,比如msg,下边请求时候对应就可以
'data|1-2':[{
'title':'@title',
'article':'@csentence'
}]
})
mockjs官网 http://mockjs.com/
在src文件夹中找到index.js引入
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';
+ import './mock/mock'
import './index.less';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
mockjs会拦截axios请求,自动返回设置的随机数据
第七步 axios请求后台接口或mock接口
npm install axios --save
或
yarn add axios
在需要的组件中使用
import React, { useEffect } from "react";
import { Button } from "antd";
import PdfView from "../components/pdf-view";
import TestPdf from "../accessts/test.pdf";
import axios from "axios";
function Home(props) {
useEffect(() => {
/** mockjs只能拦截axios请求 */
axios.get("http://test123.com").then((res) => {
console.log(res);
/** 结果是随机的,也有可能是其他值 */
});
}, []);
return (
<div>
<Button
type="primary"
onClick={() => {
props.history.push("/login");
}}
>
"点击返回登录页"
</Button>
<PdfView url={TestPdf} />
</div>
);
}
export default Home;
axios官网http://www.axios-js.com/
第八步(可选):配置antd,及其按需加载
npm i antd --save
或
yarn add antd
npm i babel-plugin-import --save-dev
或
yarn add babel-plugin-import
修改package.json文件
将babel部分改为如下代码
"babel": {
"presets": [
"react-app"
],
"plugins": [
["import", { "libraryName": "antd",
"style": "css"
}]
]
}
修改webpack.config.js文件,找到 if (preProcessor) {}将里面的内容修改如下
if (preProcessor) {
let preProcessorOptions = {
sourceMap: true,
};
if (preProcessor === "less-loader") {
preProcessorOptions = {
sourceMap: true,
//自定义主题
modifyVars: {
"primary-color": "#ff2d52", // 全局主色,
},
javascriptEnabled: true,
};
}
loaders.push(
{
loader: require.resolve("resolve-url-loader"),
options: {
sourceMap: isEnvProduction && shouldUseSourceMap,
},
},
{
loader: require.resolve(preProcessor),
options: preProcessorOptions,
}
);
}
更多主题配置请查阅https://ant.design/docs/react/customize-theme-cn
将app.css改为app.less, 并引入antd.less
@import '~antd/dist/antd.less';
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
第九步 将项目改造为typescript
1、全局安装ts
npm i -g typescript
2、创建tsconfig.json
tsc --init
修改tsconfig.json,开启jsx和allowJs配置,
3、安装开发环境依赖
npm install --save-dev typescript @types/react @types/react-dom ts-loader
或
yarn add typescript @types/react @types/react-dom ts-loader
改造项目,比如登录页面,将登录页面改为login.tsx
import React, { useEffect } from "react";
import { Input } from 'antd';
// import TestHtml from "../accessts/test.html";
const Login: React.FC = () => {
useEffect(() => { }, []);
return (
<div>
这是登录用的页面
<Input placeholder="请输入密码" />
<div id="html-content"></div>
</div>
);
};
export default Login;
app.js
import React, { Fragment } from "react";
import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
import Login from './pages/Login.tsx';
import "./App.less";
const App = () => {
return (
<Fragment>
<HashRouter>
<Switch>
<Route path="/login" component={Login} />
<Redirect to={"/login"} />
</Switch>
</HashRouter>
</Fragment>
);
}
export default App;
可能会提示这样一个错误 除非提供了’–jsx’标志,否则无法使用JSX
解决的办法: 在tsconfig.json文件中compilerOptions中加上 “jsx”: “react”,
{
"compilerOptions": {
"jsx": "react",
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}