react WebPack重配置

react項目建立流程

15

react 項目搭建

系統: windows

1.安裝 node

node 下載地址.一路 nextjavascript

若是遇到 windows 沒有權限安裝 msi 文件.打開 cmd,運行 msiexec /package 文件路徑.

查看是否安裝成功,打開終端css

node -v npm -v

2.安裝 vscode 編輯器

vscode 下載地址.一路 nextjava

3.安裝 react 項目腳手架

打開終端node

npm install -g create-react-app

4.建立 react 項目

create-react-app myApp cd myApp npm install npm start code .

5.安裝項目依賴

npm i react-router-dom mobx mobx-react axios qs --save

配置裝飾器語法支持react

npm --save-dev @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators

解壓 webpack 配置webpack

npm run eject

修改webpack.config.dev.jswebpack.config.prod.jsios

{
    test: /\.(js|mjs|jsx|ts|tsx)$/, include: paths.appSrc, loader: require.resolve('babel-loader'), options: { customize: require.resolve('babel-preset-react-app/webpack-overrides'), plugins: [ + ['@babel/plugin-proposal-decorators', { legacy: true }], + ['@babel/plugin-proposal-class-properties', { loose: true }], [ require.resolve('babel-plugin-named-asset-import'), { loaderMap: { svg: { ReactComponent: '@svgr/webpack?-prettier,-svgo![path]' } } } ] ], // This is a feature of `babel-loader` for webpack (not Babel itself). // It enables caching results in ./node_modules/.cache/babel-loader/ // directory for faster rebuilds. cacheDirectory: true, // Don't waste time on Gzipping the cache cacheCompression: false } }

6.配置路由

在項目中新建src\pages文件夾.
新建頁面文件src\pages\Home\index.jsnginx

// Home\index.js /** * @name Home * @desc 首頁 */ import React, { Component } from 'react' class Home extends Component { render() { return ( <div> <h1>Home</h1> </div> ) } } export default Home

新建router.jsweb

/** * @name Router * @desc 頁面路由配置 */ import React, { Component } from 'react' import { Switch, Route, Redirect } from 'react-router-dom' import Home from './pages/Home' class Router extends Component { render() { return ( <Switch> <Redirect path="/" to="/home" exact /> <Route path="/home" component={Home} /> </Switch> ) } } export default Router

7.配置 http 請求插件

新建src\utils\axios.jssql

import axios from 'axios' import qs from 'qs' const axiosIns = axios.create({ baseURL: '/', timeout: 10000, responseType: 'json', transformRequest: [data => qs.stringify(data)], headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' } }) axiosIns.interceptors.request.use( config => { return config }, error => Promise.reject(error) ) axiosIns.interceptors.response.use(result => result.data, error => Promise.reject(error)) const get = (url, params = null, config = {}) => axiosIns.get(url, { ...config, params }) const post = axiosIns.post const all = axiosIns.all export { get, post, all }

8.配置狀態管理插件

8.1 新建src\utils\mobx-store.js

/** * @name Store * @desc store 構造器 */ import { action, configure } from 'mobx' configure({ enforceActions: 'observed' }) class Store { constructor(modules) { Object.keys(modules).forEach(moduleName => { this[moduleName] = new modules[moduleName]({ mapStore: this.mapStore.bind(this), rootState: this.rootState }) }) } rootState = {} mapStore(moduleName) { if (moduleName) { return this[moduleName] ? this[moduleName] : console.error(new Error(`has no store named "${moduleName}"`)) } else { return this } } } let $mapStore = null let $rootState = null class StoreModule { constructor({ mapStore, rootState }) { $mapStore = mapStore $rootState = rootState } mapStore(name) { return $mapStore(name) } getRootState() { return $rootState } setState(options) { action(opt => { Object.keys(opt).forEach(key => { if (Object.prototype.hasOwnProperty.call(this, key)) { this[key] = opt[key] } else { console.error(new Error(`mobx action "setState": has no attribute named "${key}"`)) } }) })(options) } } export { Store, StoreModule }

8.2 建立一個狀態模塊,新建src\store\test-store.js

/** * @name Test * @desc */ import { observable, action, configure } from 'mobx' import { StoreModule } from '../utils/mobx-store' configure({ enforceActions: 'observed' }) class Test extends StoreModule { @observable msg = '' @action.bound handleChangeMsg(e) { this.setState({ msg: e.target.value }) } } export default Test

8.3 配置 store

新建src\store\index.js

/** * @name Store * @desc 合併所有子模塊的store */ import { Store } from '../utils/mobx-store' import Test from './test-store.js' export default new Store({ Test })

9.注入 router 和 store

修改index.js

import React from 'react' import ReactDOM from 'react-dom' import { BrowserRouter } from 'react-router-dom' import { Provider } from 'mobx-react' import store from './store' import App from './App' ReactDOM.render( <Provider {...store}> <BrowserRouter> <App /> </BrowserRouter> </Provider>, document.getElementById('root') )

修改App.js

import React, { Component } from 'react' import Routes from './router' class App extends Component { render() { return ( <div classes="container"> <Routes /> </div> ) } } export default App

修改src\pages\Home\index.js

/** * @name Home * @desc 首頁 * @author * @version */ import React, { Component } from 'react' import { inject, observer } from 'mobx-react' @inject('Test') @observer class Home extends Component { render() { return ( <div> <h1>Home</h1> <p>msg: {this.props.Test.msg}</p> <p> <input type="text" value={this.props.Test.msg} onChange={this.props.Test.handleChangeMsg} /> </p> </div> ) } } export default Home

11.http 請求例子

// src\store\test-store.js /** * @name Test * @desc */ import { observable, action, configure } from 'mobx' import { StoreModule } from '../utils/mobx-store' import { post } from '../utils/axios' configure({ enforceActions: true }) class Test extends StoreModule { @observable msg = '' @action.bound handleChangeMsg(e) { this.setState({ msg: e.target.value }) } @action.bound async getSomething() { try { const res = await post('/some-data', { type: 'news' }) } catch (err) { console.error(err) } } } export default Test

12.打包

npm run build

安裝本地服務器啓動工具

npm install -g serve

啓動打包的項目

serve -s ./build
相關文章
相關標籤/搜索