写给前端新人:从 0到1 搭建一个前端项目,都需要做什么?

module.exports = override(

addLessLoader({

lessOptions: {

javascriptEnabled: true,

modifyVars: {

‘@primary-color’: ‘#1890ff’,

},

}

}),

)

  1. 别名配置(typescript 项目这里有坑)

// config-overrides.js

const path = require(‘path’)

module.exports = override(

addWebpackAlias({

‘@’: path.resolve(__dirname, ‘src’),

}),

)

  1. 去除注释、多进程打包压缩

// config-overrides.js

const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’)

const HardSourceWebpackPlugin = require(‘hard-source-webpack-plugin’)

module.exports = override(/* … */, config => {

config.plugins = […config.plugins, {

new UglifyJsPlugin({

uglifyOptions: {

warnings: false,

compress: {

drop_debugger: true,

drop_console: true,

},

},

}),

new HardSourceWebpackPlugin()

}]

return config

})

  1. 解决埋下的两个坑
  • 修改打包出的文件夹名为 dist

// 修改打包路径除了output,这里也要修改

const paths = require(‘react-scripts/config/paths’)

paths.appBuild = path.join(path.dirname(paths.appBuild), ‘dist’)

module.exports = override(/* … */, config => {

config.output.path = path.resolve(__dirname, ‘dist’)

return config

})

  • 解决 typescript 别名配置

    • 查阅相关资料,需要在 tsconfig.json 中添加一项配置

{

“extends”: “./paths.json”

}

  • 新建文件 paths.json

{

“compilerOptions”: {

“baseUrl”: “src”,

“paths”: {

“@/“: [””]

}

}

}

  1. 配置装饰器写法

{

“compilerOptions”: {

“experimentalDecorators”: true,

}

}

  1. 配置开发代理
  • 在 src 目录新建 setupProxy.js

// src/setupProxy.js

const proxy = require(‘http-proxy-middleware’).createProxyMiddleware

module.exports = function(app) {

// app 为 Express 实例,此处可以写 Mock 数据

app.use(

proxy(‘/api’,

{

“target”: “https://qpj-test.fapiaoer.cn”,

“changeOrigin”: true,

“secure”: false,

// “pathRewrite”: {

//   “^/api”: “”

// }

})

)

}

  1. 加入 polyfill 和 antd 组件国际化处理

// src/index.tsx

import React from ‘react’

import ReactDOM from ‘react-dom’

// 注入 store

import { Provider } from ‘react-redux’

import store from ‘@/store/store’

import { ConfigProvider, Empty } from ‘antd’

import App from ‘./App’

import zhCN from ‘antd/es/locale/zh_CN’

import ‘moment/locale/zh-cn’

// polyfill

import ‘core-js/stable’

import ‘regenerator-runtime/runtime’

ReactDOM.render(

,

document.getElementById(‘root’)

)

  1. CSS Modules

create-react-app 自带支持以 xxx.module.(c|le|sa)ss 的样式表文件,使用上 typescript 项目中要注意:

const styles = require(‘./index.module.less’)

retrun (

columns={columns}

className={${styles['border-setting']}}

dataSource={props.store.check.items}

rowKey={record => record.id}

pagination={false}

/>

)

// index.module.less

.container {

padding: 24px;

background-color: #fff;

height: 100%;

overflow: auto;

.border-setting {

tr {

td:nth-child(3) {

border-left: 1px solid #F0F0F0;

border-right: 1px solid #F0F0F0;

}

}

td {

text-align: left !important;

}

}

:global { // 这个标识之后,其子代元素可以不需要使用 styles['type-check-box'] 的方式,直接写 className

.type-check-box {

.ant-checkbox-wrapper + .ant-checkbox-wrapper{

margin-left: 0;

}

}

}

}

  1. 【新】配置 React jsx 指令式属性 r-ifr-forr-modelr-show,提升开发效率:
  • 安装依赖

$ yarn add babel-react-rif babel-react-rfor babel-react-rmodel babel-react-rshow -D

  • 配置 .babelrc :

// .babelrc

{

…,

“plugins”: [

“babel-react-rif”,

“babel-react-rfor”,

“babel-react-rmodel”,

“babel-react-rshow”,

]

}

  • 使用示例:

  • r-if

 180}>best

other

  • r-for

{/* eslint-disable-next-line no-undef */}

内容 {item + ‘-’ + index}

  • r-model
  • r-show
内容
 # 注意:这是 `r-if` 的效果,不会渲染节点

四、项目配置二(优化配置)


  1. 实现组件懒加载 react-loadable

import Loadable from ‘react-loadable’

const Loading = (props: any) => {

if (props.error) {

console.error(props.error)

return 

Error! Retry

} else if (props.timedOut) {

return 

Timeout! Retry

} else if (props.pastDelay) {

return 

Loading…

} else {

return null

}

}

const loadable = (path: any) => {

return Loadable({

loader: () => import(@/pages${path}),

loading: Loading,

delay: 200,

timeout: 10000,

})

}

const Home = loadable(‘/homePage/Home’)

  1. 处理 axios 拦截响应

const service = axios.create({

baseURL: ‘/’,

timeout: 15000,

})

service.interceptors.request.use(function (config) {

return config

})

service.interceptors.response.use(function (config) {

return config

})

  1. 处理 React router 的嵌套配置

我们知道 React 中不支持类似 Vue Router 路由配置方式,React 中一切皆组件,路由也是组件,需要用到路由要临时加上路由组件,写起来就很繁琐,但我们可以自己实现路由配置表方式。

// router/router.config.ts

const routes = [

{

path: ‘/home’,

component: loadable(‘components/Index’),

exact: true,

},

{

path: ‘/new’,

component: loadable(‘components/New’),

redirect: ‘/new/list’,

// exact: true,

routes: [

{

path: ‘/new/list’,

component: loadable(‘components/NewList’),

exact: true,

},

{

path: ‘/new/content’,

component: loadable(‘components/NewContent’),

exact: true,

},

],

},

]

export default routes

// router/router.ts

import React from ‘react’

import { Switch, BrowserRouter as Router, Route } from ‘react-router-dom’

import routes from ‘./index’

function mapRoutes(routes: any[], store: object): any {

return routes.map((item: any, index: number) => {

return (

<Route exact={item.exact || false} path={item.path} key={index} render={props => {

const NewComp = item.component

Object.assign(props, {

redirect: item.redirect || null,

permission: item.permission || [],

…store

})

if (item.routes) {

return <NewComp {…props}>{ mapRoutes(item.routes, store) }

} else {

return <NewComp {…props} />

}

}} />

)

})

}

const Routes = (props: any) => {

return (

{ mapRoutes(routes, props.store) }

<Route component={() => (

404 Page not Found!
)} />

)

}

export default Routes

子路由承载页面需要加上如下代码:

import { Redirect, Route, Switch } from ‘react-router-dom’

{props.children}

<Route component={() => (

404 Page not Found!
)} />

{props.redirect && }

  1. 处理 React store

// store/store.ts

import { createStore, applyMiddleware } from ‘redux’

import thunk from ‘redux-thunk’

import logger from ‘redux-logger’

import reducers from ‘./reducer’

const store = process.env.NODE_ENV === ‘development’

? createStore(reducers, applyMiddleware(thunk, logger))

: createStore(reducers, applyMiddleware(thunk))

export default store

为了方便使用,避免每个组件都需要 connect ,这边实现了 redux store 的全局注入,但是如果项目庞大的话就会损耗些性能。

// App.tsx

import { dispatchActions } from ‘@/store/reducer’

export default connect((state: any) => ({ store: state }), dispatchActions)(App)

五、总结


自此项目搭建就全部完成了,剩下的就是业务代码了。相信你可以得到如下收获:

① 项目构建在宏观上有个极大的能力提升;

② 项目整体功能了解清晰;

③ 排查问题不慌乱;

④ 封装能力有加强;

⑤ 业务功能很清楚。

六、题外话


基于 create-react-app 创建的 React 项目,本人实现了一个脚手架,以上配置默认已经全部加入实现,欢迎 Github 试用并 star 。链接:https://github.com/zhuyuanmin/zym-cli

关于本文

作者:前端小猿_zym

============

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端校招精编面试解析大全点击这里获取完整版pdf查看

⑤ 业务功能很清楚。

六、题外话


基于 create-react-app 创建的 React 项目,本人实现了一个脚手架,以上配置默认已经全部加入实现,欢迎 Github 试用并 star 。链接:https://github.com/zhuyuanmin/zym-cli

关于本文

作者:前端小猿_zym

============

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-wKDNWdhV-1712625122733)]

[外链图片转存中…(img-Km06ERkZ-1712625122734)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-pR6CJlAQ-1712625122734)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端校招精编面试解析大全点击这里获取完整版pdf查看

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值