typescript+react+antd基础环境搭建

typescript+react+antd基础环境搭建(包含样式定制)

  • tsconfig.json 配置
// 具体配置可以看上面的链接 这里module moduleResolution的配置都会影响到antd的显示
// allowSyntheticDefaultImports  是antd官网给的配置 必须加上
{"compilerOptions": {"outDir": "./dist/","sourceMap": false,"noImplicitAny": false,"module": "es6","target": "es5","jsx": "preserve","moduleResolution": "node","forceConsistentCasingInFileNames": false,"allowJs": true,"allowSyntheticDefaultImports": true,"lib": ["es5", "dom","dom.iterable","es2015"]},"include": ["./src/**/*"]
}
  • package.json 配置
// 其中很多配置是用来做antd样式定制的
// concurrently 是用来将命令连接起来执行的 Run multiple commands concurrently
{"name": "power3","version": "1.0.0","description": "typescript && react for power3","main": "index.js","scripts": {"build": "webpack --progress --colors","start": "concurrently \"node ./server/server.js\" \" npm run dev \"","dev": "webpack-dev-server --progress --colors -p -d"},"author": "","license": "ISC","dependencies": {"antd": "^2.13.6","css-loader": "^0.28.7","immutable": "^3.8.2","md5": "^2.2.1","react": "^15.5.4","react-dom": "^15.5.4","react-hot-loader": "^3.1.1","react-router": "^4.2.0","react-router-dom": "^4.2.2"},"devDependencies": {"@types/node": "^8.0.34","@types/react": "^16.0.10","@types/react-dom": "^16.0.1","@types/react-router": "^4.0.15","@types/react-router-dom": "^4.0.8","awesome-typescript-loader": "^3.2.3","babel-core": "^6.26.0","babel-loader": "^7.1.2","babel-plugin-import": "^1.6.2","babel-preset-env": "^1.6.1","babel-preset-react": "^6.24.1","babel-preset-stage-0": "^6.24.1","concurrently": "^3.4.0","extract-text-webpack-plugin": "^2.1.0","html-webpack-plugin": "^2.30.1","less": "^2.7.2","less-loader": "^4.0.5","less-vars-to-js": "^1.2.0","source-map-loader": "^0.2.2","style-loader": "^0.19.0","typescript": "^2.5.3","url-loader": "^0.5.8","webpack": "^2.3.3","webpack-dev-server": "^2.4.2","webpack-hot-middleware": "^2.20.0"}
}
  • routes.tsx页面

该页面主要用来配置路由 指定登录页面
推荐使用react-router-dom 里面的各种接口直接继承感觉很方便

/*** 路由写到此处 页面一般会有层级关系 此处json对象是按照业务写成层级关系* 第一种做法是 处理成 平级的路由* 第二种是 根据业务的层级关系渲染出符合业务的相应导航* 此处两种都导出 然后在index.tsx中可以两种都试一下*/import {RouteProps} from 'react-router-dom'import Apple from './components/fruits/Apple'
import Banana from './components/fruits/banana'import Cabbage from './components/vegetables/cabbage'
import Radish from './components/vegetables/radish'interface PowerRouteProps extends RouteProps{name:string;
}export const _routes=[{id:'fruits',name:'水果',routes:[{name:'苹果',path:'/apple',component:Apple},{name:'香蕉',path:'/banana',component:Banana}]},{id:'vegetables',name:'蔬菜',routes:[{name:'白菜',path:'/cabbage',component:Cabbage},{name:'萝卜',path:'/radish',component:Radish}]}
];
// 此处变量我之前使用 routes 命名 结果在index.tsx引入时(import {routes} from './routes') 直接报错
// 注意导出变量名和文件名不能一样
export const maproutes = _routes.reduce((ary:PowerRouteProps[],cur:any)=>{return ary.concat(cur.routes||cur)
},[]).filter(x=>x.path && x.path!=='');
  • 简单的业务组件(只为了说明)

其他的组件可以在github上看

// ./components/vegetables/cabbage import * as React from 'react'export default class Cabbage extends React.Component{render(){return (<p>You need to eat cabbage</p>)}
}
  • 入口文件index.tsx

此处写了两种导航 一种有submenu 一种是使用plain数据直接将所有路由列出

import * as React from 'react'
import * as ReactDOM from 'react-dom'
import {HashRouter, Route, Switch, Link, BrowserRouter} from 'react-router-dom'
// 提供antd的本地语言支持
import {LocaleProvider, Menu} from 'antd'
const MenuItem = Menu.Item;
const SubMenu = Menu.SubMenu;import {maproutes,_routes} from './routes'
// plain 路由
class Navigation extends React.Component {render() {return (<Menu>{maproutes.map(route => {return (<MenuItem key={route.path}><Link to={route.path} key={`route-link-${route.path}`}>{route.name}</Link></MenuItem>)})}</Menu>)}
}
// 有层级关系的路由
class Navigations extends React.Component {render() {return (<Menu style={{width:200}} mode="inline">{_routes.map(routes=>{return (<SubMenu key={routes.id} title={routes.name}>{routes.routes.map(route=>{return (<MenuItem key={`route-${route.path}`}><Link to={route.path} key={`route-link-${route.path}`}>{route.name}</Link></MenuItem>)})}</SubMenu>)})}</Menu>)}
}class NotFoundView extends React.Component {render() {return (<div className="http-404"><h2 className="text-info">功能尚未开发完毕</h2><h3 className="text-danger">Page not found</h3></div>);}
}const Router = () => (<BrowserRouter><Switch>{maproutes.map(route => {// return <Route path={route.path} key={`route-path-${route.path}`} location={route.location} component={route.component}/>return <Route path={route.path} key={`route-${route.path}`} component={route.component}/>})}<Route path="/" exact component={Navigations}/><Route component={NotFoundView}/></Switch></BrowserRouter>
)ReactDOM.render(<Router/>, document.getElementById('app'));
  • 样式定制(使用社区提供的方法)

创建.babelrc文件
在终端(ctrl+`)中输入 type null>.babelrc

.babelrc文件

plugins的配置是为了让antd的样式生效

{"presets": [["env"],"stage-0","react"],"plugins": ["react-hot-loader/babel",["import", { "libraryName": "antd","style": true}]]}
  • 最后一步 webpack.config.js文件编写
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const fs = require('fs');
const lessToJs = require('less-vars-to-js');// 获取自己定义的要覆盖antd默认样式的文件
const themeVariables = lessToJs(fs.readFileSync(path.join(__dirname, './src/assets/style/themes.less'), 'utf8'));module.exports = {entry: "./src/index.tsx",output: {filename: "bundle.js",path: __dirname + "/dist"},// Enable sourcemaps for debugging webpack's output.devtool: "cheap-moudle-source-map",resolve: {// Add '.ts' and '.tsx' as resolvable extensions.extensions: [".ts", ".tsx", ".js", ".json"]},devServer: {port: 8003,hot: true,// historyApiFallback: true,historyApiFallback: {index: '/react.min.js'},contentBase: path.resolve(__dirname, 'dist'),publicPath: '/'},module: {rules: [// All files with a '.ts' or '.tsx' extension will be handled by// 'awesome-typescript-loader'.{test: /\.(tsx|ts)?$/,use: [{loader: 'react-hot-loader/webpack'}, {loader: 'babel-loader'}, {loader: 'awesome-typescript-loader'}]},// All output '.js' files will have any sourcemaps re-processed by// 'source-map-loader'.{enforce: "pre",test: /\.js$/,loader: "babel-loader",exclude: /node_modules/}, {test: /\.less$/,use: [{loader: "style-loader"}, {loader: "css-loader"}, {loader: "less-loader",options: {modifyVars: themeVariables}}]}, {test: /\.css$/,use: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader', publicPath: '/'})}, {test: /\.(png|jpg|jpeg|gif|svg)$/,loader: 'url-loader?limit=8192&name=[name].[ext]&publicPath='}]},// When importing a module whose path matches one of the following, just assume// a corresponding global variable exists and use that instead. This is// important because it allows us to avoid bundling all of our dependencies,// which allows browsers to cache those libraries between builds.externals: {// "react": "React",// "react-dom": "ReactDOM"},plugins: [new HtmlWebpackPlugin({template: './src/index.html',title: 'hello ts&react',inject: false,minify: {removeComments: true,collapseWhitespace: true},chunksSortMode: 'dependency'}),new ExtractTextPlugin({filename: '[name].css', allChunks: true}),new webpack.HotModuleReplacementPlugin()]
};// 此处是借鉴同事的 啊哈哈哈
const os = require('os');
console.log(`############################################################################`);
console.log(`##         os: ${os.type()} ${os.arch()} ${os.release()}`);
console.log(`##        ram: ${ (os.freemem() / 1024 / 1024 / 1024) < 1? (os.freemem() / 1024 / 1024).toFixed(0) + 'MB': (os.freemem() / 1024 / 1024 / 1024).toFixed(2) + 'GB'}`);
console.log(`##       time: ${new Date()}`);
console.log(`############################################################################`);

项目地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280043.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最小生成树Prim算法和Kruskal算法

https://www.cnblogs.com/JoshuaMK/p/prim_kruskal.html 转载于:https://www.cnblogs.com/DixinFan/p/9225105.html

如何重新打开Windows防火墙提示?

If you are setting up a new program that needs network access, but are not paying close enough attention, you might end up accidentally causing Windows firewall to block the program. How do you fix such a mistake? Today’s SuperUser Q&A post helps a f…

判断字符串出现次数最多的字符 及 次数

分析 题目的意思大致就是找出每个字符出现的次数&#xff0c;然后比较大小。那么每个字符都应该对应它出现的次数。既然是一一对应的&#xff0c;那我们就想到用对象的key和value来储存字符和其出现的次数。具体做法 新建一个空对象obj 遍历给定的字符串接下来就是最重要的 把字…

AI x 量化:华尔街老司机解密智能投资正确姿势

随着中国经济的腾飞&#xff0c;中产阶级的崛起&#xff0c;投资管理逐渐步入寻常百姓家。 值得注意的是&#xff0c;在十年前“无财可理”问题解决后&#xff0c;另一个矛盾愈发凸显——层次不齐的投资素质。据wind数据统计&#xff0c;2004年至2015年12年间&#xff0c;只有3…

如何远程调试 MAUI blazor / Blazor Hybrid

我们知道浏览器模式下 Blazor 可以使用 F12 打开开发工具,调试js查看页面元素,那当 Maui Blazor 提示烦人的 an unhandled error has occurred 该怎么进行调试呢?1. VS 运行工程于 Debug 模式下,只要 BlazorWebview 控件处于焦点,直接按F12就可以打开开发工具了. 没有焦点就鼠…

笔记本触摸键盘驱动自动禁用_如何为iPad的蓝牙键盘禁用自动更正

笔记本触摸键盘驱动自动禁用The take-for-granted features we enjoy when using an on-screen keyboard—like auto-corrections and auto-capitalization–quickly become a hindrance if you’re using a physical keyboard with your iOS device. Let’s look at how to qu…

发票的作用

目录 发票上的两个章&#xff1a;税种&#xff1a;发票的作用&#xff1a;征税方式&#xff1a;发票限额&#xff1a;参考链接发票上的两个章&#xff1a; 税务局的发票监制章商家的发票专用章税种&#xff1a; 增值税&#xff1a;商家在卖东西时为获利&#xff0c;而提高价格的…

opencv-原图基础上添加指定颜色

前言 项目中需要将某些区域使用不同的颜色表示出来&#xff0c;同时能够看到原图作为底色。 代码 #include "opencv2/highgui/highgui.hpp" #include <opencv2/imgproc.hpp> #include <iostream> using namespace cv;int main() {Mat image imread( &q…

微软发布Azure Application Insights for Node.js 1.0版本

在北美举行的Node.js交互大会上&#xff0c;微软发布了用于Node.js的Application Insights SDK。\\来自微软JavaScript平台和工具部门的高级经理Arunesh Chandra在博客上发布了这一消息&#xff0c;他说&#xff0c;微软“希望能够提升开发者在Azure上构建和运行Node.js应用程序…

正则表达式应用:实现一个简单的计算器

实现一个简单的计算器&#xff0c;代码如下&#xff1a; 下面的函数用来检验数学表达式的合规性&#xff0c;当然此处只实现两个检验&#xff1a;(1)括号应该闭合 (2)不能出现字母 def check_expression(str):check_result Trueif str.count(() ! str.count()):print(表达式有…

软考复盘:我的一些复习经验分享

大家好&#xff0c;我是Edison。最近全身乏力头疼&#xff0c;38.5度高烧&#xff0c;好在症状较轻&#xff0c;经过一天躺平加吃了芬必得&#xff08;简直神药&#xff09;后&#xff0c;退烧了&#xff0c;也不乏力了&#xff0c;也就趁娃娃睡觉时间跟大家分享一下软考的复习…

自定义注解在拦截器中为空_如何在Android中为特定联系人设置自定义铃声

自定义注解在拦截器中为空Everyone likes to know who’s calling before they actually pick up the phone, and the easiest way to achieve that is with custom ringtones for specific callers. That way, when your phone starts blasting “Cherry Pie,” you know it’…

对象的成员的初始化

变量类型&#xff1a; 1. 内置基本类型: int, char, bool, 2. 复合类型 &#xff08;compound type&#xff09;: 指针、引用、数组 3. 类类型&#xff1a; struct, class (string,vector等) 定义变量时&#xff1a; 一&#xff1a;进行“初始化”&#xff1a;可分为 ①指…

Golang面向API编程-interface(接口)

Golang面向API编程-interface&#xff08;接口&#xff09; 作者&#xff1a;尹正杰 版权声明&#xff1a;原创作品&#xff0c;谢绝转载&#xff01;否则将追究法律责任。 Golang并不是一种典型的面向对象编程&#xff08;Object Oriented Programming&#xff0c;OOP&#xf…

Linux学习_菜鸟教程_3

我是在UBANTO上运行Linux的&#xff0c;开机启动时按下shift或者Esc都不能进入到grub,没有百度到可靠的教程。 暂时先这样吧。免得我把系统搞坏了&#xff0c;先学点实用的知识~~ Next Chapter转载于:https://www.cnblogs.com/sggggr/p/9233627.html

如何使用 EF Core 7 批量删除数据

在 EF Core 7 中&#xff0c;我们可以使用批量操作来删除多条数据。这种方式与之前的版本有所不同&#xff0c;本文将对比 EFCore 7 和之前版本批量删除数据的不同方式。删除给定 ID 的数据 在 EF Core 7 中&#xff0c;我们可以使用以下代码来删除给定 ID 的数据&#xff1a;a…

笔记本禁用键盘命令符_如何在Windows中禁用命令提示符和“运行”程序

笔记本禁用键盘命令符The Command Prompt and the Run program are pretty powerful tools in the Windows world. If you’d rather specific users on a computer not have access to them, it’s not too hard to do. 命令提示符和运行程序是Windows世界中非常强大的工具。 …

MySQL Date 函数

2019独角兽企业重金招聘Python工程师标准>>> MySQL 中最重要的内建日期函数&#xff1a; NOW() 返回当前的日期和时间 CURDATE() 返回当前的日期 CURTIME() 返回当前的时间 DATE() 提取日期或日期/时间表达式的日期部分 EXTRACT() 返回日期/时间按的…

Android之Window与WindowManager

Window表示一个窗口的概念&#xff0c;在日常开发中直接接触Window的机会并不多&#xff0c;但却会经常用到Window&#xff0c;activity、toast、dialog、PopupWindow、状态栏等都是Window。在Android中Window是个抽象类&#xff0c;并且仅有一个实现类PhoneWindow。 1、Window…

C# WPF This用法详解(经典)

概述this在C#中有多种用法&#xff0c;也比较常见&#xff0c;这节主要针对它常用的四种用法展开讲解.用法1:构造函数串联执行;用法2:通过this区分传参和类中全局的定义;用法3:方法扩展类;用法4:将对象作为参数传递;代码实例using System.Text;namespace Caliburn.Micro.Hello.…