react+redux框架配置从无到有直到正常运行全流程(上)
来源:互联网 发布:mysql 更改character 编辑:程序博客网 时间:2024/05/22 07:00
写于:2017-1-18
完整干净demo地址:coding.net/u/java_luo/p/react_luo/git
技术栈:
react,redux,webpack,eslint,babel,antd(蚂蚁金服ui)
1、前期准备
①、windows系统,本框架是在windows系统下配置的
②、SublimeText, 用的这个编辑器
②、安装node.js
③、创建一个文件夹,用node命令行工具进入该文件夹,运行npm init命令 生成一个初始package.json
2、配置package.json
{ "name": "myreact", // 项目名字 "version": "1.0.0", // 项目版本 "description": "...", // 项目简介 "main": "index.js", // 项目入口js,用不到,写一个在这里当摆设 "scripts": { "watch": "node server.js", // 开发模式运行此命令启动服务 "build": "webpack -p --config webpack.production.config.js --progress --profile --colors" // 项目最终打包 运行此命令(webpack.production.config.js是后面要创建的webpack配置文件) }, "author": "luo", // 项目作者 "license": "ISC", // 项目开源许可证 "private": true, // 项目是否私有 // 项目最终需要依赖的插件 "dependencies": { "antd": "^2.6.3", // 蚂蚁金服的ui库 "babel-polyfill": "^6.20.0", // 用于解析ES6各种新功能(比如map,set,Generator等) "react": "^15.4.2", // react框架核心 "react-dom": "^15.4.2", // react渲染组件时要用 "react-redux": "^5.0.1", // react与redux连接的桥梁 "react-router": "^3.0.0", // react路由器,做路由要用 "react-router-redux": "^4.0.7", // react路由与redux连接的桥梁 "redux": "^3.6.0", // redux核心 "redux-thunk": "^2.1.0", // redux中间件,用于处理异步action "reqwest": "^2.0.5" // 一个工具插件,封装了fetch,异步请求时有用 }, // 开发模式下需要依赖的插件 "devDependencies": { "babel-core": "^6.21.0", // babel核心 "babel-loader": "^6.2.10", // webpack解析器:用于打包时解析ES6 "babel-plugin-import": "^1.1.0", // 按需加载,用于蚂蚁金服ui库,用了哪些ui组件,就编译哪些组件 "babel-preset-es2015": "^6.18.0", // babel插件:解析ES6语法 "babel-preset-react": "^6.16.0", // babel插件:解析react语法(JSX) "babel-preset-stage-3": "^6.17.0", // babel插件:解析js目前最新版本的一些语法 "css-loader": "^0.26.1", // webpack解析器:打包时处理css,less,sass这类文件中的url路径问题,比如background-image的路径,会自动匹配项目的根路径 "eslint": "^3.13.1", // 一个语法检查器,在开发的时候常用来规范代码风格和排错 "eslint-loader": "^1.6.1", // webpack解析器:把eslint加到webpack中使用,所以需要这个 "eslint-plugin-react": "^6.9.0", // eslint插件:支持检查react的语法 "extract-text-webpack-plugin": "^1.0.1", // 项目最终打包时,单独把所有样式文件打包成一个css文件,需要这个 "file-loader": "^0.9.0", // webpack解析器:打包时解析各种非图片类文件和gif文件 "html-webpack-plugin": "^2.26.0", // webpack插件:打包时自动生成一个index.html "less": "^2.7.2", // less核心 "less-loader": "^2.2.3", // webpack解析器:打包时解析less "style-loader": "^0.13.1", // webpack解析器:打包时将样式文件添加进页面中,自动生成<style>标签 "url-loader": "^0.5.7", // webpack解析器:处理图片或其他文件,会把小图片编译为base64编码 "webpack": "^1.14.0", // webpack模块化打包工具 "webpack-dev-server": "^1.16.2" // 一个和webpack配合使用的服务器工具,打包完成后启动一个服务,让开发人员方便测试,相当于tomcat }}
3、然后创建一下项目的基本目录结构
图中有两个东西不是直接使用的,而是要加载到webpack中,让webpack打包的时候自动调用:
①、.babelrc,即babel功能是要让webpack去调用
②、.eslintrc.json, 即语法检测是在打包时自动去检测
4、配置babel
babel 用于解析ES6,jsx等新语法,让现代浏览器可以运行。
创建.babelrc文件(名为.babelrc,无后缀)
{ // 运用babel的3个插件,es2015,stage-3,react (即npm install时的那3个插件) "presets": ["es2015", "stage-3", 'react'], // 下面是配置按需加载那个插件的(babel-plugin-import) // 是从蚂蚁金服抄的,大致意思就是,css、less等样式文件需要按需加载 // js也要按需加载 "plugins": [["import",[ { "libraryName": "antd", "libraryDirectory": "lib", "style": true }, { "libraryName": "antd-mobile", "libraryDirectory": "component", }, ]]]}
5、配置eslint
{ // 项目的环境 // 意思就是以下配置的这些环境,它们自身的全局变量,eslint认为是存在的,比如jquery的$,如果下面不配置jquery:true,项目中直接使用$,eslint会认为$未定义 "env": { "browser": true, // 浏览器环境,window变量等 "commonjs": true, // commonjs环境,require方法等 "es6": true, // es6环境,各种es6新功能 "jquery": true // jquery, 就是$符号 }, // 继承某个官方定义好的检查规则 // 下面用的是react的规则,必须配这个,否则eslint识别不了react "extends": "plugin:react/recommended", // 设置各种解析器 "parserOptions": { "ecmaVersion": 8, // js版本,最新的8(即JS2017) "ecmaFeatures": { // 额外的语言特性 "impliedStrict": true, // 全局启用严格模式 "experimentalObjectRestSpread": true, // 支持...余运算符,就是ES6里面那个“...”解构赋值 "jsx": true // jsx语法 }, "sourceType": "module" // 代码类型:模块化。因为我们经常用import,export等 }, // 第3方插件 "plugins": [ "react" // 支持react(即eslint-plugin-react),上面配置了jsx,但react语法不仅仅是jsx,所以需要这个 ], // 自定义的检查规则 "rules": { // 字符串的引号必须用单引号 "quotes": [ "error", "single" ], // 每一句代码结束必须加分号 "semi": [ "error", "always" ], "no-cond-assign": "error", // 禁止条件表达式中出现赋值操作符 "no-debugger": "error", // 不允许代码中出现debugger "no-dupe-args": "error", // function禁止重名参数 "no-caller": "error", // 禁用 arguments.caller 或 arguments.callee "no-invalid-this": "error", // 禁止全局this "no-unmodified-loop-condition": "error", // 禁止死循环 "no-with": "error", // 禁止使用with语句 "no-catch-shadow": "error" // 禁止 catch 子句的参数与外层作用域中的变量同名 }}
eslit的具体使用和配置可以参考此网站:Eslint中文站
6、配置webpack
webpack用于项目打包,把众多的js,css等文件压缩,混淆加密,最终只生成几个合并后的文件
开发环境和生产环境的配置有所不同,下面先配置开发环境:
webpack.dev.config.js
var path = require('path'); // 用于获取根路径var webpack = require('webpack'); // webpack核心var ROOT_PATH = path.resolve(__dirname); // 项目根路径var APP_PATH = path.resolve(ROOT_PATH, 'src'); // 项目的src目录路径var APP_FILE = path.resolve(APP_PATH, 'app'); // 项目的入口文件(即src/app.js)var BUILD_PATH = path.resolve(ROOT_PATH, '/build'); //规定打包好的文件存放到此目录下(开发模式中,我们一般配置为最终生成1个bundle.js)module.exports = { /* 需要被打包的文件在此配置 */ entry: { app: [ 'webpack-dev-server/client?http://localhost:8888', // 热更新监听此地址(端口号与server.js中配置的要一致,我们稍后来写server.js) 'webpack/hot/only-dev-server', // 启用热更新 APP_FILE // 入口文件 ] }, /* 打包后要输出的文件在此配置 */ output: { publicPath: '/test/', // 这是在启动webpack-dev-server时,bundle.js的引用路径应该相对于此路径,即在index.html中: // <script src="/test/bundle.js"></script> // 而且所有的url地址,比如css中的背景图片,html中的img的src都会自动变成:/test/***** path: BUILD_PATH, // 将打包好的文件放在此路径下,开发模式中只会在内存中存在,不会在此路径生成真正的文件 filename: 'bundle.js', //最终生成的文件名字 }, devtool: 'source-map', // 打包后,代码都被压缩了,如果报错看不出是在哪一行报的错,配置这个就是为了解决这个问题 /* 下面是配置一些解析器 */ module: { /* 在打包之前运行 */ preLoaders: [ { test: /\.js?$/, // 解析.js,.jsx loader: 'eslint', // 解析器是eslint,即进行语法检查,不过关的话会报错 exclude: /node_modules/, // 不检查node_modules目录下的内容 }, ], /* 打包时需要用到的解析器 */ loaders: [ // 解析.js,.jsx,用babel解析器,webpack会自动加载我们配置的.babelrc文件 { test: /\.js$/, exclude: /node_modules/, loader: 'babel', }, // 解析.css,先执行css-loader,再执行style-loader // 注意:连node_modules中的也一并解析 { test: /\.css$/, loaders: ['style', 'css'], }, // 解析.less,先执行css-loader,再执行style-loader // 注意:连node_modules中的也一并解析(因为蚂蚁金服ui框架的样式文件就存在此目录下) // 如果没有用到less,就不用配(如果不配,蚂蚁金服ui框架的样式文件就要使用antd.css,而不要使用antd.less) { test: /\.less$/, loaders: ['style', 'css', 'less'], }, // 其他各类文件处理,打包后会把这些文件挪到打包好的文件夹中 { test: /\.(eot|woff|svg|ttf|woff2|gif|appcache|mp3)(\?|$)/, exclude: /node_modules/, loader: 'file-loader?name=[name].[ext]', }, // 处理图片,这里配置的是,小于8192字节的图片变成base64编码,其余图片最终会生成一个images文件夹,存放其中 { test: /\.(png|jpg|gif)$/, exclude: /node_modules/, loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]', } ] }, /* 配置一些额外的webpack插件 */ plugins: [ new webpack.HotModuleReplacementPlugin(), // 热更新插件 new webpack.NoErrorsPlugin() // 即使有错误也不中断运行 ], /* 配置额外的自定义方案 */ resolve: { extensions: ['', '.js', '.jsx', '.less', '.css'], //在webpack打包时,自动匹配这些后缀名的文件 }};
开发模式下:
①、所有的样式文件会以内嵌方式全部加到index.html的head中。
②、会生成一个仅存在于内存中的bunde.js文件
7、写server.js
第6步配置了webpack.dev.config.js,打包后,需要运行这个项目,
所以写一个server.js:
var webpack = require('webpack'); // webpack核心var WebpackDevServer = require('webpack-dev-server'); // webpack提供的服务器插件var config = require('./webpack.dev.config.js'); // webpack的配置文件/* 下面是创建一个服务对象,固定写法 */var server = new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, // 文件相对引用路径,就用配置文件中配置的 hot: true, // 是否启用热更新 inline: true, // 是否实时刷新,即代码有更改,自动刷新浏览器 historyApiFallback: true, // 所有的url路径均跳转到index.html,需要设置为true,否则比如访问localhost:8888,就跳转不到/home页 progress: true, // 在控制台输出webpack的编译进度 stats: { colors: true }, // 不同类型的信息用不同的颜色显示});/* 将所有的访问路径,都返回index.html */server.app.get('*', function(req, res) { res.sendFile(__dirname + '/src/index.html')});/* 启动服务 */server.listen(8888, function() { console.log('启动服务:8888端口')});
启动服务的命令在package.json中已经配好:
运行 npm run watch 即可
现在启动服务,将什么也没有,因为src/app.js和src/index.html是空的
这个之后再配置,下面来看一下配置最终打包所需的webpack配置文件
8、配置webpack.production.config.js
即最终用于生产环境的正式打包所需配置
webpack.production.config.js:
var path = require('path'); // 为了得到项目根路径var webpack = require('webpack'); // webpack核心var ExtractTextPlugin = require('extract-text-webpack-plugin'); // 为了单独打包cssvar HtmlWebpackPlugin = require('html-webpack-plugin'); //根据模板生成最终html文件var ROOT_PATH = path.resolve(__dirname); // 项目根路径var APP_PATH = path.resolve(ROOT_PATH, 'src'); // 项目src目录var APP_FILE = path.resolve(APP_PATH, 'app'); //项目入口文件(即src/app.js)var BUILD_PATH = path.resolve(ROOT_PATH, 'build/dist'); //打包后文件所存放的目录(一般就这么命名)module.exports = { entry: { app: APP_FILE, // 需要被打包的文件,就这个入口文件 }, output: { path: BUILD_PATH, // 将文件打包到此目录下 publicPath: '/', // 在生成的html中,文件的引入路径会相对于此地址,生成的css中,以及各类图片的URL都会相对于此地址 // 因为打包后的所有文件,是要交给后台程序员,然后跟后台程序一起,组装成一个完整的项目,上线后,肯定有一个网址来访问,比如: www.test.com; // 那么前端代码中所有的URL地址,都是相对于这个网址而言的,所以这里配置publicPath为‘/’,比如首页的路径就是www.test.com/home,图片test.jpg的访问路径就是www.test.com/images/test.jpg // 最关键的是路由跳转,我们之后要配置react路由,比如这里配置的publicPath是‘/’,那路由中route访问主页,就应该配置为: // <Route path="/home" component={homeContainer} /> // 又比如publicPath配置的是'/xxx', route就应该是: // <Route path="/xxx/home" component={homeContainer} /> // 一般就配置为'/',因为一个项目上线后就会有一个顶级域名指向它,但我们自己测试的时候,比如你最终打包了,然后把代码放到tomcat中运行,tomcat访问肯定就是:http://localhost:8888/myreact,这不是顶级域名,你就应该配置publicPath为‘/myreact’,路由中也相应配置为/myreact/home filename: '[name].js', // 最终生成的文件名字,项目中为app.js,最终也会叫app.js chunkFilename: '[name].chunk.js', // 这是配置一些非入口文件生成的最终文件名字,比如你用了代码分割,按需加载,把你的项目中某些文件单独打包了,就会用到这个。我们这里只有一个app.js,所以这个暂时用不上 }, /* 各种解析器 */ module: { loaders: [ // 解析.js,.jsx { test: /\.js$/, exclude: /node_modules/, loader: 'babel', }, // 解析.css,注意这里要用这个插件作为loader,最后才能生成单独的css文件 { test: /\.css$/, loader: ExtractTextPlugin.extract('style', ['css']), // 用这种方式写的,表示此类文件单独打包成一个css文件 }, // 解析less,原理同上 { test: /\.less$/, loader: ExtractTextPlugin.extract('style', ['css','less']), }, // 解析各种非图片文件 { test: /\.(eot|woff|svg|ttf|woff2|gif|appcache|mp3)(\?|$)/, exclude: /node_modules/, loader: 'file-loader?name=[name].[ext]', }, // 解析图片,小于8kb的转换成base64 // 注意配种中的name,就是生成到了images文件夹下 { test: /\.(png|jpg|gif)$/, exclude: /node_modules/, loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]', } ] }, /* 额外的插件 */ plugins: [ new webpack.DefinePlugin({ // 一定要配置这个,这个是为了告诉webpack,当前用什么模式打包代码,production生产模式,dev开发模式 'process.env': { NODE_ENV: JSON.stringify('production') //定义生产环境 } }), // 此插件详细教程 http://www.cnblogs.com/haogj/p/5160821.html new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML filename: '../index.html', //生成的html存放路径,相对于(注意前面配置的BUILD_PATH是“build/dist”,即index.html会生成到build下,其他文件会打包到build/dist下) template: './src/index_template.html', //html模板路径 inject: true, // 是否将js放在body的末尾 hash: false, // 是否为本页面所有资源文件添加一个独特的hash值 }), // 配置了这个插件,再配合上面loader中的配置,将所有样式文件打包为一个单独的css文件 new ExtractTextPlugin('[name].css'), // 提取那些公共的模块、代码打包为一个单独的js文件 // 下面这个方法第3个参数是自动去匹配,webpack遍历所有资源,发现是模块的,而且这个模块不是在src目录中的,就提取到公共js中 // 即把所有node_modules中用到的包都单独打包到一个js中,如果有css,还会单独生成一个vendors.css文件 new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', (module, count) => module.resource && module.resource.indexOf(APP_PATH) === -1), // Uglify 加密压缩源代码 new webpack.optimize.UglifyJsPlugin({ output: { comments: false, // 删除代码中所有注释 }, compress: { warnings: false, // 估计是不输出警告信息之类的 }, }), ], // 配置额外的解决方案 resolve: { extensions: ['', '.js', '.jsx', '.less', '.css'], //后缀名自动补全 }};
9、写index.html 和 index_template.html模板
index.html:
<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" /> <title>项目名字</title></head><body> <div id="app-root"></div> <script src="/test/bundle.js"></script></body></html>
上面的代码中,因为在webpack.dev.config.js中配置的output.publicPath是‘/test/’,
所以html中的script标签也相应的是/test/bundle.js
上面的这个index.html只是用于开发时,启动服务,然后就会跳转到这个html
index_template.html
<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" /> <title>项目名称</title></head><body> <div id="app-root"></div></body></html>
这个模版html是用于真正打包时,生成最终的index.html,可以交给后台人员直接使用的。js和css,webpack会自动加到最终的index.html中
到此为止,已经配置了可以正常运行的基本雏形,下一篇将在这个基本框架中,加入react,redux,以及基本业务逻辑
后半段:react+redux框架配置从无到有直到正常运行全流程(下)
- react+redux框架配置从无到有直到正常运行全流程(上)
- react+redux框架配置从无到有直到正常运行全流程(上)
- react+redux框架配置从无到有直到正常运行全流程(下)
- react+redux框架配置从无到有直到正常运行全流程(下)
- springside4.2.3GA 从头配置,直到在eclipse中正常运行全流程
- springside4.2.3GA 从头配置,直到在eclipse中正常运行全流程
- react+redux工作流程
- react+redux 前端开发流程
- React: 宏观上认识React和Redux
- React-Redux (初探)
- 配置redux react 以及webpack
- react+redux+react-router4配置过程
- react-redux的工作流程理解
- react+redux+react-redux
- redux在react-native上使用(一)--加入redux
- redux在react-native上使用(二)--加入redux-saga
- redux在react-native上使用(三)--加入redux-thunk
- redux在react-native上使用(五)--redux-actions使用
- 乌克兰又断电了,看Ukrenergo断电事件的技术分析与防护方案
- 利用Cobalt strike一步步教你发送钓鱼邮件
- reading session
- Tomcat(三) Tomcat安装配置:Tomcat+Nginx+keepalived 实现动静分离、Session会话保持的高可用集群
- 【LeetCode】 116. Populating Next Right Pointers in Each Node
- react+redux框架配置从无到有直到正常运行全流程(上)
- 使用spring全注解实现继承时遇到的问题
- Aircrack-ng 之wifi破解
- 【Linux Socket 编程入门】04 - socket编程最常使用的函数及数据结构
- Path in Matrix
- 这才是2017年规划---贫穷来自于懒惰
- 153. Find Minimum in Rotated Sorted Array
- 总结一下学习vb串口通信的初期果实
- 扩展LDBSCAN 算法在图上的应用