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.pswp.cn/news/280043.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280043.shtml
英文地址,請注明出處:http://en.pswp.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.…