本文来自网易云社区

作者:汪洋

背景

最近开发一个全新AB测试平台,思考了下正好可以使用react技术开发。

实践前技术准备

首先遇到一个概念,redux。这货还真不好理解,大体的理解:Store包含所有数据,视图触发一个Action,Store收到Action后,返回一个新的 State,这样视图就发生变化,State计算过程叫做 Reducer,Reducer其实就是一个处理数据的函数,接受 Action和 当前State作为参数,返回一个新的 State。
明白这个后,就可以开始实践了。

搭建平台的脚手架

对于我这方面没搞过的菜鸟,还真是不容易。接下来说下作为新手如何实践的。

  1. 第一步:依赖包

    "devDependencies": {"babel-core": "^6.26.0","babel-eslint": "^8.2.2","babel-loader": "^7.1.2","babel-plugin-import": "^1.6.6","babel-preset-es2015": "^6.22.0","babel-preset-react": "^6.24.1","babel-preset-stage-0": "^6.24.1","css-loader": "^0.28.7","eslint": "^4.18.2","eslint-config-airbnb": "^16.1.0","eslint-loader": "^2.0.0","eslint-plugin-import": "^2.9.0","eslint-plugin-jsx-a11y": "^6.0.3","eslint-plugin-react": "^7.7.0","extract-text-webpack-plugin": "^3.0.2","html-webpack-plugin": "^3.0.4","less": "^2.7.3","less-loader": "^4.0.6","style-loader": "^0.19.1","url-loader": "^1.0.1","webpack": "^3.1.0"},"dependencies": {"normalize.css": "^8.0.0","react": "^16.2.0","react-dom": "^16.2.0","react-redux": "^5.0.7","react-router-dom": "^4.2.2","redux": "^3.7.2"}

    dependencies 中引入的依赖包,是react的标配了,不用解释。
    devDependencies 中引入了 webpack,babel,babel插件,eslint语法检测,eslint配置包airbnb,html模板资源替换插件 html-webpack-plugin,css提取插件 extract-text-webpack-plugin,less编译相关插件,图片等静态资源路径处理插件 url-loader。
    这里作为新手,一般都是参考网上的配置,比如我就是github上找了个项目,摸索一下。推荐一本教程书《React全栈》,作者写的很详细,对入门绝对有帮助。
    至此,基本依赖包已加载完。

  2. 第二步:webpack配置 这里不得不说,新手真不容易。 首先介绍下项目结构:
    views/entry.html(静态模板),
    src/entry.jsx(入口文件),
    src/actions(redux概念中Actions所在的文件夹) ,
    src/reducers(redux概念中Reducers所在的文件夹) ,
    src/store(redux概念中Store所在的文件夹) ,
    src/pages(存放页面的文件夹,jsx),
    src/compinents(存放业务组件的文件夹,jsx),
    src/style(公共样式文件夹,less),
    src/utils(帮助类文件夹),
    src/constants(常量所在文件夹,保存各自的actions的type),
    src/plugins(第三方插件文件夹),
    build/(编译后文件),
    webpack/(webpack编译配置所在文件夹),
    .eslintrc(eslint配置文件),
    .gitignore(git配置文件),
    package.json

接下来就是webpack的配置了,先上代码

const path = require('path');const webpack = require('webpack');// html中替换编译后的jsconst HtmlwebpackPlugin = require('html-webpack-plugin');// css提取const ExtractTextPlugin = require('extract-text-webpack-plugin');const ROOT_PATH = path.resolve(__dirname);const APP_PATH = path.resolve(ROOT_PATH, '../src');const BUILD_PATH = path.resolve(ROOT_PATH, '../build');module.exports = {entry: {entry: path.resolve(APP_PATH, './entry.jsx'),vendor: ['react', 'react-dom', 'pace']},output: {filename: '[name].js',path: BUILD_PATH,chunkFilename: '[name].js',publicPath: '../'},devtool: 'eval-source-map',  module: {rules: [{test: /\.(js|jsx)$/,exclude: /node_modules/,use: [{loader: 'babel-loader',query: {presets: ['es2015', 'react', 'stage-0'],plugins: ['syntax-dynamic-import', ['import', { libraryName: 'antd', style: 'css' }]]}}]},{test: /\.(css|less)$/,use: ExtractTextPlugin.extract({fallback: 'style-loader',use: [            'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',            'less-loader']}),exclude: /node_modules/},{test: /\.(css)$/,use: ExtractTextPlugin.extract({fallback: 'style-loader',use: [            'css-loader']}),include: /node_modules/},{test: /\.(jpg|jpeg|png|svg|gif|bmp)/i,use: [          'url-loader?limit=5000&name=img/[name].[sha512:hash:base64:8].[ext]']},{test: /\.(woff|woff2|ttf|eot)($|\?)/i,use: [          'url-loader?limit=5000&name=fonts/[name].[sha512:hash:base64:8].[ext]']}]},resolve: {extensions: ['.js', '.jsx', '.less', '.css', '.png', '.jpg', '.svg', '.gif', '.eot'],alias: {pace: path.resolve(ROOT_PATH, '../src/plugins/pace/index.js'),ImagesPath: path.resolve(ROOT_PATH, '../src/')}},devServer: {historyApiFallback: true,hot: true,inline: true,progress: true},plugins: [    new webpack.optimize.CommonsChunkPlugin({name: ['commons', 'vendor'],minChunks: 2}),    new ExtractTextPlugin('commons.css', {allChunks: true}),    new HtmlwebpackPlugin({template: path.resolve(ROOT_PATH, '../views/entry.html'),filename: path.resolve(ROOT_PATH, '../build/entry.html'),chunks: ['entry', 'vendor'],hash: false}),    // 加署名new webpack.BannerPlugin('Copyright by xxx')]
};

第一次接触配置,真的找不到北,太多插件,太多功能。作为新手,那需要怎么个思路,我总结:按项目需求来配置。不要认为其他人配置的就适合自己项目,要不然给自己带来各种麻烦。 摸索这个过程还挺长的:
A. 首先需求还是明确的:less编译、jsx编译、公共文件单独打包、html静态模板中插入编译后的文件路径、css提取。 上面这些对应配置:

const path = require('path');const webpack = require('webpack');// html中替换编译后的jsconst HtmlwebpackPlugin = require('html-webpack-plugin');// css提取const ExtractTextPlugin = require('extract-text-webpack-plugin');const ROOT_PATH = path.resolve(__dirname);const APP_PATH = path.resolve(ROOT_PATH, '../src');const BUILD_PATH = path.resolve(ROOT_PATH, '../build');module.exports = {entry: {entry: path.resolve(APP_PATH, './entry.jsx'),vendor: ['react', 'react-dom', 'pace']},output: {filename: '[name].js',path: BUILD_PATH,chunkFilename: '[name].js',publicPath: '../'},devtool: 'eval-source-map',  module: {rules: [{test: /\.(js|jsx)$/,exclude: /node_modules/,use: [{loader: 'babel-loader',query: {presets: ['es2015', 'react', 'stage-0']}}]},{test: /\.(css|less)$/,use: ExtractTextPlugin.extract({fallback: 'style-loader',use: [            'css-loader',            'less-loader']}),exclude: /node_modules/},{test: /\.(jpg|jpeg|png|svg|gif|bmp)/i,use: [          'url-loader?limit=5000&name=img/[name].[sha512:hash:base64:8].[ext]']},{test: /\.(woff|woff2|ttf|eot)($|\?)/i,use: [          'url-loader?limit=5000&name=fonts/[name].[sha512:hash:base64:8].[ext]']}]},plugins: [    new webpack.optimize.CommonsChunkPlugin({name: ['commons', 'vendor'],minChunks: 2}),    new ExtractTextPlugin('commons.css', {allChunks: true}),    new HtmlwebpackPlugin({template: path.resolve(ROOT_PATH, '../views/entry.html'),filename: path.resolve(ROOT_PATH, '../build/entry.html'),chunks: ['entry', 'vendor'],hash: false})]
};

B. 配置到这步后,就能满足基本开发了。试用之后,这时候对自己提出了几个问题:

  1. 命名css,开发的时候能不能不用担心命名冲突的问题。

  2. css中引入图片后,编译失败问题。

  3. 第三方插件 加载效果pace组件,引入问题。

  4. 现在文件过大,有根据路由按需加载需求。

针对上面4个问题,重新配置:
第2个和3个解决方案一致:即声明别名

  resolve: {extensions: ['.js', '.jsx', '.less', '.css', '.png', '.jpg', '.svg', '.gif', '.eot'],alias: {pace: path.resolve(ROOT_PATH, '../src/plugins/pace/index.js'),ImagesPath: path.resolve(ROOT_PATH, '../src/')}}

当中第3个问题,网上找了好多资料,都没有结果,后来请教了前端群的同行,才解决该问题。
解决第1个问题过程中,我学习到了cssModule的概念,一开始菜鸟还不好理解,实践了后,还真是个好东西。

      {test: /\.(css|less)$/,use: ExtractTextPlugin.extract({fallback: 'style-loader',use: [            'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',            'less-loader']}),exclude: /node_modules/},

只要css-loader启动modules就好了。为了支持 react,引入了 react-css-modules 依赖包。

网易云免费体验馆,0成本体验20+款云产品

更多网易研发、产品、运营经验分享请访问网易云社区。

相关文章:
【推荐】 HBase原理–所有Region切分的细节都在这里了
【推荐】 6本互联网技术畅销书免费送(数据分析、深度学习、编程语言)!

react技术栈实践(1)相关推荐

  1. react技术栈实践

    背景 最近开发一个全新AB测试平台,思考了下正好可以使用react技术开发. 实践前技术准备 首先遇到一个概念,redux.这货还真不好理解,大体的理解:Store包含所有数据,视图触发一个Actio ...

  2. React 技术栈在蚂蚁金服的实践

    在2017在线技术峰会"阿里开源项目最佳实践"上,蚂蚁金服前端工程师崔晓斌为大家带来了"React 技术栈在蚂蚁金服的实践"的演讲.主要从研发的模式变迁开始说起 ...

  3. 深入react技术栈(11):样式处理

    我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注前端小歌谣 基本样式设置 样式中的像素值 使用className库 Css Modules css模块化遇到了哪些问题 css模块化方案 样式默认 ...

  4. React技术栈探究-Redux

    React技术栈耕耘 -- Redux Redux 是近年来提出的 Flux 思想的一种实践方案,在它之前也有 reflux . fluxxor 等高质量的作品,但短短几个月就在 GitHub 上获近 ...

  5. 如何从零学习 React 技术栈

    为什么要学习 React? 首先,React 相较于其他框架,其生态圈发展最为完整成熟,有非常多现成的.完整的解决方案. 其次,它适用于大中型应用的开发,便于团队中多人之间协作,很多大厂都在正式的项目 ...

  6. react 技术栈项目轻量化方案调研

    react 技术栈项目轻量化方案调研 团队的新项目,无论是pc端的还是移动端的,都已全面转移到了 react 的技术栈. 然而,对移动端来说,react 框架脚本的体量还是有些偏大. 在后续项目比较成 ...

  7. 实战react技术栈+express前后端博客项目(8)-- 前端管理界面标签管理+后端对应接口开发...

    项目地址:https://github.com/Nealyang/R... 本想等项目做完再连载一波系列博客,随着开发的进行,也是的确遇到了不少坑,请教了不少人.遂想,何不一边记录踩坑,一边分享收获呢 ...

  8. 深入react技术栈(12):组件内通信

    我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注前端小歌谣获取前后端知识 父组件向子组件传值 子组件向父组件传值 跨级组件通信 没有嵌套关系的组件通信 文章参考深入React技术栈

  9. 深入react技术栈(10):受控组件和非受控组件

    我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注前端小歌谣 受控组件 非受控组件 受控组件和非受控组件的区别 文章参考深入React技术栈

最新文章

  1. ESP8266 wifi干扰、钓鱼实现
  2. python实时连接oracle_Python连接Oracle
  3. Bootstrap分页
  4. 河北大学计算机专业调剂,【计算机考研调剂】河北大学2021级硕士研究生预调剂信息统计的通知...
  5. 【codevs2333】【BZOJ2002】弹飞绵羊,第一次的LCT
  6. thinkphp多语言设置
  7. 8102年底如何开发和维护一个npm项目
  8. df 查看显示所有磁盘的信息
  9. html怎么做实心圆,html5如何使用canvas画空心圆与实心圆
  10. win10计算机还原点如何创建,win10系统创建还原点及系统还原的操作方法
  11. android6.0原生壁纸,安卓6.0原生壁纸 androidM6.0自带高清壁纸下载
  12. Android产品研发(二十一)--Android中的UI优化
  13. Ceph 命令 pool image 纠删
  14. python随机生成英文字母_在Python中生成随机字母
  15. LCA(倍增+Tarjan)和BFS、DFS以及Prim、Kruskal
  16. FreeFEM++根据给定网格尺寸剖分网格
  17. 值得关注的IT技术博客
  18. 输出月份英文名java_输出月份英文名 (30 分)
  19. `算法竞赛题解` LeetCode.6115 统计理想数组的数目
  20. 皮卡丘靶场的搭建以及SQL注入攻击(加强版)

热门文章

  1. 科学家从脑电图中解读大脑的运动意图
  2. “纹身贴皮电路“:未来在皮肤上画个电路就能监测身体健康状况
  3. oculus rift 开发入门
  4. iPhone拍人像,人头直接不见了,什么情况?
  5. 谷歌又孵化出黑科技项目!押注工业机器人方向,上海交大校友参与
  6. 发明复制粘贴的那个人去世了
  7. 滴滴AI负责人叶杰平:你的每一次出行,都已有AI落地的助力 | MEET 2020
  8. 表情包界泥石流:原本是用在人脸上的AI,拿去给Emoji提升分辨率,结果哈哈哈哈哈...
  9. matplotlib 入门之Image tutorial
  10. centos7 gitlab安装