构建一个通用的 react 项目架构模板
components
公共组件pages
逻辑页面,一般为路由页面utils
工具函数库store
状态管理库router.js
页面路由
axios
,qs
模块. http 请求库node-sass
,sass-loader
.sass
支持.babel-plugin-react-css-modules
: 用于更简便的css-modules
书写方案.此插件要安装到开发模式.postcss-scss
: 使react-css-modules
识别scss
.sass-resources-loader
: 使用scss
全局资源(样式和公共变量).babel-plugin-transform-decorators-legacy
:es-next
装饰器支持.- 安装
babel-preset-x
.主要是新的 es7 语法支持.yarn add babel-preset-env babel-preset-react babel-preset-es2015 babel-preset-stage-0 -D
yarn eject
这里有两个部分需要修改. 第一个是对.js
文件的处理,让jsx
中的引用到css-modules
的元素获得处理过(hash)的className
. 第二个是对.scss
文件的处理, 将所有的.scss
文件进行重编译并添加的到 html 文档的head
里面.
1.在/config/webpack.config.dev.js
中, 找到module.exports.module.rules.oneOf
, 再找到test: /\.(js|jsx|mjs)$/
所在的对象.在options
选项中添加相应的plugins
:
plugins: [
[
'react-css-modules',
{
// 类名hash规则
generateScopedName: '[local]-[hash:base64:10]',
filetypes: {
// 对 .scss 文件进行支持
'.scss': { syntax: 'postcss-scss' }
},
// 属性映射名称,在jsx中使用到
attributeNames: { classes: 'className', activeClass: 'activeClassName' }
}
]
]
2.直接暴力修改原来的test: /\.css$/
为test: /\.scss$/
. 然后在css-loader
的options
中添加两个属性:
options: {
// 开启css-modules
modules: true,
importLoaders: 1,
// 类名hash规则
localIdentName: '[local]-[hash:base64:10]'
}
这里要注意. 上述两个部分的'类名 hash 规则'必须一致. 否则编译后不会提示报错,但是没有效果.
只需要在刚才的test: /\.scss$/
中,添加两个 loader 即可:
{
require.resolve('sass-loader'),
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/assets/global-styles.scss')
}
}
}
这里的__dirname
指的是代码所在的当前文件,即webpack.config.dev.js
这个文件.后面的路径既是基于当前路径的相对路径.
在组件中只需直接引入.scss
文件,其实同时可以引入多个,但我偏不.
import './styles.scss'
然后在jsx
中添加classes
属性. classes
这个属性的名称是可以定制的.属性的值是字符串. 写法和传统的 css 类名一样.
<div classes="the-text">something</div>
yarn add mobx mobx-react
yarn add babel-plugin-transform-decorators-legacy -D //装饰器插件
添加preset
和plugin
,还是刚刚的那个test: /\.(js|jsx|mjs)$/
,在options
里面添加:
options: {
presets: ['env', 'react', 'es2015', 'stage-0'],
plugins: [
'transform-decorators-legacy',
]
}
这里要注意,在
plugins
中有多个插件时,transform-decorators-legacy
必须放在第一个,否则没有效果.
mobx 自身没有规范关于 store 的写法,虽然有一些推荐写法,但还是不全.鄙人自己写一个.
在utils
文件夹中新建mobx-store.js
.在其中定义 store 的写法.
在store
文件夹中定义每个子模块时继承StoreModule
这个类即可.关于store
部分的写法,请听鄙人娓娓道来.
- 根级 store 怎么写
- 各个子 store 模块怎么写
- 如果把 store 注入到项目
- 组件中如何引用(过滤)
主要是为了更方便地引用资源.在webpack.config.dev.js
中,找到alias
:
{
'@': path.resolve(__dirname, './src')
}
使用别名后, vscode 会无法跟踪文件. 在项目根目录添加jsconfig.json
文件来解决这个问题:
// /jsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
},
// 允许使用装饰器@
"experimentalDecorators": true
}
}
默认打包的时候, 在编译出来的index.html
里面, 所有引用的路径都是以/
开头的. 这会导致无法直接运行打包好的项目. 其实只要将/
改为./
即可. 但是手动改毕竟不方便, 可以在配置中修改:
找到/config/paths.js
中的这行代码
const servedUrl = envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/')
然后将/
改为./
就可以了.
axios 是目前基于XMLHttpRequest
封装的比较健全和稳定的库. fetch
还很新,相应的库还不是很健全.但未来必定成为主要技术.
安装依赖:
yarn add axios -D //主文件
yarn add qs -D //这是一个模块,帮助axios把参数转换为后端可以识别的数据格式
添加鄙人写的 axios api 的工具文件. 放在/src/utils/aixos.js
使用的时候,引用get
,post
,all
这些方法即可,参数怎么写,看官网.
项目打包时, 默认将所有组件打包成一个 js 文件. 如果项目比较打的时候, 首次加载 js 时会因文件过大, 导致加载很慢.
最好的方案是: 将使用的组件分类成不同的模块, 每个模块在应用使用时再加载, 做到按需加载的目的.
每个模块基本按照路由来划分, 公共组件也单独分成一类.
使用到的插件: react-loadable
, 这个插件可以让组件通过异步加载. 使用到的知识点: webpack chunk
. 这个知识点参考自 vue-router 路由懒加载
首先安装插件
yarn add react-loadable
在引入组件时, 不直接使用这种方法引入:
import MyComp from './MyComp'
而是这样引入
import Loadable from 'react-loadable'
const MyComp = Loadable({
loader: () = > import('./MyComp'),
loading: () = > <div>Loading...</div>
})
如果有多个组件需要按需加载, 将这些组件打包到同一个 js 文件中. 这样需要定义一个包分组名称, 然后将组件打包到这个分组中.
const MyComp = Loadable({
loader: () = > import(/* webpackChunkName: "my-component-group" */ './MyComp'),
loading: () = > <div>Loading...</div>
})
const MyCompTwo = Loadable({
loader: () = > import(/* webpackChunkName: "my-component-group" */ './MyCompTwo'),
loading: () = > <div>Loading...</div>
})
这样, MyComp
和MyCompTwo
这两个组件就会被统一打包到名为my-component-group
的 js 中.
vscode
编辑器会在用户输入相应的模块名,包名,方法名,变量名时,会自动导入相同名称的资源. 但是很多时候这个功能会有错误, 所以建议不要使用这个功能.
编辑器设置:
// 禁用自动导入
"typescript.autoImportSuggestions.enabled": false
只需在/config/webpack.config.prod.js
找到new webpack.optimize.UglifyJsPlugin
后,修改:
compress: {
warnings: false,
comparisons: false,
drop_console: false, //禁用 console
drop_debugger: false //禁用 debugger
},
// /config/webpack.config.prod.js
const shouldUseSourceMap = false
以上就是目前 react 项目模板的一些内容.
关于webpack
的配置是在开发模式下的,生产模式要另外配置,也就是 CtrlC+CtrlV 的事情.
git clone https://gitee.com/darcrandex/react-project-template.git your-project-name
cd your-project-name
npm install
npm start