webpack构建react项目(一)

前言 

  下面是我们使用到技术栈:

    webpack + react + redux + react-router + react-thunk + ES6 + ....

  注意事项:

    建议使用npm5.X 或者 yarn 包管理工具(最好不要使用cnpm,虽然安装包速度上很快,但是在文件关联上会有坑,之前用的时候被坑过)

一、新建项目目录

config : webpack 配置文件

dist: 打包后代码

src: 源码目录

二、基础配置

安装基础的包

// 生成默认package.josn 文件
npm init

// 安装 webpack 和 webpack-dev-server
npm install webpack webpack-dev-server --save-dev

// 安装 react react-dom
npm install react react-dom --save

// 安装 babel-core 、babel-loader、babel-preset-env、babel-preset-react
npm install  babel-core babel-loader babel-preset-env babel-preset-react --save-dev

// html-webpack-plugin 生成html文件
npm install html-webpack-plugin --sav-dev

添加 webpack 配置

先添加部分基础文件:

config/webpack/file.path.js

 1 const { resolve } = require(‘path‘)
 2
 3 // 项目根目录
 4 const projectPath = process.cwd()
 5 // 代码地址目录
 6 const srcPath = resolve(projectPath, ‘src‘)
 7 // 入口文件目录
 8 const mainPath = resolve(srcPath, ‘main‘)
 9
10 // 入口文件
11 const indexJsPath = resolve(mainPath, ‘index.jsx‘)
12 const indexHtmlPath = resolve(mainPath, ‘index.html‘)
13
14 module.exports = {
15     srcPath,
16     mainPath,
17     indexJsPath,
18     indexHtmlPath
19 }

config/webpack.config.js

const HtmlWebpackPlugin = require(‘html-webpack-plugin‘)

const { srcPath, indexJsPath, indexHtmlPath  } = require(‘./file.path.js‘)

// 生成HTML文件
const generateIndex = new HtmlWebpackPlugin({
    inject: ‘body‘,
    filename: ‘index.html‘,
    template: indexHtmlPath
})

module.exports = {
    // 基础目录(绝对路径),用于从配置中解析入口点和加载程序
    // 默认使用当前目录,但建议在配置中传递一个值。这使得您的配置独立于CWD(当前工作目录)
    context: srcPath,

    // 入口文件
    entry: indexJsPath,

    // 输入配置
    output: {
    },

    // 模块配置
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                use: ‘babel-loader‘
            }
        ]
    },

    // 插件配置
    plugins: [
        generateIndex
    ]
}

添加 babel 配置 .babelrc:

.babelrc

1 {
2     "presets": [
3         "env", // babel 启动插件
4         "react" // 编译react语法插件
5     ]
6 }

添加入口文件 src/main/index.jsx:

 1 import React from ‘react‘
 2 import ReactDOM from ‘react-dom‘
 3
 4 const render = () => {
 5     ReactDOM.render(
 6         <h1>Hello React</h1>,
 7         document.getElementById(‘app-container‘)
 8     )
 9 }
10
11 render()

添加 index.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>webpack react配置</title>
 8 </head>
 9 <body>
10
11 </body>
12 </html>

在package.json 中添加启动命令:

{
  ...
  "scripts": {
    "start": "webpack-dev-server --config config/webpack.config.js"
  },
  ...
}

现在可以直接在cmd中运行:

npm run start

可以在浏览器打开 http://localhost:8080/ ,你可以看到一下效果:

完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons%201

三、高级配置

1. 添加 react-router

// 安装 react-router-dom
npm install react-router-dom --save

添加 src/main/app.js

 1 import React, { Component } from ‘react‘
 2 import { BrowserRouter, Route, Link } from ‘react-router-dom‘  
 3
 4 import Home from ‘../containers/Home‘
 5 import About from ‘../containers/About‘
 6 import Topics from ‘../containers/Topics‘
 7
 8 // BrowserRouter 下只能有一个子元素
 9 class App extends Component {
10     render() {
11         return (
12             <BrowserRouter>
13                 <div>
14                     <ul>
15                         <li><Link to="/">Home</Link></li>
16                         <li><Link to="/about">About</Link></li>
17                         <li><Link to="/topics">Topics</Link></li>
18                     </ul>
19
20                     <hr/>
21
22                     <Route exact path="/" component={Home}/>
23                     <Route path="/about" component={About}/>
24                     <Route path="/topics" component={Topics}/>
25                 </div>
26             </BrowserRouter>
27         )
28     }
29 }
30
31 export default App

添加 containers/Home/index.js

 1 import React, { Component } from ‘react‘
 2
 3 const Home = () => {
 4     return (
 5         <div>
 6             Home
 7         </div>
 8     );
 9 }
10 export default Home

添加 containers/About/index.js

1 import React from ‘react‘
2
3 const About = () => (
4     <div>
5         about
6     </div>
7 )
8
9 export default About

添加 containers/Topics/index.js

import React from ‘react‘

const Topics = () => {
    return (
        <div>
            topics
        </div>
    );
}
export default Topics

修改 src/main/index.jsx 文件

 1 import React from ‘react‘
 2 import ReactDOM from ‘react-dom‘
 3
 4 import App from ‘./app.js‘
 5
 6 const render = Component => {
 7     ReactDOM.render(
 8         <Component />,
 9         document.getElementById(‘app-container‘)
10     )
11 }
12
13 render(App)

路由我们添加完了,可以运行项目, 在浏览器 http://localhost:8080/ 预览效果。

react-router路由有 BrowserRouter和HashRouter 两种路由,两者的区别:

  BrowserRouter 使用HTML5 历史API, HashRouter 使用哈希值
  例如:如果同一个修改用户信息路由,在BroserRouter下显示 user/edit,而在HashRouter 下显示为 #/user/edit
  刷新页面BrowserRouter会向服务端发送请求,后台要做一定处理,而HashRouter 不会向服务端发送请求

  在react-router 4.0 的文档中有这样一段话:
  注意: 使用 hash 的方式记录导航历史不支持 location.key 和 location.state。 在以前的版本中,我们为这种行为提供了 shim,但是仍有一些问题我们无法解决。 任何依赖此行为的代码或插件都将无法正常使用。 由于该技术仅用于支持传统的浏览器,因此在用于浏览器时可以使用 <BrowserHistory> 代替。

完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons2

2.配置redux 、react-thunk

// 安装redux react-redux
npm install redux react-redux react-thunk --save

添加 src/main/store.js

 1 import { combineReducers, createStore, applyMiddleware  } from ‘redux‘
 2 import thunk from ‘redux-thunk‘
 3
 4 import rootReducers from ‘../reducers‘
 5
 6 const middleware = [thunk]
 7
 8 const store = createStore(
 9     combineReducers(rootReducers),
10     {},
11     applyMiddleware(...middleware)
12 )
13
14 export default store

添加 src/reduxcers/index.js

1 function userInfo(state = {}) {
2     return {
3         name: ‘react‘
4     }
5 }
6
7 export default {
8     userInfo
9 }

修改 src/main/app.js

 1 import { Provider } from ‘react-redux‘
 2 import store from ‘./store‘
 3
 4   ...
 5
 6     render() {
 7         return (
 8             <Provider store={store}>
 9                 ...
10             </Provider>
11         )
12     }
13
14   ...

修改 src/tontainers/Home/index.js

 1 import React, { Component } from ‘react‘
 2 import { connect } from ‘react-redux‘
 3
 4 const Home = ({ userInfo }) => {
 5     return (
 6         <div>
 7             Home
 8             <div>
 9                 这是redux中的数据
10                 {userInfo.name}
11             </div>
12         </div>
13     );
14 }
15
16 const mapStateToProps = ({ userInfo }) => {
17     return {
18         userInfo
19     }
20 }
21
22 const mapDispatchTopProps = {}
23 // 使用connect 关联redux
24 export default connect(mapStateToProps, mapDispatchTopProps)(Home)

redux我们添加完了,可以运行项目, 在浏览器 http://localhost:8080/ 预览效果。

完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons3

3.配置 react 热加载

修改 config/webpack.config.js

 1 const webpack = require(‘webpack‘)
 2
 3   ...
 4
 5     // 插件配置
 6     plugins: [
 7         ...
 8         // 开启全局的模块热替换(HMR)
 9         new webpack.HotModuleReplacementPlugin(),
10         // 热加载中可以输入更加友好的模块名
11         new webpack.NamedModulesPlugin()
12     ]
13
14   ...
15
16     devServer: {
17         hot: true
18     }
19   ...

这样配置已经可以实现热加载了,但是并不算结束,还需要配置 react-hot-loader 的热加载插件,这是因为 webpack-dev-server只能即时的刷新页面,但是组件中的状态保存不住,因为React有一些自己的语法(jsx)是HotModuleReplacementPlugin处理不了。而react-hot-loader 在 --hot 基础上做了额外的处理,来保证状态可以存下来。

// 安装 react-hot-loader
npm install react-hot-loader --save

修改 .babelrc

{
    "presets": [
        ["env", {
            "modules": false
        }],
        "react"
    ],
    "plugins": ["react-hot-loader/babel"]
}

添加 react-hot-loader/patch 和 publicPath 到 webpack.config.js,

 1 ...
 2
 3 module.exports = {
 4   ...
 5     // 入口文件
 6     entry: [
 7         ‘react-hot-loader/patch‘,
 8         indexJsPath
 9     ],
10
11     // 输入配置
12     output: {
13         publicPath: ‘/‘
14     },
15
16   ...
17 }
18
19  ...

修改 src/main/index.jsx

import React from ‘react‘
import ReactDOM from ‘react-dom‘
import { AppContainer } from ‘react-hot-loader‘
import App from ‘./app.js‘

const render = Component => {
  ReactDOM.render(
    <AppContainer>
      <Component />
    </AppContainer>,
    document.getElementById(‘root‘),
  )
}

render(App)

// Webpack Hot Module Replacement API
if (module.hot) {
  module.hot.accept(‘./containers/App‘, () => { render(App) })
}

react-hot-loader 就配置完成了,现在更改三个页面中的文件,就可以在页面中实时看到。

配置时注意事项:

  1. 必须将webpack配置中output下publicPath设置为"/",否则无法实现热加载
  2. 将.babelre 中设置babel env预设更改为不使用Babel转换成ES2015模块 [ "env": { "modules": false } ]
  3. react-hot-loader在webpack-dev-server的热加载基础上做了额外的处理,所以必须要打开webpack-dev-server的 hot模式 才可以实现热加载

react-hot-loader我们添加完了,可以运行项目, 在浏览器 http://localhost:8080/ 预览效果。

完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons4

4. 配置各种资源的loader

css资源加载器

// 安装 style-loader css-loader postcss-loader
npm install style-loader css-loader postcss-loader --save-dev

下面是webpack.config.js 中的配置

 1 ...
 2 // 模块配置
 3 module: {
 4     rules: [
 5         ...
 6         {
 7             test: /\.css$/,
 8             use: [
 9                 {
10                     loader: ‘style-loader‘
11                 },
12                 {
13                     loader: ‘css-loader‘,
14                     options: {
15                         importLoaders: 1
16                     }
17                 },
18                 {
19                     loader: ‘postcss-loader‘
20                 }
21             ]
22         }
23         ...
24     ]
25 },
26 ...

使用postcss需要添加postcss.config.js

module.exports = {
    plugins: [
        // 添加你需要的插件,这个后面会提到
    ]
}

之前一直使用sass,但是这里并没有选择sass、less等css预处理框架,个人认为postcss是一个平台,提供了丰富的插件,可以更好处理css。

图片资源的加载

// 安装 url-loader file-loader
npm install url-loader file-loader --save-dev

下面是webpack.config.js 中的配置

 1 ...
 2 // 模块配置
 3 module: {
 4     rules: [
 5         ...
 6         {
 7             test: /\.(png|jpg|gif)$/,
 8             use: [
 9                 {
10                     loader: ‘url-loader‘,
11                     options: {
12                         limit: 8192
13                     }
14                 }
15             ]
16         },
17         ...
18     ]
19 },
20 ...

url-loader: 可以将图片小于8192(根据limit设置而定)的图片装成base64和源码添加在一起,减少请求,提高加载速度。

file-loader: 对url-loader无法处理的图片资源(大于limit设置的值),使用此loader进行处理,当然这个loader还可以加载字体图标等文件,这里就不在详细添加了。

完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons5

  基本的配置都讲完了,后续系列中会讲到优化webpack配置、开发生成配置的拆分、构建优化和服务代理,mock数据等功能

  如果本文对你有帮助,请给个 star,感谢^_^

时间: 2024-09-29 08:23:22

webpack构建react项目(一)的相关文章

webpack构建react项目的配置文件

webpack是一个模块打包工具,处理模块之间的依赖同时生成对应模块的静态资源. webpack把项目中所有的静态文件都看作一个模块 模快之间存在着一些列的依赖 多页面的静态资源生成(打包之后生成多个静态文件,涉及到代码拆分) webpack.config.js文件 //__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录 //webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugi

使用webpack搭建react项目 webpack-react-project

webpack-react-project 使用webpack搭建react项目 webpack搭建react项目 github源码 具体配置信息参照package.json和webpack.config.js 首先创建一个项目文件夹,并进入到该文件夹: mkdir react-webpack-project 初始化项目:npm init 根据提示创建package.json 通过NPM安装webpack和webpack-cli,其中-D相当于--save-dev: npm install we

webpack构建Vue项目引入jQ时发生“&#39;$&#39; is defined but never used”的处理

今天公司需要新建个数据后台,就按照查到的方法构建了Vue框架的项目,引入jQ.bootstrap时,按照在线方法配置,发现 main.js 里的引用jQ一直显示红标,没多想,在按照网上配置完后,npm run dev运行,就抛出这么个错误,百思不得解 错误如下: '$' is defined but never used 1 http://eslint.org/docs/rules/space-before-function-paren 1 http://eslint.org/docs/rule

使用Webpack构建React应用

前面写过一遍<使用gulp+Browserify构建React应用>,本文来看看更强大的构建工具- -Webpack.先来看看webpack强大之处介绍 1.将css.图片以及其他资源打包到同一个包中 2.在打包之前对文件进行预处理(less.coffee.jsx等) 3. 根据入口文件的不同把你的包拆分成多个包 4.支持开发环境的特殊标志位 5.支持模块代码"热"替换 6.支持异步加载 ??Webpack不仅帮助你打包所有的Javascript文件,还拥有其他应用需要的资

webpack构建react多页面应用

写这个的初衷是很难找一个简洁的项目脚手架,很多脚手架都有很多依赖,光看依赖就要很久,所以自己参照网上的内容,弄个这么一个简单的多页面的脚手架. 利用creat-react-app 新建一个react应用 npm install -g create-react-app 然后创建一个项目 create-react-app demo create-react-app会自动初始化一个脚手架并安装 React 项目的各种必要依赖,如果在过程中出现网络问题,请用cnpm淘宝镜像安装. 然后我们进入项目并启动

webpack搭建react项目

遥看套路挖掘机,不见当年老司机.this is a boilerplate 1.新建一个项目目录文件夹,暂且叫seed cd seed npm init 然后一直回车,最后yes,最终生成一个package.json文件 2.新建以下 src  文件夹用于存放js,css,img等源码和引用的静态文件 .babelrc babel编译器配置文件 favicon.ico   浏览器默认读取的一个icon index.html  入口首页 webpack.config.js  webpack配置文件

用Webpack构建Vue项目

开始之前,需要安装node环境.(安装过程在此就不啰嗦了) 1.创建基本结构 首先我们要创建一个空文件夹(我这里叫todos,你可以随便命名)作为项目的根目录. 创建一个没有任何依赖关系的package.json,可以通过命令行 npm init 创建. 配置下基本信息即可. 创建一个index.html文件,这个是显示在浏览器中的页面. 注意: 1.这里的暂时并不存在: 2.的数据会被vue文件填入. 创建一个src文件夹,并在文件夹内新建一个main.js文件: 这样我们就完成了一个关于vu

webpack构建vue项目(配置篇)

最近公司要求用vue重构项目,还涉及到模块化开发,于是乎,我专门花了几天的时间研究了一下webpack这个目前来看比较热门的模块加载兼打包工具,发现上手并不是很容易,现将总结的一些有关配置的心得分享出来,欢迎大神来拍砖... 一.新建一个项目目录,cd /d 定位进去,然后输入npm init,会提示你填写一些项目的信息,一直回车默认就好了,或者直接执行npm init -y 直接跳过,这样就在项目目录下生成了一个package.json文件. 二.接下来就是通过npm安装项目依赖项,命令行输入

gulp+webpack构建前端项目

本文将介绍如何利用gulp+webpack构建一个基本的前端项目.假设你已经安装了node环境并且会使用简单的命令行 1.gulp安装 (1)全局安装 npm install gulp -g (2)查看gulp是否安装成功 gulp -v (3)进入本地目录,新建gulpfile.js 2.安装gulp-webpack插件 基于gulp的插件非常多,建议大家查看npm官网https://www.npmjs.com (1)安装 webpack的用途主要是模块化+打包.安装敲入命令 npm inst