目前网络上关于react和antd的教程有很多,在构建项目阶段大多用create-react-app,dva等脚手架工具进行搭建,使用工具固然方便,却总感觉没能真正完全掌握这门技术,于是自己尝试从头搭建了一个项目

1.环境

    本机使用v8.9.4版本的node,开发工具为Visual Studio Code

2.初始化项目

在项目目录下执行命令 npm init 初始化项目,在生成的 package.json 文件中添加以下依赖并执行 npm install 
"dependencies": { "antd": "^3.10.1" }, "devDependencies": { "babel-core":
"^6.26.3", "babel-loader": "^7.1.2", "babel-plugin-import": "^1.9.1",
"babel-plugin-transform-class-properties": "^6.24.1", "babel-preset-es2015":
"^6.24.1", "babel-preset-react": "^6.24.1", "css-loader": "^1.0.0", "eslint":
"^5.7.0", "eslint-loader": "^2.1.1", "eslint-plugin-react": "^7.11.1",
"html-webpack-plugin": "^3.2.0", "react": "^16.5.2", "react-dev-utils":
"^6.0.5", "react-dom": "^16.5.2", "react-router-dom": "^4.3.1", "style-loader":
"^0.23.1", "url-loader": "^1.1.2", "webpack": "^4.20.2", "webpack-cli":
"^3.1.2", "webpack-dev-server": "^3.1.9" }
    当然也可以使用npm install手动单独下载对应依赖,但有些依赖必须指定版本,否则会有冲突。在项目目录下创建如下文件夹



src用于放置react组件,public用于放置静态文件,dist放置编译目标文件,config用于放置配置文件

3.配置webpack

在config中创建webpack配置文件,任意命名,我这里命名为webpack.config.js。创建用于控制路径的配置文件,我这里命名为paths.js
'use strict'; const path = require('path'); const fs = require('fs'); const
appDirectory = fs.realpathSync(process.cwd()); const resolveAppPath =
relativePath => path.resolve(appDirectory, relativePath); module.exports = {
mainJs:resolveAppPath('src/main.js'), html:resolveAppPath('public/index.html'),
buildPath:resolveAppPath('dist'), };
paths.js文件用于配置在编译时可能用到的一些路径,并将其转化为绝对路径,这里导入了三个路径

1.mainJs:入口文件,可以理解为我们的静态页面在未编译时所引入的唯一js文件,这也是react官方推荐的模式

2.html:静态页面路径

3.biildPath:编译完成后的文件应该放置的目录
const path = require('path'); const paths = require('./paths'); const
HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry:
paths.mainJs, output: { filename: 'bundle-[hash].js', path: paths.buildPath },
module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: {
loader: "babel-loader" } },{ test: /\.css$/, use: ['style-loader',
'css-loader'] },{ test: /\.(png|jpg|jpeg|gif)$/, use: 'url-loader' }, ] },
plugins: [ new HtmlWebpackPlugin({ template: paths.html, inject: true }) ] };
entry选项用于指定入口文件,,可以理解为我们的静态页面在未编译时所引入的唯一js文件


output选项用于指定编译结果,filename设置编译完成的文件名称,使用[hash]将编译完成的js文件加上哈希码,防止浏览器缓存,path指定js文件放置目录


需要注意的是除了使用babel-loader对js文件的语法进行转换之外,还要用style-loader和css-loader对css文件进行转换,否则在使用antd的样式时会报错,使用HtmlWebpackPlugin在编译时往html文件中插入编译后的js文件

对于babel的配置主要有两种方式,一种是在项目根目录下创建.babelrc文件
{ "presets": [ "es2015", "react" ], "plugins":
["transform-class-properties",["import", { "libraryName": "antd",
"libraryDirectory": "es", "style": "css" }]] }
加入transform-class-properties插件可以使用属性初始化器语法,不用在构造函数中定义属性,同时配置
babel-plugin-import,实现antd的按需引入

4.测试

在src目录下新建page目录,创建index.js文件,编写一个测试组件,这里用antd官方文档上的演示代码
import React from 'react'; import { Menu, Icon, Switch } from 'antd'; const {
SubMenu } = Menu; class Sider extends React.Component { state = { mode:
'inline', theme: 'light', } changeMode = (value) => { this.setState({ mode:
value ? 'vertical' : 'inline', }); } changeTheme = (value) => { this.setState({
theme: value ? 'dark' : 'light', }); } render() { return ( <div> <Switch
onChange={this.changeMode} /> Change Mode <span className="ant-divider"
style={{ margin: '0 1em' }} /> <Switch onChange={this.changeTheme} /> Change
Theme <br /> <br /> <Menu style={{ width: 256 }} defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']} mode={this.state.mode} theme={this.state.theme} >
<Menu.Item key="1"> <Icon type="mail" /> Navigation One </Menu.Item> <Menu.Item
key="2"> <Icon type="calendar" /> Navigation Two </Menu.Item> <SubMenu
key="sub1" title={<span><Icon type="appstore" /><span>Navigation
Three</span></span>}> <Menu.Item key="3">Option 3</Menu.Item> <Menu.Item
key="4">Option 4</Menu.Item> <SubMenu key="sub1-2" title="Submenu"> <Menu.Item
key="5">Option 5</Menu.Item> <Menu.Item key="6">Option 6</Menu.Item> </SubMenu>
</SubMenu> <SubMenu key="sub2" title={<span><Icon type="setting"
/><span>Navigation Four</span></span>}> <Menu.Item key="7">Option 7</Menu.Item>
<Menu.Item key="8">Option 8</Menu.Item> <Menu.Item key="9">Option 9</Menu.Item>
<Menu.Item key="10">Option 10</Menu.Item> </SubMenu> </Menu> </div> ); } }
export default Sider;
创建router文件夹,在其中创建router.js文件,编写路由
import React from 'react'; import {HashRouter,Route,Switch,Link} from
'react-router-dom' import Sider from '../page/index' export default class
AppRouter extends React.Component { constructor(props) { super(props); }
render() { return ( <HashRouter> <div id="wrapper"> <Route path="/"
component={Sider}/> </div> </HashRouter> ) } }
在入口文件main.js中引入
import React, { Component } from 'react'; import { render } from 'react-dom';
import AppRouter from './router/router' render( <AppRouter/>,
document.getElementById('root') );
命令行执行webpack --config
./config/webpack.config.js(在package.json文件中配置 "build":"webpack --config
./config/webpack.config.js" 可直接使用npm run build)
,在dist目录下会出现编译后的html文件和js文件,直接在浏览器打开,结果如下



完成项目搭建