前言

  前几天做了一个项目:【node】记录项目的开始与完成——pipeline_kafka流式数据库管理项目;因为开发时间紧迫,浅略的使用了一下react,感觉这个ui库非常的符合我的口味,现在趁着有空闲时间,将项目前端重构一番。这里面存在一些坑,都是深不见底的水坑,说多了都是泪水。。。好在顺利完成,现在在这里再一步一步重来一遍,和需要学习webpack的前端童鞋分享。

准备

tips:文章最后可下载demo

一:目录

  

  首先我们要新建目录,

  

  新建app文件夹,它存放入口文件,component组件,

  新建static文件夹存放打包后的文件,

  新建webpack文件夹,存放的webpack配置文件。

二、生成package.json

  在当前目录打开cmd或者PowerShell或者终端,

  

  输入npm init 然后一直回车到执行完毕,package.json就滚到文件夹根目录下面了

、安装webpack

  shell输入 npm i webpack -g 安装webpack

  

  我成功后的提示是这样的。

四、新建文件

  在目录app中新建main.js,

  在目录webpack中新建webpack的配置文件  webpack.config.js

  在目录static中新建一个  index.html

  在目录static中新建一个js目录

五、初步配置

  首先写一下 /static/index.html这个文件,因为生成的文件目录在 /static/js文件夹里面,所以这里要预先引用打包后的文件,最后访问这个html文件就可以看到效果

  

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><title>webpack_Demo</title></head><body><div class="content"></div><script src="./js/app.js" type="text/javascript" charset="utf-8"></script></body>
</html>

  然后配置webpack.config.js:

  刚开始我们就配一个简单的入口和输出目录就可以了: 

var path = require("path");module.exports = {entry:{  //入口文件"app":path.join(__dirname,"../app/main.js")  //app对应生成的文件名},output:{path:path.join(__dirname,"../static/js/"),filename:"[name].js"   //这里[name]就是表示对应entry对象的name,然后生成的后戳是.js}
}

 现在我们就可以简单的测试一下,在/app/main.js中随意写一些代码 ,比如alert(1)。

  在shell中调用webpack测试,运行:

  webpack --config ./webpack/webpack.config.js

  

  成功后访问index.html,查看效果,如果报错,可能是缺少哪个依赖包,安装后重复上面步骤。

  这个时候文件目录就变成了:

   app.js就是打包后生成的文件。

  现在我们要把打包命令放在package.json里,因为每次编译都要运行那么长的命令,太痛苦了。在package.json简单的配置一个script就可以使用npm run xxx运行了,编辑package.json:

  

{"name": "web_pack","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build":"webpack --config ./webpack/webpack.config.js" //添加一个build 值是打包用到的命令},"author": "","license": "ISC","dependencies": {"webpack": "^3.0.0"}
}

现在在shell里运行 npm run build就可以编译了

到这一步,初步的配置就算是完成了,接下来配置一个webpack-dev-server,然后就可以配置react组件,生成项目了

配置webpack-dev-server

  什么是webpack-dev-server?

  它是用来监控文件的修改事件,启动它的时候,会分配一个端口,指向当前的目录,一旦目录下文件被修改,它会通知浏览器自动刷新页面,省去了不断的按f5的烦恼。

  在shell中安装,运行:

  npm i webpack-dev-server --save-dev

  安装成功后,运行:

  node_modules/.bin/webpack-dev-server --config ./webpack/webpack.config.js --port 8089 --open

  --config 是webpack配置文件目录,--port 是运行的端口号

  运行成功会在系统默认浏览器弹出一个窗口,这是一个选择文件夹的界面,我们访问static,就可以访问到index.html了:

  

  这里需要注意的一点是,你还需要将index.html中的app.js引用改成http://localhost:8089/app.js,因为webpack-dev-server加载的是虚拟文件,目录在根目录下,所以需要修改这里。  

<script src="http://localhost:8089/app.js" type="text/javascript" charset="utf-8"></script>

  项目完成后再改成对应的路径。

  修改完成,修改一下main.js中的js代码,再看看浏览器中页面是否改变。webpack-dev-server大致就配置好了,另外附上它的api地址:

  webpack-dev-server

 最后再把命令配置到package.json中

{"name": "web_pack","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "node_modules\.bin\webpack-dev-server --config ./webpack/webpack.config.js --port 8089 --open",  //添加到test中 "build":"webpack --config ./webpack/webpack.config.js"
  },"author": "","license": "ISC","dependencies": {"webpack": "^3.0.0"}
}

现在运行npm run test 就可以开始开发了。

配置react

  到了这一步,我们要开始配置react,首先还是安装依赖包,编译jsx文件需要用到babel、babel-core、babel-loader、babel-preset-es2015、babel-preset-react、还有react自己的react、react-dom。安装他们:

  npm i babel babel-core babel-loader babel-preset-es2015 babel-preset-react react react-dom --save

  安装成功之后,先在main.js写一个demo

  

var React = require("react");
var ReactDOM = require("react-dom");
ReactDOM.render(<div><h1>welcome</h1></div>,document.querySelector(".content"));

  这里一定要用 ReactDOM.render 老的版本react.render会报语法错误。

配置babel-loader

  在webpack.config.js添加babel-loader用来解析jsx和es6的代码:

  

var path = require("path");module.exports = {entry:{"app":path.join(__dirname,"../app/main.js") //入口文件 name对应输出的[name]
    },output:{path:path.join(__dirname,"../static/js/"), //输出路径filename:"[name].js"        //输出app.js
    },module:{loader:[{test:/\.(js|jsx)$/,    //这是配置加载文件的规则 值是正则表达式 这里写的意思是.js .jsx结尾的文件加载loaderloader:"babel-loader",exclude:/node_module/,        //这个目录不需要加载loader
                query:{presets:["react","es2015"]        //加载loader的presets
                }}]}
}

  配置了module下面的loaders。

  然后npm run test 开启服务,测试一下代码是否可以运行。

  顺利的话,这里应该能看到welcome了:

  

  现在的代码结构显然过于简单,下面我们在app文件目录下新建两个目录 component 和 views。

  先在component 文件夹下新建hello.jsx,写一些代码:

import React from "react";class Hello extends React.Component{constructor(props){super(props);this.propTypes = {text:React.PropTypes.string}}render(){return <div className="hello">hello <span>{this.props.text}</span></div>}
}
module.exports = Hello;

  一般我的import 语法用来表示react组件或其他资源的引入,require语法用来表示js的引入,另外这里用的是es6的class语法。关于es6,在文章下面有浅略说明。

  然后再views新建index.jsx,这里可以写主要的页面代码:

import React from 'react';
import Hello from "../component/hello.jsx"; //引入hello组件class Index extends React.Component{render(){return <div className="index_container"><Hello text="world"></Hello></div>}
}module.exports = Index;

 最后main.js引入index,把index加入rander就可以看到效果了:

var React = require("react");
var ReactDOM = require("react-dom");import Index from "./views/index.jsx"; //引入index
ReactDOM.render(<div><Index></Index>  //插入index视图</div>,document.querySelector(".content"));

查看效果:

到了这一步,基本的视图结构就完成了,接下来配置css的加载,基本和react的方式一样,加载对应的loader,解析对应的文件。

配置css:

  视图解决了,现在我们要解决css的引入问题,这里可以选择的就比较多 css、sass、less等都可以,我选择的是css,因为我的sass文件可以使用ruby的sass编译,在编辑保存时已经自动编译成css了,个人觉得这样管理起来更加方便。

  首先还是安装依赖,运行:

  npm i css-loader file-loader style-loader url-loader --save-dev

  file-loader url-loader 是用来编译图片资源的,它会将url()中的静态资源打包编译成base64格式,这里需要注意,不要在css中写找不到文件的路径,否则会报错编译失败。

  安装完成后配置css-loader:

  

var path = require("path");module.exports = {entry:{"app":path.join(__dirname,"../app/main.js") //入口文件 name对应输出的[name]
    },output:{path:path.join(__dirname,"../static/js/"), //输出路径filename:"[name].js"        //输出app.js
    },module:{loaders:[{test:/\.(js|jsx)$/,    //这是配置加载文件的规则 值是正则表达式 这里写的意思是.js .jsx结尾的文件加载loaderloader:"babel-loader",exclude:/node_module/,        //这个目录不需要加载loader
                query:{presets:["react","es2015"]        //加载loader的presets
                }},{test:/\.css$/, //配置.css后戳的解析loader:"style-loader!css-loader"},       {         test:/\.(png|jpg)$/, //配置静态文件解析         loader:"url-loader?limit=8192"       }]}
}

注意style-loader必须写在css-loader前面,否则就会报错

  配置完成,在hello.jsx引入个css瞧瞧(这里要重启一下test):

  

引入的方法是

import "./hello.css";

引入成功,这样css就可以使用了

项目结构

  到目前为止 项目的结构是这样的:

  

  app中存放 组件(component)、视图(views)、入口文件 。

  static中存放打包后的项目文件。

  webpack中存放webpack的配置文件

  建议将公共组件打包,比如建一个hello文件夹,里面存放hello.jsx和hello.css以及需要的插件、文档,这样它的多项目复用将变得非常方便,拷贝文件即可。

浅谈es6以及react中的小坑

  es6的class关键字看起来很性感,实际上也只是整了个容,感觉内在变化不多。与createClass差别不是很大,在react中每次生命组件都要继承React.Component。

  比如上面的hello.jsx:

constructor(props){super(props);this.propTypes = {text:React.PropTypes.string}}

  这是构造函数,就是new xxx()调用的那个函数,这里为啥要super? 这是个奇怪的写法,原因是因为构造函数中访问不到this,需要调用super()才能顺利访问到this,这里个人尤为不解,虽然理解起来也不难,构造函数属于static方法,这里为啥不能和java一样的逻辑,构造函数只能访问类?

   this.propTypes  

   这个属性标明了组件中所有用到的props 并且能验证传入的值的正确性,感觉组件有它非常有必要,建议写props不要少了这个属性。

 react 中this的坑

  在hello.jsx组件上添加一个click事件,在事件中打印this:

class Hello extends React.Component{constructor(props){super(props);this.propTypes = {text:React.PropTypes.string}}render(){return <div className="hello" onClick={this.print}>hello <span>{this.props.text}</span></div>}print(){console.log("点击事件");console.log(this);}
}

   会发现this的值既不是点击dom也不是class而是null:

  

  可是如果在静态文件中写React.createClass则不会出现null。

  我的解决办法是在render中强制指定this为class: 

render(){this.print = this.print.bind(this);//绑定this到函数return <div className="hello" onClick={this.print}>hello <span>{this.props.text}</span></div>}

查看官方文档解释是:

React.createClass有一个内置的魔术功能,可以自动绑定所有方法this。这对于在其他类中不用于此功能的JavaScript开发人员来说可能会有点混乱,或者当从React转到其他类时可能会令人困惑。因此,我们决定不将此内置到React的类模型中。如果需要,您仍然可以在构造函数中明确地预处理方法。
在遇到点击更改state时,一定会用到this。要注意this的指向问题

总结

  前端就像是一只正当壮年的母鸡,今天下个蛋,明天下个蛋,是寡蛋是好蛋不知道,今天的蛋和明天的蛋尝起来味道也差不多。我们就像是饲养员,负责给母鸡送吃的,下了蛋就要马上负责收,否则要么就烂了、要么就孵出小鸡吃不了鸡蛋了。

  那些层出不穷的框架,坏掉的框架、已经变的强大就很难驾驭的框架,这对前端来说是一个考验。

相关资源

  下载我最终做好的demo

  react文档翻译(快速入门)

webpack2中文文档
转载请注明出处(完)

转载于:https://www.cnblogs.com/ztfjs/p/webpack.html

【前端】一步一步使用webpack+react+scss脚手架重构项目相关推荐

  1. 手挽手带你学React:四档(上)一步一步学会react-redux (自己写个Redux)

    手挽手带你学React入门四档,用人话教你react-redux,理解redux架构,以及运用在react中.学完这一章,你就可以开始自己的react项目了. 之前在思否看到过某个大神的redux搭建 ...

  2. webpack+react+es6开发模式

    一.前言 实习了两个月,把在公司用到的前端开发模式做个简单的整理.公司里前端开发模式webpack+react+redux+es6,这里去掉了redux. webpack, react, redux等 ...

  3. 从零开始一个webpack+react项目

    从零开始一个webpack+react项目 最近在做react组件化的分享,从项目中抽离组件,那么第一步自然是搭建相关的环境 本篇旨在从零开始,用最少的配置.最少的代码.最少的依赖来搭建一个最简单的w ...

  4. 基于 Webpack 3 的 React 工程项目脚手架

    基于 Webpack 3 的 React 工程项目脚手架从属于笔者的 Web 前端入门与工程实践,算来已经是笔者 React 技术栈脚手架的第四个迭代版本.更多关于 React 或者前端开发相关的资料 ...

  5. SpringBoot+MyBatisPlus+ElementUI一步一步搭建前后端分离的项目(附代码下载)

    场景 一步一步教你在IEDA中快速搭建SpringBoot项目: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/87688277 ...

  6. button active 跳转到另一个页面_一步一步实现一个古诗词网站(四)——首页

    汪小黑:一步一步实现一个古诗词网站(三)--首页​zhuanlan.zhihu.com 在上篇文章中,我们一步一步的实现了我们的静态首页,从中学习到了页面布局方面的知识. 在这篇文章中,我们将使用 J ...

  7. 【Linux】一步一步学Linux——dpkg-preconfigure命令(275)

    00. 目录 文章目录 00. 目录 01. 命令概述 02. 命令格式 03. 常用选项 04. 参考示例 05. 附录 01. 命令概述 dpkg-preconfigure命令用于在Debian ...

  8. 【Linux】一步一步学Linux——dpkg-reconfigure命令(272)

    00. 目录 文章目录 00. 目录 01. 命令概述 02. 命令格式 03. 常用选项 04. 参考示例 05. 附录 01. 命令概述 dpkg-reconfigure命令是Debian lin ...

  9. 【Linux】一步一步学Linux——indent命令(262)

    00. 目录 文章目录 00. 目录 01. 命令概述 02. 命令格式 03. 常用选项 04. 参考示例 05. 附录 01. 命令概述 indent命令可识别C语言代码文件,并加以格式化,以方便 ...

  10. 【Linux】一步一步学Linux——gcc命令(249)

    00. 目录 文章目录 00. 目录 01. 命令概述 02. 命令格式 03. 常用选项 04. 参考示例 05. 附录 01. 命令概述 gcc命令使用GNU推出的基于C/C++的编译器,是开放源 ...

最新文章

  1. Hinton等人新研究:如何更好地测量神经网络表示相似性
  2. Google联手Facebook 要在AI研究上搞什么大事?
  3. android浮动文本,android – 如何将文本添加到浮动操作按钮?
  4. Python学习笔记:偏函数
  5. mysql myisam存储引擎不能添加外键,添加后显示成功,实则失败
  6. mac os mysql 命令_Mac环境下MySQL的安装和基本命令的使用
  7. C++ share_prt 简单设计和实现
  8. pcie 的function_PCIe扫盲——BDF与配置空间
  9. [开发技巧3]不显示报表直接打印
  10. 扩展吉日嘎拉的用户角色管理,让用户角色编码和名称在一个组织里面唯一
  11. JeeWx捷微管家系统
  12. 让AngularJS兼容IE8及其以下浏览器版本的方法
  13. 非线性方程的数值解法:二分法的MATLAB实现
  14. nanomsg的协议
  15. Cypress使用教程
  16. 霍志刚中国科学院计算机,曙光4000系列高性能计算机研究集体
  17. 使用JDBC的基本步骤
  18. 可以降低汽车气缸里面的机油由于摩擦产生的蓝烟的机油添加剂
  19. AspectJ简单实现
  20. linux的LCD的驱动编写

热门文章

  1. Windows消息前缀
  2. CSS图片文字排版01
  3. 日志:实现微信公众号自动问答机器人(待整理)
  4. yaahp使用教程_结合层次分析法和模糊综合评价法的评价方法-利用yaahp
  5. wps页眉怎么设置不同页码_wps页眉的页码和页脚的页码不同怎么设置?
  6. quartz 每月一次_Quartz 每月1号,执行规则表达式怎么列?
  7. 计算机组成原理实验二八位寄存器,计算机组成原理课后参考答案
  8. Hadoop单机版安装
  9. 光纤通道交换机的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  10. RV32G下lui/auipc和addi结合加载立即数时的补值问题