React+Webpack快速上手指南(小结)


Posted in Javascript onAugust 15, 2018

前言

这篇文章不是有关React和Webpack的教程,只是一篇能够让你快速上手使用目前这两种热门技术的前端指南,并假设你对两者有一个基本的认识。如果你想先行了解下React,可以放肆的移步至 React官方教程,如果你已经使用了其他的模块加载与资源打包技术,不妨也来看看 Webpack 提供的思路。

webstorm+react+webpack

强烈推荐使用webstorm!。(当然你完全可以使用诸如atom,Sublime之类的编辑器,但之所以选择webstorm是因为它默认支持对react JSX 的语法高亮以及可以手动开启Emmet对jsx的支持,棒棒哒~)

首先请这么组织你的项目结构:

--your project
 |--app
 |--components
  |--productBox.jsx
 |--main.js
 |--build
 |--index.html
 |--bundle.js(该文件是webpack打包后生成的)

用npm安装react、webpack

默认已经安装了nodejs,并输入:npm init根据提示输入内容并创建package.json文件

然后依次输入:

npm install react --save-dev
npm install webpack --save-dev

安装最新版本的React与Webpack并将它们保存至package.json内的开发依赖项目中。

创建webpack.config.js配置文件

新建一个名为webpack.config.js的文件,它应该长这个样:

var path = require('path');

module.exports = {
 entry: path.resolve(__dirname, './app/main.js'),
 output: {
 path: path.resolve(__dirname, './build'),
 filename: 'bundle.js',
 }
};

其中entry指定了webpack的入口程序,好比c++和java中的main程序一样,我们把最终要插入到页面指定位置的react模板写入main.js中:

app/main.js

var React = require('react');
var AppComponent = require('./components/productBox.js');
React.render(<AppComponent />, document.getElementById('content'));

以及引入的自定义react组件:

app/components/productBox.js

var React = require('react');
var ProductBox = React.createClass({
 render: function () {
 return (
  <div className="productBox">
  Hello World!
  </div>
 );
 }
});

module.exports = ProductBox;

而output则指定了webpack打包成功之后文件名称以及文件的存放位置。

依照之前指定的项目结构,我们可以在index.html中直接引入打包生成的bundle.js,像这样:

build/index.html

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title>React Test</title>
</head>
<body>
 <div id="content"></div>
 <script src="bundle.js"></script>
</body>
</html>

安装并启用webpack-dev-server

webpack-dev-server允许我们可以把本地项目跑在像nginx那样的web服务器上,更重要的是我们可以在package.json文件内定义scripts,同时修改webpack的配置文件来达到类似BrowserSync(即文件修改能被监听,并自动刷新浏览器)的效果!

我们先打开package.json,并找到scripts代码块。在没引入webpack-dev-server之前,我们运行这个项目的姿势是这样的:
修改scripts为

"scripts": {
 "build": "webpack"
}

并且执行:

npm run build

项目就跑起来啦,但是每次修改程序我们都要手动输入npm run build来跑项目,这无疑是一件非常蛋疼的事情。但有了webpack-dev-server光环,我们的姿势应该是这样的:

为scripts添加

"scripts": {
 "build": "webpack",
 "dev": "webpack-dev-server --devtool eval --progress --colors --content-base build"
}

ps:dev里各属性值的意思是:

  1. webpack-dev-server: 在 localhost:8080 建立一个 Web 服务器
  2. --devtool eval:为你的代码创建源地址。当有任何报错的时候可以让你更加精确地定位到文件和行号
  3. --progress: 显示合并代码进度
  4. --colors: 在命令行中显示颜色
  5. --content-base build:指向设置的输出目录

并且在index.html里加入:

build/index.html

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title>React Test</title>
</head>
<body>
 <div id="content"></div>
 <script src="http://localhost:8080/webpack-dev-server.js"></script>
 <script src="bundle.js"></script>
</body>
</html>

在webpack.config.js的入口处加入:

var path = require('path');

module.exports = {
 entry: ['webpack/hot/dev-server', path.resolve(__dirname, './app/main.js')],
 output: {
 path: path.resolve(__dirname, './build'),
 filename: 'bundle.js',
 }
};

以便在进行改动时浏览器可以自动刷新。

最后执行:

npm run dev

你只要在浏览器打开这个地址:http://localhost:8080,webpack-dev-server会为你准备好一切,你只要敲一敲键盘,save一下,所见即所得。

Webpack Loader

讲到这里,我们基本上就可以迅速搭建一个简单的web项目,但不得不提的是webpack loader。它是我个人认为相比于其他模块加载更牛X的地方,将它用于react的开发,结合react与生俱来的优越性能,两者天衣无缝的配合简直就是黄金组合。

总的来说webpack loader可以实现:

  1. 可以将React JSX语法转为js语句
  2. React开发中支持ES6语法
  3. 支持通过import来直接引入css、less、sass甚至是图片
  4. 支持css中引用的图片大小在某一大小范围之内直接转为BASE64格式

。。。。。等等等

为了能够让以上功能奏效,我们要先安装对应的:

babel-loader

npm install babel-loader --save-dev

css-loader

npm install css-loader --save-dev

less-loader

npm install less-loader --save-dev

style-loader

npm install style-loader --save-dev

url-loader

npm install url-loader --save-dev

而具体的实现,我们只要在webpack的配置文件中加入module属性里的loaders:

var path = require('path');

module.exports = {
 entry: ['webpack/hot/dev-server', path.resolve(__dirname, './app/main.js')],
 output: {
 path: path.resolve(__dirname, './build'),
 filename: 'bundle.js',
 },
 module: {
 loaders: [{
  test: /\.jsx?$/,
  loader: 'babel'
 }, {
  test: /\.css$/,
  loader: 'style!css'
 }, {
  test: /\.less$/,
  loader: 'style!css!less'
 },{ 
  test: /\.(png|jpg)$/, 
  loader: 'url?limit=25000' 
 }]
 }
};

通过指定文件后缀来执行对应的loader操作,我们甚至可以轻松的引入其他类型的文件,最后所有被引入进来的文件都会统统打包到bundle.js中去!

开发环境下的优化

在开发React组件的代码中,在webpack的帮助下我们都是通过require(‘react')的方式引入ReactJS,默认的require()方法会在webpack打包的时候去遍历ReactJS及其依赖。试想下,如果我们还引入了其他的库,例如jQuery、react-router、moment等,require都会以同样的方式去遍历,这会大大增加打包的时间。这显然会影响到开发的效率。

为了能够尽可能的加速打包过程,我们应该重写它的行为,鼓励在开发中使用依赖的压缩版本

假如我们只引入了react,我们可以这样修改webpack.config.js:

var path = require('path');
var node_modules = path.resolve(__dirname, 'node_modules');
var pathToReact = path.resolve(node_modules, 'react/dist/react.min.js');

var config = {
 entry: ['webpack/hot/dev-server', path.resolve(__dirname, './app/main.js')],
 resolve: {
 alias: {
  'react': pathToReact
 }
 },
 output: {
 path: path.resolve(__dirname, './build'),
 filename: 'bundle.js'
 },
 module: {
 noParse: [pathToReact],
 loaders: [{
  test: /\.jsx?$/,
  loader: 'babel'
 }, {
  test: /\.css$/,
  loader: 'style!css'
 }, {
  test: /\.less$/,
  loader: 'style!css!less'
 },{ 
  test: /\.(png|jpg)$/, 
  loader: 'url?limit=25000' 
 }]
 }
};

module.exports = config;

resolve属性里的alias用来告诉webpack,当引入react时,试图去匹配压缩过的react;

而module中的noParse则是告诉当webpack尝试去解析压缩文件时,这种行为是不允许的。

当然啦,细心的你可能会发现当引入更多的库时,这样写多少会显得有点冗余,为此下面有个更加优雅的写法:

var path = require('path');
var node_modules_dir = path.join(__dirname, 'node_modules');
var deps = [ 
 'react/dist/react.min.js',
 'react-router/dist/react-router.min.js',
 'moment/min/moment.min.js'
];
var config = {
 entry: ['webpack/hot/dev-server', path.resolve(__dirname, './app/main.js')],
 resolve: {
 alias: {}
 },
 output: {
 path: path.resolve(__dirname, './build'),
 filename: 'bundle.js'
 },
 module: {
 noParse: [],
 loaders: [{
  test: /\.jsx?$/,
  loader: 'babel'
 }, {
  test: /\.css$/,
  loader: 'style!css'
 }, {
  test: /\.less$/,
  loader: 'style!css!less'
 },{ 
  test: /\.(png|jpg)$/, 
  loader: 'url?limit=25000' 
 }]
 }
};

deps.forEach(function (dep) {
 var depPath = path.resolve(node_modules_dir, dep);
 config.resolve.alias[dep.split(path.sep)[0]] = depPath;
 config.module.noParse.push(depPath);
});

module.exports = config;

瞬间biger起来了,待加以修饰之后,让我们更加便捷高效的享受React与Webpack带来的乐趣吧。

相关的代码请狠狠点击这里查看,自行体验下哈

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
一个加密JavaScript的开源工具PACKER2.0.2
Nov 04 Javascript
利用onresize使得div可以随着屏幕大小而自适应的代码
Jan 15 Javascript
jQuery源码分析之Event事件分析
Jun 07 Javascript
javascript setAttribute, getAttribute 在不同浏览器上的不同表现
Aug 05 Javascript
js单独获取一个checkbox看其是否被选中
Sep 22 Javascript
Bootstrap每天必学之导航
Nov 26 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(二)
Sep 14 Javascript
JS实现重新加载当前页面或者父页面的几种方法
Nov 30 Javascript
js实现下拉框二级联动
Dec 04 Javascript
vue 弹窗时 监听手机返回键关闭弹窗功能(页面不跳转)
May 10 Javascript
微信小程序实现拖拽功能
Sep 26 Javascript
JS+CSS实现炫酷光感效果
Sep 05 Javascript
layui从数据库中获取复选框的值并默认选中方法
Aug 15 #Javascript
关于微信小程序bug记录与解决方法
Aug 15 #Javascript
layui select获取自定义属性方法
Aug 15 #Javascript
Vue自定义toast组件的实例代码
Aug 15 #Javascript
JavaScript中set与get方法用法示例
Aug 15 #Javascript
基于JavaScript实现瀑布流布局
Aug 15 #Javascript
解决Layui 表单提交数据为空的问题
Aug 15 #Javascript
You might like
php连接mysql数据库代码
2009/03/10 PHP
PHP中对各种加密算法、Hash算法的速度测试对比代码
2014/07/08 PHP
PHP 9 大缓存技术总结
2015/09/17 PHP
PHP加密解密实例分析
2015/12/25 PHP
PHP+jQuery实现滚屏无刷新动态加载数据功能详解
2017/05/04 PHP
JavaScript 关键字屏蔽实现函数
2009/08/02 Javascript
学习ExtJS border布局
2009/10/08 Javascript
PHP 与 js的通信(via ajax,json)
2010/11/16 Javascript
javascript学习笔记(五) Array 数组类型介绍
2012/06/19 Javascript
Javascript表格翻页效果实现思路及代码
2013/08/23 Javascript
JS基于myFocus库实现各种功能的tab选项卡切换效果
2015/09/19 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
2017/04/13 Javascript
Javascript中八种遍历方法的执行速度深度对比
2017/04/25 Javascript
bootstrap table sum总数量统计实现方法
2017/10/29 Javascript
vue select二级联动第二级默认选中第一个option值的实例
2018/01/10 Javascript
微信小程序仿微信运动步数排行(交互)
2018/07/13 Javascript
仿iPhone通讯录制作小程序自定义选择组件的实现
2019/05/23 Javascript
angular中的post请求处理示例详解
2020/06/30 Javascript
vue-quill-editor插入图片路径太长问题解决方法
2021/01/08 Vue.js
python 实现文件的递归拷贝实现代码
2012/08/02 Python
Python 冒泡,选择,插入排序使用实例
2015/02/05 Python
Python获取当前公网ip并自动断开宽带连接实例代码
2018/01/12 Python
20行python代码的入门级小游戏的详解
2019/05/05 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
Python使用monkey.patch_all()解决协程阻塞问题
2020/04/15 Python
夏威夷航空官网:Hawaiian Airlines
2016/09/11 全球购物
Nike瑞典官方网站:Nike.com (SE)
2018/11/26 全球购物
BAILEY 44官网:美国制造的女性服装
2019/07/01 全球购物
初中体育教学反思
2014/01/14 职场文书
社区学雷锋活动策划方案
2014/01/30 职场文书
激励口号大全
2014/06/17 职场文书
保险专业求职信
2014/07/07 职场文书
农村文化活动总结
2014/08/28 职场文书
2015年幼儿园卫生保健工作总结
2015/05/12 职场文书
网络研修心得体会
2016/01/08 职场文书
写一个Python脚本自动爬取Bilibili小视频
2021/04/24 Python