react webpack 脚手架external react 时只能使用其全局变量或相对路径怎么办

Webpack 是 OneAPM 前端技术栈中很重要的一部分,它非常好用,如果你还不了解它,建议你阅读这篇,在 OneAPM 我们用它完成静态资源打包,ES6 代码的转换 ,React 组件的组织等,在接下来的日子里,我们将通过一系列文章和业界分享我们在使用 Webpack 过程中关于性能方面的经验。
作为系列文章的第一篇,我们会重点介绍 Webpack 中的 resolve.alias ,也就是请求重定向。不过请注意 Webpack 里的请求是对模块的依赖,也就是一个 require语句,而不是一个 HTTP 请求。
必要的准备
需要你有一定的 Node.js 基础
电脑上装有最新版的 Webpack (npm install webpack -g)
了解 Webpack 配置文件的格式
例子:本地时钟
要实现的功能很简单,就是在页面上用中文显示当前时间,需要用到 moment 这个库,这个库封装了很多和日期相关的函数,而且自带了国际化的支持。
新建一个 Node.js 项目
使用 npm init 初始化你的项目,然后通过npm install moment -D加上 moment 的开发者依赖。
新建一个entry.js作为入口文件,当然你也可以用 app.js 这样的名字,只是大部分的 Webpack 示例都是用的是 entry.js。
var moment = require('moment');
document.write(moment().locale('zh-cn').format('LLLL'));
新建一个页面index.html, 引用 bundle.js:
&h5&当前时间:&/h5&
&script src=&dist/bundle.js&&&/script&
此时的文件目录看起来是这样的:
index.html
package.json
node_modules/moment
到目前为止 bundle.js 这个文件还不存在,不过别着急,接下来的工作就交给 Webpack 来完成。
index.html
------------------------+
package.json
+--& &Clock App&
+--&bundle.js+--+
node_modules/moment-+
如图,Webpack 会把 entry.js 和 moment模块一起打包成一个 bundle.js 文件,和 index.html 一起构成了我们的 Clock App。怎么样,是不是已经听到 Clock App 滴答作响了?
使用 webpack 打包代码
在命令行执行:
webpack --entry ./entry.js --output-path dist --output-file bundle.js
你会看到类似下面的输出结果:
Hash: bfcb30e3ef7
Version: webpack 1.10.0
Time: 650ms
Chunk Names
[0] ./entry.js 125 bytes {0} [built]
+ 86 hidden modules
可以看到,耗时 650ms,这么慢着实让人意外,一定要想办法提高“新一代神器”速度;另一方面,最后一行的 + 86 hidden modules 非常让人怀疑:明明是一个简单的 Clock App,怎么会有这么多的依赖。
如何快速定位 Webpack 速度慢的原因
再一次,在命令行输入:
webpack --entry ./entry.js --output-path dist --output-file bundle.js \
--colors \
--profile \
--display-modules
不过这次新增加了三个参数,这三个参数的含义分别是:
--colors 输出结果带彩色,比如:会用红色显示耗时较长的步骤
--profile输出性能数据,可以看到每一步的耗时
--display-modules默认情况下 node_modules 下的模块会被隐藏,加上这个参数可以显示这些被隐藏的模块
这次命令行的结果已经很有参考价值,可以帮助我们定位耗时比较长的步骤
Hash: bfcb30e3ef7
Version: webpack 1.10.0
Time: 650ms
Chunk Names
[0] ./entry.js 125 bytes {0} [built]
factory:11ms building:8ms = 19ms
[1] ../~/moment/moment.js 102 kB {0} [built]
[0] 19ms -& factory:7ms building:141ms = 167ms
[2] (webpack)/buildin/module.js 251 bytes {0} [built]
[0] 19ms -& [1] 148ms -& factory:132ms building:159ms = 458ms
[3] ../~/moment/locale ^\.\/.*$ 2.01 kB {0} [optional] [built]
[0] 19ms -& [1] 148ms -& factory:6ms building:10ms dependencies:113ms = 296ms
[4] ../~/moment/locale/af.js 2.57 kB {0} [optional] [built]
[0] 19ms -& [1] 148ms -& [3] 16ms -& factory:52ms building:65ms dependencies:138ms =
..... 广告分割线,Node.js 工程师简历请发
[85] ../~/moment/locale/zh-cn.js 4.31 kB {0} [optional] [built]
[0] 22ms -& [1] 162ms -& [3] 18ms -& factory:125ms building:145ms dependencies:22ms
[86] ../~/moment/locale/zh-tw.js 3.07 kB {0} [optional] [built]
[0] 22ms -& [1] 162ms -& [3] 18ms -& factory:126ms building:146ms dependencies:21ms
从命令行的结果里可以看到从 Request[4] 到 Request[86] 都是在解析 moment.js附带的大量本地化文件。所以我们遇到的速度慢的问题其实是由 moment引起的。
如果你想知道为什么 Webpack 会加载这么多的模块,可以参考这篇文章
我们再来看看 entry.js代码的第一行,标准的 CommonJS写法:
var moment = require('moment');
也就是说,请求的是 moment的源码。实际上,通过 NPM 安装moment 的时候会同时安装 moment 的源码和压缩后的代码,试验证明下面这种写法也是可行的:
var moment = require('moment/min/moment-with-locales.min.js');
只不过这样改,可读性会有所下降,而且每一个用到moment 的地方都得这么写。另外,如果同样的问题出现在第三方模块中,修改别人代码就不那么方便了。下面来看看用 Webpack 怎么解决这个问题。
在 Webpack 中使用别名
别名(resolve.alias) 是 Webpack 的一个配置项,它的作用是把用户的一个请求重定向到另一个路径,例如通过修改 webpack.config.js配置文件,加入:
resolve: {
moment: &moment/min/moment-with-locales.min.js&
这样待打包的脚本中的 require('moment'); 其实就等价于 require('moment/min/moment-with-locales.min.js'); 。通过别名的使用在本例中可以减少几乎一半的时间。
Hash: cdeaee0741a
Version: webpack 1.10.0
Time: 320ms
Chunk Names
[0] ./entry.js 125 bytes {0} [built]
factory:11ms building:9ms = 20ms
[1] ../~/moment/min/moment-with-locales.min.js 146 kB {0} [built] [1 warning]
[0] 20ms -& factory:8ms building:263ms = 291ms
[2] (webpack)/buildin/module.js 251 bytes {0} [built]
[0] 20ms -& [1] 271ms -& factory:3ms building:1ms = 295ms
WARNING in ../~/moment/min/moment-with-locales.min.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./locale in
*/webpack_performance/node_modules/moment/min
@ ../~/moment/min/moment-with-locales.min.js 1:
在 Webpack中忽略对已知文件的解析
module.noParse 是 webpack 的另一个很有用的配置项,如果你 确定一个模块中没有其它新的依赖 就可以配置这项,webpack 将不再扫描这个文件中的依赖。
noParse: [/moment-with-locales/]
这样修改,再结合前面重命名的例子,更新后的流程是:
webpack 检查到 entry.js 文件对 moment的请求;
请求被 alias 重定向,转而请求 moment/min/moment-with-locales.min.js;
noParse 规则中的 /moment-with-locales/一条生效,所以 webpack 就直接把依赖打包进了 bundle.js 。
Hash: 38b4ed70b9
Version: webpack 1.10.0
Time: 76ms
Chunk Names
[0] ./entry.js 125 bytes {0} [built]
factory:13ms building:13ms = 26ms
[1] ../~/moment/min/moment-with-locales.min.js 146 kB {0} [built]
[0] 26ms -& factory:13ms building:5ms = 44ms
时间进一步被压缩,只需要 76ms,比前一步还减少了 75%。
在 Webpack 中使用公用 CDN
Webpack 是如此的强大,用其打包的脚本可以运行在多种环境下,Web 环境只是其默认的一种,也是最常用的一种。考虑到 Web 上有很多的公用 CDN 服务,那么 怎么将 Webpack 和公用的 CDN 结合使用呢?方法是使用 externals声明一个外部依赖。
externals: {
moment: true
当然了 HTML 代码里需要加上一行
&script src=&///libs/moment/2.8.3/moment-with-locales.min.js&&&/script&
这次打包,结果只用了 49 ms,几乎达到了极限。
本文结合本地时钟的例子,展示了定位 Webpack 性能问题的步骤,以及所需要的两个参数 :--display-modules
和 --profile。然后,重点介绍了 resolve.alias 即利用别名做重定向的方法和场景,在此基础上,配合module.noParse 忽略某些模块的解析可以进一步加快速度。最后介绍了用 externals 定义外部依赖方法来使用公用 CDN。
本文相关的源码在: /wyvernnot/webpack_performance/tree/master/moment-
本文系工程师原创文章。OneAPM是中国基础软件领域的新兴领军企业,能帮助企业用户和开发者轻松实现:缓慢的程序代码和SQL语句的实时抓取。想阅读更多技术文章,请访问OneAPM。
本文目前还没有评论……webpack external react 时只能使用其全局变量或相对路径怎么办
我想把react作为external lib 从bundle里面分离出来,但是require好像不起作用呢,在配置里起得名字也不好使。只能使用文件的相对路径来require或者干脆不require就行了。可是我想使用cmd模式用require来把它引入怎么办?
//配置如下
var webpack = require('webpack');
var path = require('path');
var config = {
path.resolve(__dirname, 'scripts/main.js')
path: path.resolve(__dirname, 'build'),
libraryTarget: "umd",
library: '',
filename: 'bundle.js'
externals: [
//第一种写法
{"../build/react.min.js": 'React'}
//第二种写法,这货怎么用的有木有大神教一下- -!
{"../build/react.min.js": {
root: 'ReactJS',
commonjs: ["./ReactJS", "ReactJS"],
loaders: [{
exclude: "scripts/react.min.js",
test: /\.js$/,
loaders: ['babel']
'use strict';
//第一种配置,下面这句话写不写都不会报错。
var React = require('../build/react.min.js');
console.log('main' + 1 + 2);
var Main = React.createClass({
getInitialState: function() {
switch: true
_toggle() {
this.setState({
switch: !this.state.switch
render() {
&input type="button" onClick={this._toggle} value="Press Me!"/&
React.render(&Main /&, document.body);
//webpack.config.js
module.exports = {
externals: {
'react': 'React'
externals对象的key是给require时用的,比如require('react'),对象的value表示的是如何在global(即window)中访问到该对象,这里是window.React。
同理jquery的话就可以这样写:'jquery': 'jQuery',那么require('jquery')即可。
HTML中注意引入顺序即可:
&script src="react.min.js" /&
&script src="bundle.js" /&
我是这样写的
javascript//webpack.config.js
module.exports = {
externals: {
'react': 'window.React'
var React = require('react');
//home.html
&script src='../build/react.min.js' type="text/javascript"&&/script&
> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!
网时只能打开一个IE窗口..不能打开第二个..怎样解决这个问题? 下载注册表修复软件或反间谍软件查杀是否有病毒.木马 也可以这样: 修复IE注册.从开始-&运行 输入命令 regsvr32 actxprxy.dll 确定 输入命令 regsvr32 shdocvw.dll 确定,重启
问题描述: 关于oc和swift混编 框架framework时 只能在真机运行或只能在模拟器单独运行的解决方案. 问题提供者:by 走跑 解决方案: 首先制作swift版本的framework(Cocoa Touch Framework)取名FirstMixed 1. 工程里面新建一个SwiftView.swift文件,继承UIView,class必须是pu ...
解决firefox3.0,ie8 在上传文件时只能获得文件名,而不能获得文件路径的问题:
我们的目的是要获取到文件的全路径,包括文件地址和文件名.下面我们以(struts 1.x)为例讲解---------------------------------------------------------------------------------- ...
&/pre&&pre code_snippet_id=&430174& snippet_file_name=&blog__4634982& name=&code& class=&csharp&&&/pre&&pre c ...
转自:http://blog.csdn.net/rlj021/archive//3530939.aspx一.头文件
gcc 在编译时寻找所需要的头文件 :
※搜寻会从-I开始
※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
※再找内定目录/usr/i ...
gcc 在编译时寻找所需要的头文件 :
※搜寻会从-I开始(gcc 参数,指定头文件搜索位置)
※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
※再找内定目录 /usr/include
/usr/local/include /usr/li ...
gcc 在编译时寻找所需要的头文件 :
※搜寻会从-I开始
※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
※再找内定目录/usr/include
/usr/local/include/usr/lib/gcc-lib/i386-linux/2.95.2/i ...
一.头文件 gcc 在编译时寻找所需要的头文件 :※搜寻会从-I开始※然后找gcc的环境变量C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH ※再找内定目录/usr/include
/usr/local/include/usr/lib/gcc-lib/i386-linux/2.95.2/include/ ...React-Todos入门例子 – 热前端深入浅出React(二):React开发神器Webpack-java-火龙果软件工程
&&&&您可以捐助,支持我们的公益事业。
每天15篇文章
不仅获得谋生技能
更可以追随信仰
深入浅出React(二):React开发神器Webpack
作者:王沛 来源:InfoQ
1083 次浏览
&&&&评价:
上一篇我们对React有了一个总体的认识,在介绍其中的技术细节之前,我们首先来了解一下用于React开发和模块管理的主流工具Webpack。称之为React开发神器有点标题党了,不过Webpack确实是笔者见过的功能最为强大的前端模块管理和打包工具。虽然Webpack是一个通用的工具,并不只适合于React,但是很多React的文章或者项目都使用了Webpack,尤其是react-hot-loader这样的神器存在,让Webpack成为最主流的React开发工具。
CommonJS和AMD是用于JavaScript模块管理的两大规范,前者定义的是模块的同步加载,主要用于NodeJS;而后者则是异步加载,通过requirejs等工具适用于前端。随着npm成为主流的JavaScript组件发布平台,越来越多的前端项目也依赖于npm上的项目,或者自身就会发布到npm平台。因此,让前端项目更方便的使用npm上的资源成为一大需求。于是诞生了类似browserify这样的工具,代码中可以使用require函数直接以同步语法形式引入npm模块,打包后再由浏览器执行。
Webpack其实有点类似browserify,出自Facebook的Instagram团队,但功能比browserify更为强大。其主要特性如下:
同时支持CommonJS和AMD模块(对于新项目,推荐直接使用CommonJS);
串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、ES6的支持;
可以基于配置或者智能分析打包成多个文件,实现公共模块或者按需加载;
支持对CSS,图片等资源进行打包,从而无需借助Grunt或Gulp;
开发时在内存中完成打包,性能更快,完全可以支持开发过程的实时打包需求;
对sourcemap有很好的支持,易于调试。
Webpack将项目中用到的一切静态资源都视之为模块,模块之间可以互相依赖。Webpack对它们进行统一的管理以及打包发布,其官方主页用下面这张图来说明Webpack的作用:
可以看到Webpack的目标就是对项目中的静态资源进行统一管理,为产品的最终发布提供最优的打包部署方案。本文就将围绕React对其相关用法做一个总体介绍,从而能让你将其应用在自己的实际项目之中。
安装Webpack,并加载一个简单的React组件Webpack一般作为全局的npm模块安装:
npm install -g webpack
之后便有了全局的webpack命令,直接执行此命令会默认使用当前目录的webpack.config.js作为配置文件。如果要指定另外的配置文件,可以执行:
webpack ―config webpack.custom.config.js
尽管Webpack可以通过命令行来指定参数,但我们通常会将所有相关参数定义在配置文件中。一般我们会定义两个配置文件,一个用于开发时,另外一个用于产品发布。生产环境下的打包文件不需要包含sourcemap等用于开发时的代码。配置文件通常放在项目根目录之下,其本身也是一个标准的CommonJS模块。
一个最简单的Webpack配置文件webpack.config.js如下所示:
module.exports = {
'./app/main.js'
path: __dirname + '/assets/',
publicPath: &/assets/&,
filename: 'bundle.js'
其中entry参数定义了打包后的入口文件,数组中的所有文件会按顺序打包。每个文件进行依赖的递归查找,直到所有相关模块都被打包。output参数定义了输出文件的位置,其中常用的参数包括:
path: 打包文件存放的绝对路径
publicPath: 网站运行时的访问路径
filename: 打包后的文件名
现在来看如何打包一个React组件。假设有如下项目文件夹结构:
- react-sample
index.html
webpack.config.js
其中Hello.js定义了一个简单的React组件,使用ES6语法:
var React = require('react');class Hello ponent {
render() {
&h1&Hello {this.props.name}!&/h1&
entry.js是入口文件,将一个Hello组件输出到界面:
var React = require('react');var Hello = require('./Hello');React.render(&Hello name=&Nate& /&, document.body);
index.html的内容如下:
&html&&head&&/head&&body&&script src=&/assets/bundle.js&&&/script&&/body&&/html&
在这里Hello.js和entry.js都是JSX组件语法,需要对它们进行预处理,这就要引入webpack的JSX加载器。因此在配置文件中加入如下配置:
loaders: [
{ test: /\.jsx?$/, loaders: ['jsx?harmony']}
加载器的概念稍后还会详细介绍,这里只需要知道它能将JSX编译成JavaScript并加载为Webpack模块。这样在当前目录执行webpack命令之后,在assets目录将生成bundle.js,打包了entry.js的内容。当浏览器打开当前服务器上的index.html,将显示“Hello
Nate!”。这是一个非常简单的例子,演示了如何使用Webpack来进行最简单的React组件打包。
加载AMD或CommonJS模块在实际项目中,代码以模块进行组织,AMD是在CommonJS的基础上考虑了浏览器的异步加载特性而产生的,可以让模块异步加载并保证执行顺序。而CommonJS的require函数则是同步加载。在Webpack中笔者更加推荐CommonJS方式去加载模块,这种方式语法更加简洁直观。即使在开发时,我们也是加载Webpack打包后的文件,通过sourcemap去进行调试。
除了项目本身的模块,我们也需要依赖第三方的模块,现在比较常用的第三方模块基本都通过npm进行发布,使用它们已经无需单独下载管理,需要时执行npm
install即可。例如,我们需要依赖jQuery,只需执行:
npm install jquery ―save-dev
更多情况下我们是在项目的package.json中进行依赖管理,然后通过直接执行npm
install来安装所有依赖。这样在项目的代码仓库中并不需要存储实际的第三方依赖库的代码。
安装之后,在需要使用jquery的模块中需要在头部进行引入:
var $ = require('jquery');$('body').html('Hello Webpack!');
可以看到,这种以CommonJS的同步形式去引入其它模块的方式代码更加简洁。浏览器并不会实际的去同步加载这个模块,require的处理是由Webpack进行解析和打包的,浏览器只需要执行打包后的代码。Webpack自身已经可以完全处理JavaScript模块的加载,但是对于React中的JSX语法,这就需要使用Webpack的扩展加载器来处理了。
Webpack开发服务器除了提供模块打包功能,Webpack还提供了一个基于Node.js
Express框架的开发服务器,它是一个静态资源Web服务器,对于简单静态页面或者仅依赖于独立服务的前端页面,都可以直接使用这个开发服务器进行开发。在开发过程中,开发服务器会监听每一个文件的变化,进行实时打包,并且可以推送通知前端页面代码发生了变化,从而可以实现页面的自动刷新。
Webpack开发服务器需要单独安装,同样是通过npm进行:
npm install -g webpack-dev-server
之后便可以运行webpack-dev-server命令来启动开发服务器,然后通过localhost:8080/webpack-dev-server/访问到页面了。默认情况下服务器以当前目录作为服务器目录。在React开发中,我们通常会结合react-hot-loader来使用开发服务器,因此这里不做太多介绍,只需要知道有这样一个开发服务器可以用于开发时的内容实时打包和推送。详细配置和用法可以参考官方文档。
Webpack模块加载器(Loaders)Webpack将所有静态资源都认为是模块,比如JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,图片等等,从而可以对其进行统一管理。为此Webpack引入了加载器的概念,除了纯JavaScript之外,每一种资源都可以通过对应的加载器处理成模块。和大多数包管理器不一样的是,Webpack的加载器之间可以进行串联,一个加载器的输出可以成为另一个加载器的输入。比如LESS文件先通过less-load处理成css,然后再通过css-loader加载成css模块,最后由style-loader加载器对其做最后的处理,从而运行时可以通过style标签将其应用到最终的浏览器环境。
对于React的JSX也是如此,它通过jsx-loader来载入。jsx-loader专门用于载入React的JSX文件,Webpack的加载器支持参数,jsx-loader就可以添加?harmony参数使其支持ES6语法。为了让Webpack识别什么样的资源应该用什么加载器去载入,需要在配置文件进行配置:通过正则表达式对文件名进行匹配。例如:
preLoaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'jsxhint'
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'react-hot!jsx-loader?harmony'
test: /\.less/,
loader: 'style-loader!css-loader!less-loader'
test: /\.(css)$/,
loader: 'style-loader!css-loader'
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=8192'
可以看到,该使用什么加载器完全取决于这里的配置,即使对于JSX文件,我们也可以用js作为后缀,从而所有的JavaScript都可以通过jsx-loader载入,因为jsx本身就是完全兼容JavaScript的,所以即使没有JSX语法,普通JavaScript模块也可以使用jsx-loader来载入。
加载器之间的级联是通过感叹号来连接,例如对于LESS资源,写法为style-loader!css-loader!less-loader。对于小型的图片资源,也可以将其进行统一打包,由url-loader实现,代码中url-loader?limit=8192含义就是对于所有小于8192字节的图片资源也进行打包。这在一定程度上可以替代Css
Sprites方案,用于减少对于小图片资源的HTTP请求数量。
除了已有加载器,你也可以自己实现自己的加载器,从而可以让Webpack统一管理项目特定的静态资源。现在也已经有很多第三方的加载器实现常见静态资源的打包管理,可以参考Webpack主页上的加载器列表。
React开发神器:react-hot-loaderWebpack本身具有运行时模块替换功能,称之为Hot
Module Replacement (HMR)。当某个模块代码发生变化时,Webpack实时打包将其推送到页面并进行替换,从而无需刷新页面就实现代码替换。这个过程相对比较复杂,需要进行多方面考虑和配置。而现在针对React出现了一个第三方react-hot-loader加载器,使用这个加载器就可以轻松实现React组件的热替换,非常方便。其实正是因为React的每一次更新都是全局刷新的虚拟DOM机制,让React组件的热替换可以成为通用的加载器,从而极大提高开发效率。
要使用react-hot-loader,首先通过npm进行安装:
npm install ―save-dev react-hot-loader
之后,Webpack开发服务器需要开启HMR参数hot,为了方便,我们创建一个名为server.js的文件用以启动Webpack开发服务器:
var webpack = require('webpack');var WebpackDevServer = require('webpack-dev-server');var config = require('../webpack.config');new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
noInfo: false,
historyApiFallback: true}).listen(3000, '127.0.0.1', function (err, result) {
if (err) {
console.log(err);
console.log('Listening at localhost:3000');});
为了热加载React组件,我们需要在前端页面中加入相应的代码,用以接收Webpack推送过来的代码模块,进而可以通知所有相关React组件进行重新Render。加入这个代码很简单:
'webpack-dev-server/client?http://127.0.0.1:3000', // WebpackDevServer host and port
'webpack/hot/only-dev-server',
'./scripts/entry' // Your app?s entry point]
需要注意的是,这里的client?http://127.0.0.1:3000需要和在server.js中启动Webpack开发服务器的地址匹配。这样,打包生成的文件就知道该从哪里去获取动态的代码更新。下一步,我们需要让Webpack用react-hot-loader去加载React组件,如上一节所介绍,这通过加载器配置完成:
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'react-hot!jsx-loader?harmony'
做完这些配置之后,使用Node.js运行server.js:
node server.js
即可启动开发服务器并实现React组件的热加载。为了方便,我们也可以在package.json中加入一节配置:
&scripts&: {
&start&: &node ./js/server.js&}
从而通过npm start命令即可启动开发服务器。示例代码也上传在Github上,大家可以参考。
这样,React的热加载开发环境即配置完成,任何修改只要以保存,就会在页面上立刻体现出来。无论是对样式修改,还是对界面渲染的修改,甚至事件绑定处理函数的修改,都可以立刻生效,不得不说是提高开发效率的神器。
将Webpack开发服务器集成到已有服务器尽管Webpack开发服务器可以直接用于开发,但实际项目中我们可能必须使用自己的Web服务器。这就需要我们能将Webpack的服务集成到已有服务器,来使用Webpack提供的模块打包和加载功能。要实现这一点其实非常容易,只需要在载入打包文件时指定完整的URL地址,例如:
&script src=&http://127.0.0.1:3000/assets/bundle.js&&&/script&
这就告诉当前页面应该去另外一个服务器获得脚本资源文件,在之前我们已经在配置文件中指定了开发服务器的地址,因此打包后的文件也知道应该通过哪个地址去建立Socket
IO来动态加载模块。整个资源架构如下图所示:
打包成多个资源文件将项目中的模块打包成多个资源文件有两个目的:
将多个页面的公用模块独立打包,从而可以利用浏览器缓存机制来提高页面加载效率;
减少页面初次加载时间,只有当某功能被用到时,才去动态的加载。
Webpack提供了非常强大的功能让你能够灵活的对打包方案进行配置。首先来看如何创建多个入口文件:
entry: { a: &./a&, b: &./b& },
output: { filename: &[name].js& },
plugins: [ monsChunkPlugin(&init.js&) ]}
可以看到,配置文件中定义了两个打包资源“a”和“b”,在输出文件中使用方括号来获得输出文件名。而在插件设置中使用了CommonsChunkPlugin,Webpack中将打包后的文件都称之为“Chunk”。这个插件可以将多个打包后的资源中的公共部分打包成单独的文件,这里指定公共文件输出为“init.js”。这样我们就获得了三个打包后的文件,在html页面中可以这样引用:
&script src=&init.js&&&/script&&script src=&a.js&&&/script&&script src=&b.js&&&/script&
除了在配置文件中对打包文件进行配置,还可以在代码中进行定义:require.ensure,例如:
require.ensure([&module-a&, &module-b&], function(require) {
var a = require(&module-a&);
Webpack在编译时会扫描到这样的代码,并对依赖模块进行自动打包,运行过程中执行到这段代码时会自动找到打包后的文件进行按需加载。
小结本文结合React介绍了Webpack的基本功能和用法,希望能让大家对这个新兴而强大的模块管理工具有一个总体的认识,并能将其应用在实际的项目开发中。笔者也将其应用在之前提供的React示例组件项目中,大家可以参考。除了这里介绍的功能,Webpack还有许多强大的特性,例如插件机制、支持动态表达式的require、打包文件的智能重组、性能优化、代码混淆等等。限于篇幅不再一一介绍,其官方文档也非常完善,需要时可以参考。
更多课程...&&&
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
|&京ICP备号&京公海网安备号

我要回帖

更多关于 react redux webpack 的文章

 

随机推荐