typescript+react+antd基础环境搭建

小编 2026-06-17 阅读:470 评论:0
typescript+react+antd基础环境搭建(包含样式定制) tsconfig.json 配置 // 具体配置可以看上面的链接 这里module moduleResolutio...

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


// 具体配置可以看上面的链接 这里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(`############################################################################`);

项目地址

来源:https://segmentfault.com/a/1190000011721098

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表