предисловие
Прошло много времени с последней статьи.В последние две недели компания была отправлена в BOE в командировку, чтобы отвечать за предварительную работу устоявшейся проектной команды. За это время я построил front-end проект с нуля, в этот раз уделял больше времени и больше думал. В прошлом были интерфейсные проекты, но времени было относительно мало, поэтому многие проблемы были проигнорированы. На этот раз мы просто оптимизировали предыдущую и подытожили некоторые впечатления, чтобы поделиться с вами. Если у вас есть лучшие идеи, пожалуйста, оставьте сообщение для обмена.
Советы:
-
Этот проект основан на перспективах проекта интерфейса ПК, и проект мобильного интерфейса не полностью применим. Вы, ребята, должны обратить на это внимание.
-
Проект велся в разных направлениях, и соответствующее направление каждой ветки можно найти вCONTRIBUTING.mdПосмотреть в
инструкция проекта
адрес проекта: https://github.com/ruichengping/react-webpack-pc
Проект можно собрать с помощью написанного мной инструмента asuna-cli.Адрес инструмента, написанного мной, следующий:
https://github.com/ruichengping/asuna-cli
Выше приведена структура каталогов примера проекта, мы проанализируем ее по порядку ниже**
build
Этот файл в основном содержит некоторые связанные файлы, упакованные с помощью webpack.
- build.js---- сценарий упаковки веб-пакета, используемый для сборки пакета рабочей среды
- check-versions.js---- В основном определяет, соответствует ли версия узла и npm текущей среды упаковки требованиям.
- utils.js---- Некоторые библиотеки инструментов, необходимые для упаковки веб-пакетов
- webpack.base.conf.js---- Некоторые базовые конфигурации webpack, конфигурации webpack различных сред основаны на этом
- webpack.dev.conf.js---- конфигурация веб-пакета для среды разработки
- webpack.prod.conf.js---- конфигурация веб-пакета для производственной среды
Я изменил конфигурацию веб-пакета этого проекта в проекте vue-cli, который можно использовать для создания проекта React. В настоящее время существует только две среды: среда разработки и производственная среда.Некоторые компании могут иметь несколько сред, и конфигурация веб-пакета в каждой среде отличается.В настоящее время формат имени файла может быть создан в соответствии с различными средами. .webpack..conf.js'' конфигурация веб-пакета для использования.webpack.base.conf.jsЕсть несколько основных конфигураций, таких какrules,input,outputконфигурации, вообще говоря, они примерно одинаковы в каждой среде, и можно использовать некоторые различияwebpack-mergeПлагины объединены. Вообще говоря, для большинства проектов достаточно двух конфигураций веб-пакета для среды разработки и рабочей среды.
config
Здесь хранятся параметры конфигурации, необходимые веб-пакету в различных средах.
- dev.env.js---- Предоставить переменные среды в среде разработки для внешнего мираNODE_ENV
- index.js---- Сохраняет параметры конфигурации для различных сред
- prod.env.js---- Предоставить переменные среды в производственной среде снаружиNODE_ENV
Если вам нужно добавить другую среду, вы можете создать файл с именем «.env.js» и открыть переменные среды для внешнего мира.NODE_ENV, а затем импортируйте его в index.js, чтобы задать соответствующие параметры.
mock
Это для издевательства над интерфейсом, который может не использоваться многими компаниями, а я редко хожу на издевательство на работе. Вот введение в мои собственные идеи насмешек над интерфейсом, здесь я выбираюmockjsплюсjson-serverКомбинация. Для конкретного использования этих двух вы можете проверить их официальные документы.
- api---- Храните данные, соответствующие различным API
- index.js---- Основной файл json-сервера
- routes.json---- отображение маршрутизации
package.json я настраиваю скрипт следующим образом:
"mock": "json-server mock/index.js --port 3000 --routes mock/routes.json"
Консоль выполняет «npm run mock».
src
api
url.js
export default {
fetchUserInfo:{
method:'get',
url:'/api/user'
},
fetchAuthorInfo:{
method:'get',
url:'/api/author'
},
fetchUserList:{
method:'get',
url:'/api/userList'
}
}
index.js
import _ from 'lodash'
import http from '@/utils/http'
import API_URL from './url';
function mapUrlObjToFuncObj(urlObj){
const API = {};
_.keys(urlObj).forEach((key)=>{
const item = urlObj[key]
API[key]=function(params){
return http[item.method](item.url,params)
}
});
return API;
}
function mapUrlObjToStrObj(urlObj){
const Url = {};
_.keys(urlObj).forEach((key)=>{
const item = urlObj[key]
Url[key]=item.url
});
return Url;
}
export const API = mapUrlObjToFuncObj(API_URL);
export const URL = mapUrlObjToStrObj(API_URL);
Здесь мы используем для размещения адреса интерфейса апи, для последующего обслуживания интерфейса мы не будем напрямую прописывать мертвый адрес интерфейса в процессе использования, а инкапсулируем запрос интерфейса в один метод. За счет унифицированного обслуживания интерфейса мы можем добиться того, что при выполнении таких операций, как изменение адреса интерфейса, изменение метода запроса, добавление интерфейса и т. д., нет необходимости искать повсюду во всем проекте, пока поддерживается внешний объект url.js. Способ применения следующий:
import {API} from '@/api'
//params为请求参数
API.fetchUserInfo(params).then(response=>{
//response为返回值
...
})
assets
Здесь мы поместим ресурсы изображений, необходимые для проекта.Эти ресурсы изображений обычно используются в качестве значков и относительно невелики. webpack преобразует его вBASE64использовать. Если вы не хотите использовать его таким образом, вы можете хранить ресурсы изображения в статическом каталоге.
components
Здесь хранятся общедоступные компоненты, используемые всем проектом. Чтобы определить компонент, требуется создать новую папку, имя папки — это имя компонента, а в этой папке создаются файлы index.jsx и style.scss. Например, чтобы сделать компонент HelloWorld, он должен иметь следующую структуру.
HelloWorld
- index.jsx
- style.scss //Сохраняем стиль компонента
index.js
import React from 'react';
import './style.scss';
class HelloWorld extends React.PureComponent{
render(){
return (
<h4 className="u-text">Hello World</h4>
)
}
}
export default HelloWorld;
style.scss
.u-text{
color: red;
}
layouts
这里存放着布局文件。关于这个布局文件我是这么去定义它的,我在开发过程中有一些页面他们的某一部分都是相同,早之前可能大家可能会在一个React组件加和去实现这个功能,可以这么干,没毛病。但是这个有一个不好点就是你的路由没法做统一的管理,分散在各个组件中,给后续的维护带来很多问题。为了解决这个,我选择利用props.children结合标签嵌套的方式去完成。 Например:
Сначала установите макет (это тоже компонент React) BasicLayout.jsx
import React from 'react';
class BasicLayout extends React.PureComponent{
render(){
const {children} = this.props;
return (
<div>
<div>隔壁老王今日行程:</div>
<div>{children}</div>
</div>
)
}
}
export default BasicLayout;
После определения мы можем использовать его следующим образом:
import React from 'react';
import BasicLayout from '<BasicLayout的路径>'
class Work extends React.PureComponent{
render(){
return (
<BasicLayout>
<div>今天隔壁老王比较累,不工作!</div>
<BasicLayout>
)
}
}
export default BasicLayout;
Окончательная структура DOM выглядит следующим образом:
<div>
<div>隔壁老王今日行程:</div>
<div>
<div>今天隔壁老王比较累,不工作!</div>
</div>
</div>
Таким образом, мы можем создать множество страниц, подобных приведенным ниже, на основе BasicLayout.
<div>
<div>隔壁老王今日行程:</div>
<div>
//<不同的内容>
</div>
</div>
Используя этот метод, мы можем написать все наши маршруты вместе. Некоторые люди могут подумать, что каждый раз писать и импортировать BasicLayout очень хлопотно. Есть ли другой лучший способ? Я расскажу об этом здесь, когда буду говорить о App.jsx. Пропустить первым.
pages
Компоненты, хранящиеся здесь, являются компонентами уровня страницы, а маршруты, соответствующие react-router, должны соответствовать друг другу. Каждая страница — это папка, имя файла — это имя страницы, и каждая страница должна содержать следующие файлы:
- компоненты ---- хранят некоторые компоненты, уникальные для текущей страницы
- redux ---- хранить три файлаactions.js,actionTypes.js,reducer.js, эти файлы должны относиться только к этой странице
- index.jsx ---- файл входа на страницу
- style.scss -- стиль, требуемый страницей Конкретный код можно просмотреть самостоятельно в проекте клонирования git, и он не будет опубликован здесь.
scss
Здесь хранятся общие файлы scss, и сравниваются некоторые часто используемые функциональные классы, @mixin, @function и т. д.
store
Здесь четыре файла:
- actions.js
- actionTypes.js
- reducer.js
- index.js
Мы знаем, что у каждой страницы есть свойactions.js,actionTypes.js,reducer.js, но это глобально, и index.js выставит хранилище наружу, а затем введет его в main.js.
import {createStore,combineReducers,applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import API from '@/api';
import user from './reducer';
import author from '@/pages/PageOne/redux/reducer';
const rootReducer = combineReducers({
user,
author
});
const store=createStore(
rootReducer,
applyMiddleware(thunk.withExtraArgument({
API
}))
)
export default store;
Вот небольшая деталь, redux-thunk может нести какие-то дополнительные объекты или методы, здесь я несу объект API. Когда нам нужно использовать объекты API в action.js, нам не нужно их импортировать. Давайте проведем сравнение:
перед фиксацией
import * as actionTypes from './actionTypes';
import API from '../api';
export const fecthUserName=(params)=> async (dispatch,getState)=>{
const response =await API.fetchUserInfo(params);
const {success,data} = response;
if(success){
dispatch({
type:actionTypes.CHANGE_USER_NAME,
payload:data
});
}
}
после модификации
import * as actionTypes from './actionTypes';
export const fecthUserName=(params)=> async (dispatch,getState,{API})=>{
const response =await API.fetchUserInfo(params);
const {success,data} = response;
if(success){
dispatch({
type:actionTypes.CHANGE_USER_NAME,
payload:data
});
}
}
utils
Здесь будут храниться некоторые из моих собственных инкапсулированных файлов инструментов js.Например, я инкапсулировал в проект http.js на основе axios, что упрощает работу с axios.
router/index.js
Здесь он настроен на предотвращение регистрации маршрутов и отображение меток маршрутов в app.js.
import Loadable from 'react-loadable';
import createHistory from 'history/createBrowserHistory';
import BasicLayout from '@/layouts/BasicLayout';
import NavTwoLayout from '@/layouts/NavTwoLayout';
import Loading from '@/components/Loading';
import NotFound from '@/pages/Exception/404';
const Home = Loadable({loader: () => import('@/pages/Home'),loading: Loading});
const Teachers = Loadable({loader: () => import('@/pages/Teachers'),loading: Loading});
export const history = createHistory();
export const routes = [
{
path:'/',
redirect:'/navone/home'
},
{
path:'/navone',
redirect:'/navone/home',
children:[{
path:'/home',
layout:BasicLayout,
component:Home
}]
},
{
path:'/navtwo',
redirect:'/navtwo/teachers',
children:[{
path:'/teachers',
layout:NavTwoLayout,
component:Teachers
}]
},
{
path:'*',
component:NotFound
}
]
App.js
Здесь используется для отображения метки маршрутизации в соответствии с конфигурацией маршрутизации, сначала поместите код:
import React from 'react';
import {Router} from 'react-router-dom';
import {Switch, Route ,Redirect} from 'react-router';
import {history,routes} from '@/router';
function getRouterByRoutes(routes){
const renderedRoutesList = [];
const renderRoutes = (routes,parentPath)=>{
Array.isArray(routes)&&routes.forEach((route)=>{
const {path,redirect,children,layout,component} = route;
if(redirect){
renderedRoutesList.push(<Redirect key={`${parentPath}${path}`} exact from={path} to={`${parentPath}${redirect}`}/>)
}
if(component){
renderedRoutesList.push(
layout?<Route
key={`${parentPath}${path}`}
exact path={`${parentPath}${path}`}
render={(props)=>React.createElement(layout,props,React.createElement(component,props))} />:
<Route
key={`${parentPath}${path}`}
exact
path={`${parentPath}${path}`}
component={component}/>)
}
if(Array.isArray(children)&&children.length>0){
renderRoutes(children,path)
}
});
}
renderRoutes(routes,'')
return renderedRoutesList;
}
class App extends React.PureComponent{
render(){
return (
<Router history={history}>
<Switch>
{getRouterByRoutes(routes)}
</Switch>
</Router>
)
}
}
export default App;
Здесь нам нужно сосредоточиться на содержимом, которое мы пропускаем в макете. Можем ли мы каждый раз оборачивать код компонентом макета? Ответ — да. Здесь я выбираю свойство рендеринга в.
main.js
Файл записи веб-пакета в основном импортирует некоторые глобальные js или scss и выполняет метод рендеринга под реактивным домом.Код выглядит следующим образом:
import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import store from '@/store';
import App from '@/App';
import '@/scss/reset.scss';
import '@/scss/base.scss';
render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('app')
)
static
Это статический каталог ресурсов, обычно хранящий некоторые сторонние библиотеки инструментов. Этот каталог в основном рассматривает два аспекта:
- Некоторые сторонние библиотеки инструментов не имеют пакетов npm, и мы не можем добавить их с помощью npm install или yarn add.
- Некоторые относительно большие сторонние библиотеки инструментов повлияют на нашу скорость упаковки, мы можем взять их и импортировать через скрипт.
На самом деле лучший способ для сторонней библиотеки инструментов — это CDN, но у некоторых компаний ее просто нет, поэтому они могут сделать только это. Добавленная вами третья библиотека инструментов доступна на текущем сервере"/static/*", который нужно получить по пути.
templates
Файлы шаблонов, необходимые для построения на уровне страницы и компонента, хранятся здесь.Создание на уровне страницы предоставляет два шаблона: PageReducer (интегрированный редуктор) и PageSample (редуктор не интегрирован), в то время как компоненты предоставляют только один шаблон, ComSample. Конструкцию на уровне страниц и компонентов необходимо создавать с помощью asuna-cli.В настоящее время проект интегрирован с asuna-cli. package.json написал два скрипта: npm run newPage (сборка страницы) и npm run newComponent (сборка компонента). Разработка может выбрать сборку в соответствии с фактическими потребностями, конкретное использование asuna-cli может пойти наhttps://github.com/ruichengping/asuna-cliПроверить.
Другие файлы
- .babelrc ---- файл конфигурации для преобразования Babel
- .gitignore ---- файлы, которые необходимо игнорировать для операций git
- .postcssrc.js ---- файл конфигурации postcss
- index.html ---- шаблон index.html, веб-пакет сгенерирует новый index.html на основе этого, сотрудничайте сhtml-webpack-pluginиспользовать
- package.json — имя нарицательное
- Readme.md ---- Описание предмета
- theme.js ---- файл конфигурации цвета темы ant-design, пожалуйста, обратитесь к ant-design для конкретного использования
- asuna.config.js ---- файл конфигурации asuna-cli
- yarn.lock ---- заблокировать версию пакета
Эпилог
Это просто краткое изложение личных проектов React корпоративного уровня. Конечно, есть недостатки, и если в процессе работы будут какие-то хорошие идеи, я обновлю его по этому поводу. Приглашаем всех обратить внимание на Звезду! Если у вас также есть хорошие идеи, оставьте сообщение для обмена, я надеюсь, что эта скромная статья вдохновит вас.