├── .gitignore
├── README.md
├── demo01
├── index.html
├── main.js
└── webpack.config.js
├── demo02
├── index.html
├── main.jsx
└── webpack.config.js
├── demo03
├── app.css
├── index.html
├── main.js
└── webpack.config.js
├── demo04
├── big.png
├── index.html
├── main.js
├── small.png
└── webpack.config.js
├── demo05
├── app.css
├── index.html
├── main.jsx
└── webpack.config.js
├── demo06
├── index.html
├── main.js
└── webpack.config.js
├── demo07
├── main.js
└── webpack.config.js
├── demo08
├── index.html
├── main.js
└── webpack.config.js
├── demo09
├── index.html
├── main.js
└── webpack.config.js
├── demo10
├── a.js
├── index.html
├── main.js
└── webpack.config.js
├── demo11
├── a.js
├── index.html
├── main.js
└── webpack.config.js
├── demo12
├── index.html
├── main1.jsx
├── main2.jsx
└── webpack.config.js
├── demo13
├── index.html
├── main.js
└── webpack.config.js
├── demo14
├── index.html
├── main.js
└── webpack.config.js
├── demo15
├── data.js
├── index.html
├── main.jsx
└── webpack.config.js
├── demo16
├── index.html
├── index.js
├── main.js
└── webpack.config.js
├── demo17
├── app.css
├── index.html
├── index.jsx
└── webpack.config.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 这个仓库是以前学习和收集的一些WebPack插件和例子,和对这些插件简单的应用。主要是玩转`Webpack` 和`React`。参考阮大大的例子[ruanyf/webpack-demos](https://github.com/ruanyf/webpack-demos) ,更容易读懂。还有尤小右大大的例子[vuejs-templates/webpack](https://github.com/vuejs-templates/webpack)和[vuejs-templates/webpack-simple](https://github.com/vuejs-templates/webpack-simple) 在 `Webpack` 中应用 `vue`,参考这些例子结合官方文档看,慢慢就玩转 [Webpack](https://webpack.github.io/) 和 [React](http://facebook.github.io/react/)。
2 |
3 |
4 | # 目录
5 |
6 | - [准备工作](#准备工作)
7 | - [Webpack第一个例子](#webpack第一个例子)
8 | - [运行命令](#运行命令)
9 | - [常用的命令](#常用的命令)
10 | - [包工具应用](#包工具应用)
11 | - [Babel加载](#babel加载)
12 | - [CSS加载](#css加载)
13 | - [图片加载](#图片加载)
14 | - [CSS组件加载](#css组件加载)
15 | - [UglifyJs插件](#uglifyjs插件)
16 | - [HTML Webpack插件](#html-webpack插件)
17 | - [命令启动打开入口路径](#命令启动打开入口路径)
18 | - [环境变量玩儿法](#环境变量玩儿法)
19 | - [代码分割](#代码分割)
20 | - [用bundle-loader分割代码](#用bundle-loader分割代码)
21 | - [普通模块React应用](#普通模块react应用)
22 | - [jQuery加载](#jquery加载)
23 | - [每个模块中使用JSLite或者jQuery](#每个模块中使用jslite或者jquery)
24 | - [暴露全局变量](#暴露全局变量)
25 | - [模块热替换](#模块热替换)
26 | - [使用webpack命令的两个子命令](#使用webpack命令的两个子命令)
27 | - [修改webpack配置方法](#修改webpack配置方法)
28 | - [React 路由](#react-路由)
29 | - [React Router 配置](#react-router-配置)
30 | - [路由匹配](#路由匹配)
31 | - [学习资料](#学习资料)
32 |
33 |
34 | # 准备工作
35 |
36 | 首先全局安装两个包 [Webpack](https://www.npmjs.com/package/webpack) 和 [webpack-dev-server](https://www.npmjs.com/package/webpack-dev-server)
37 |
38 | ```bash
39 | $ npm i -g webpack webpack-dev-server
40 | ```
41 |
42 |
43 | 接下来克隆这个仓库和安装它的依赖
44 |
45 | ```bash
46 | $ git clone https://github.com/jaywcjlove/webpack-react-demo.git
47 | $ cd webpack-react-demo
48 | $ npm install
49 | ```
50 |
51 | 然后进入演示的例子
52 |
53 | ```bash
54 | $ cd demo01
55 | $ webpack-dev-server
56 | ```
57 |
58 | 在浏览器中访问 `http://127.0.0.1:8080` 进行预览查看生成的效果。
59 |
60 | 上面的 `webpack` `webpack-dev-server` 是全局安装,你也可以不用全局安装,放到你的 `package.json` 文件中,例如:
61 |
62 | ```bash
63 | {
64 | // ...
65 | "scripts": {
66 | "dev": "webpack-dev-server --devtool eval --progress --colors",
67 | "deploy": "NODE_ENV=production webpack -p"
68 | },
69 | // ...
70 | }
71 | ```
72 |
73 | 这种方法你得这么运行 `npm run dev` 和 `npm run deploy`
74 |
75 |
76 | # Webpack第一个例子
77 |
78 | Webpack 是前端构建工具,类似于 `gulp` 和 `grunt`,相对于 `gulp` 和 `grunt`,构建起来相对复杂一点点。这里有官方文档介绍 [Webpack](http://webpack.github.io/docs/what-is-webpack.htm)
79 |
80 | 第一个简单的例子[demo01](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo01)首先得有 一个配置文件`webpack.config.js` 记得名字,必须得这样,Webpack可以直接识别配置文件。
81 |
82 | ```js
83 | module.exports = {
84 | entry: './main.js',
85 | output: {
86 | filename: 'bundle.js'
87 | }
88 | };
89 | ```
90 |
91 | **多个入口文件** 只需要更改配置文件`webpack.config.js` 中的内容
92 |
93 | - `entry` 配置中添加你所有文件。
94 | - `filename` 值设置为 `filename: '[name].js'`
95 |
96 | ```js
97 | module.exports = {
98 | entry: {
99 | bundle1: './main1.js',
100 | bundle2: './main2.js'
101 | },
102 | output: {
103 | filename: '[name].js'
104 | }
105 | };
106 | ```
107 |
108 | 添加一个入口`js`文件`main.js`。
109 |
110 | ```js
111 | document.write('
Hello World
');
112 | ```
113 |
114 | 添加静态页面 `index.html`
115 |
116 | ```html
117 |
118 |
119 |
120 |
121 |
122 | ```
123 |
124 | ## 运行命令
125 |
126 | ```bash
127 | $ webpack
128 | ```
129 |
130 | 会生成 `bundle.js` 你直接页面中引用并且打开它。
131 |
132 | ```bash
133 | # 这个可以使用 http://localhost:8080 来预览
134 | $ webpack-dev-server
135 | ```
136 |
137 | 上面这个命令是开发模式没有生成js 文件,它不是生成这是一个重载 Webpack 服务。
138 |
139 | ## 常用的命令
140 |
141 | - `webpack` – 开发的时候构建,没有进行任何处理有很多注释的js文件
142 | - `webpack -p` – 这个是构建压缩过的js文件
143 | - `webpack --watch` – 监控文件变化持续构建
144 | - `webpack -d` – 生产出 `.map` 文件,这个文件调试非常有用[JavaScript Source Map 详解](http://www.ruanyifeng.com/blog/2013/01/javascript_source_map.html)
145 | - `webpack --colors` – 输出带有颜色的信息
146 |
147 | # 包工具应用
148 |
149 | ## Babel加载
150 |
151 | 加载预处理插件,可将 `JSX/ES6` 转换成 `js` 文件。官方完整的[加载列表](http://webpack.github.io/docs/list-of-loaders.html)
152 |
153 | 接下来这个例子[demo02](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo02)依赖下面的包工具
154 |
155 | ```bash
156 | npm install babel-loader babel-preset-es2015 babel-preset-react react react-dom --save
157 | ```
158 |
159 | 创建 `index.html` 文件
160 |
161 | ```html
162 |
163 |
164 |
165 |
166 |
167 |
168 | ```
169 |
170 | 创建 `main.jsx` 文件
171 |
172 | ```js
173 | const React = require('react');
174 | const ReactDOM = require('react-dom');
175 |
176 | ReactDOM.render(
177 | Hello, world!
,
178 | document.querySelector('#wrapper')
179 | );
180 | ```
181 |
182 | 创建 `webpack.config.js` 文件
183 |
184 | ```js
185 | module.exports = {
186 | entry: './main.jsx',
187 | output: {
188 | filename: 'bundle.js'
189 | },
190 | module: {
191 | loaders:[
192 | {
193 | test: /\.js[x]?$/,
194 | exclude: /node_modules/,
195 | loader: 'babel-loader?presets[]=es2015&presets[]=react'
196 | },
197 | ]
198 | }
199 | };
200 | ```
201 |
202 | 上面的 `webpack.config.js` 中的 `module.loaders` 是一个装载机,配置你需要装载的东西,你可以改成明了的书写方法:
203 |
204 | ```json
205 | {
206 | loaders: [
207 | {
208 | test: /\.jsx?$/,
209 | exclude: /node_modules/,
210 | loader: 'babel',
211 | query: {
212 | presets: ['es2015', 'react']
213 | }
214 | }
215 | ]
216 | }
217 | ```
218 |
219 | ## CSS加载
220 |
221 | Webpack允许你在js文件中引入CSS文件,然后用 `CSS-loader` 对CSS文件进行预处理,这个例子[demo03](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo03)依赖`CSS-loader` 和 `style-loader`。
222 | 安装依赖
223 |
224 | ```bash
225 | npm install css-loader style-loader --save
226 | ```
227 |
228 | main.js
229 |
230 | ```js
231 | require('./app.css');
232 | ```
233 |
234 | app.css
235 |
236 | ```css
237 | body {
238 | background-color: blue;
239 | }
240 | ```
241 |
242 | index.html
243 |
244 | ```html
245 |
246 |
247 |
248 |
249 |
250 | Hello World
251 |
252 |
253 | ```
254 |
255 | webpack.config.js
256 |
257 | ```js
258 | module.exports = {
259 | entry: './main.js',
260 | output: {
261 | filename: 'bundle.js'
262 | },
263 | module: {
264 | loaders:[
265 | { test: /\.css$/, loader: 'style-loader!css-loader' },
266 | ]
267 | }
268 | };
269 | ```
270 |
271 | `style-loader` 会将样式插入到 html 标签中,运行打开页面将是一个内联样式。会将上面的 HTML 干成下面这样的内联元素插入页面。
272 |
273 | ```html
274 |
275 |
276 |
281 |
282 | ```
283 |
284 | ## 图片加载
285 |
286 | 图片加载需要依赖 `file-loader` 和 `url-loader` ,安装依赖。[demo04](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo04)
287 |
288 | ```bash
289 | npm install url-loader file-loader --save
290 | ```
291 |
292 | main.js
293 |
294 | ```js
295 | var img1 = document.createElement("img");
296 | img1.src = require("./small.png");
297 | document.body.appendChild(img1);
298 | var img2 = document.createElement("img");
299 | img2.src = require("./big.png");
300 | document.body.appendChild(img2);
301 | ```
302 |
303 | index.html
304 |
305 | ```html
306 |
307 |
308 |
309 |
310 |
311 | ```
312 |
313 | webpack.config.js
314 |
315 | ```js
316 | module.exports = {
317 | entry: './main.js',
318 | output: {
319 | filename: 'bundle.js'
320 | },
321 | module: {
322 | loaders:[
323 | { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
324 | ]
325 | }
326 | };
327 | ```
328 |
329 | `url-loader` 插件后面跟上参数,`'url-loader?limit=8192'` 当图片小于 `8192` bytes,会将图片生成 `data:image/png;base64` base64 图片。两张图片加载方式分别不同:
330 |
331 | ```html
332 |
333 |
334 | ```
335 |
336 | ## CSS组件加载
337 |
338 | `css-loader?modules` (查询模块的参数) 使用[CSS模块](https://github.com/css-modules/css-modules)的规格。加载CSS模块默认是本地作用域,如果你要将CSS作用于全局,你得将选择器放入global中如`:global(.h2)` [demo05](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo05)
339 |
340 | index.html
341 |
342 | ```html
343 |
344 |
345 | Hello World
346 | Hello Webpack
347 |
348 |
349 |
350 |
351 | ```
352 |
353 | app.css
354 |
355 | ```css
356 | .h1 {color:red; }
357 | :global(.h2) {color: blue; }
358 | ```
359 |
360 | main.jsx
361 |
362 | ```js
363 | var React = require('react');
364 | var ReactDOM = require('react-dom');
365 | var style = require('./app.css');
366 | ReactDOM.render(
367 |
368 |
Hello World
369 | Hello Webpack
370 | ,
371 | document.getElementById('example')
372 | );
373 | ```
374 |
375 | webpack.config.js
376 |
377 | ```js
378 | module.exports = {
379 | entry: './main.jsx',
380 | output: {
381 | filename: 'bundle.js'
382 | },
383 | module: {
384 | loaders:[
385 | {
386 | test: /\.js[x]?$/,
387 | exclude: /node_modules/,
388 | loader: 'babel-loader',
389 | query: {
390 | presets: ['es2015', 'react']
391 | }
392 | },{
393 | test: /\.css$/,
394 | loader: 'style-loader!css-loader?modules'
395 | }
396 | ]
397 | }
398 | };
399 | ```
400 |
401 | ## UglifyJs插件
402 |
403 | Webpack 有插件系统来扩展其功能。例如:[UglifyJs Plugin](http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin)将 `main.js` 输出压缩版本的 `bundle.js` [demo06](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo06),[UglifyJS 参数设置](https://github.com/mishoo/UglifyJS2#usage)。
404 |
405 |
406 | main.js
407 |
408 | ```js
409 | var longVariableName = 'Hello';
410 | longVariableName += ' World';
411 | document.write('' + longVariableName + '
');
412 | ```
413 |
414 | index.html
415 |
416 | ```html
417 |
418 |
419 |
420 |
421 |
422 | ```
423 |
424 | webpack.config.js
425 |
426 | ```js
427 | var webpack = require('webpack');
428 | var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
429 | module.exports = {
430 | entry: './main.js',
431 | output: {
432 | filename: 'bundle.js'
433 | },
434 | plugins: [
435 | new uglifyJsPlugin({
436 | compress: {
437 | warnings: false
438 | }
439 | })
440 | ]
441 | };
442 | ```
443 |
444 | 运行之后`main.js` 将被压缩
445 |
446 | ## HTML Webpack插件
447 |
448 | [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) 能创建`index.html` 文件。[demo07](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo07)
449 |
450 | main.js
451 |
452 | ```js
453 | document.write('Hello World
');
454 | ```
455 |
456 | webpack.config.js
457 |
458 | ```js
459 | var HtmlwebpackPlugin = require('html-webpack-plugin');
460 | module.exports = {
461 | entry: './main.js',
462 | output: {
463 | filename: 'bundle.js'
464 | },
465 | plugins: [
466 | new HtmlwebpackPlugin({
467 | title: 'Webpack-demos'
468 | })
469 | ]
470 | };
471 | ```
472 |
473 |
474 | ## 命令启动打开入口路径
475 |
476 | [open-browser-webpack-plugin](https://github.com/baldore/open-browser-webpack-plugin) 这是一个傻叉的包工具,就一个特别方便的功能,就是在你运行`webpack-dev-server`命令的时候,自动打开`http://localhost:8080/` 你配置的网址。[demo08](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo08)
477 | 稍做更改`webpack.config.js`中的 module.exports.plugins 添加一个插件。
478 |
479 | ```js
480 | plugins: [
481 | new HtmlwebpackPlugin({
482 | title: 'Webpack-demos'
483 | }),
484 | new OpenBrowserPlugin({
485 | url: 'http://localhost:8080'
486 | })
487 | ]
488 | ```
489 |
490 |
491 | ## 环境变量玩儿法
492 |
493 | [demo09](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo09) 只有在开发环境中使用环境变量,才能使某些代码起作用。
494 |
495 | main.js
496 | ```js
497 | document.write('Hello World
');
498 |
499 | if (__DEV__) {
500 | document.write(new Date());
501 | }
502 | ```
503 |
504 | index.html
505 |
506 | ```html
507 |
508 |
509 |
510 |
511 |
512 | ```
513 |
514 | webpack.config.js
515 |
516 | ```js
517 | var webpack = require('webpack');
518 | var devFlagPlugin = new webpack.DefinePlugin({
519 | __DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
520 | });
521 |
522 | module.exports = {
523 | entry: './main.js',
524 | output: {
525 | filename: 'bundle.js'
526 | },
527 | plugins: [devFlagPlugin]
528 | };
529 | ```
530 |
531 | 通过环境变量来运行`webpack-dev-server` 命令
532 |
533 | ```bash
534 | # Linux & Mac
535 | $ env DEBUG=true webpack-dev-server
536 |
537 | # Windows
538 | $ DEBUG=true webpack-dev-server
539 | ```
540 |
541 | ## 代码分割
542 |
543 | 这个非常重要,构建大型应用的时候,你需要将你的代码分模块,不然你的js越来越大,加载速度越来越慢,分块也适合项目模块化,多人共同应用开发。我们在下面的例子[demo10](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo10) 用的是CommonJs 的加载方式 `require.ensure` 你可以到官网看跟多的模块加载方式[在这里](http://webpack.github.io/docs/code-splitting.html)
544 |
545 | main.js
546 |
547 | ```js
548 | require.ensure(['./a'], function(require) {
549 | var content = require('./a');
550 | document.open();
551 | document.write('' + content + '
');
552 | document.close();
553 | });
554 | ```
555 |
556 | `require.ensure` 告诉 webpack 去加载分割出来的 `a.js` 文件
557 |
558 | a.js
559 |
560 | ```js
561 | module.exports = 'Hello World';
562 | ```
563 |
564 | 按照上面的书写方式,webpack知道你的依赖关系,根据这个依赖关系输出js,然后在`index.html`页面上引用入口 `js` 文件 `main.js`。
565 |
566 | ```html
567 |
568 |
569 |
570 |
571 |
572 | ```
573 |
574 | webpack.config.js
575 |
576 | ```js
577 | module.exports = {
578 | entry: './main.js',
579 | output: {
580 | filename: 'bundle.js'
581 | }
582 | };
583 | ```
584 |
585 | ## 用bundle-loader分割代码
586 |
587 | 此功能需要安装[bundle-loader](https://www.npmjs.com/package/bundle-loader) [demo11](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo11) 这个例子只要将 [demo10](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo10) 的例子中的`main.js`文件改改就可以了,然后安装依赖。
588 |
589 | ```bash
590 | $ npm install --save bundle-loader
591 | ```
592 |
593 | main.js
594 |
595 | ```js
596 | var load = require('bundle-loader!./a.js');
597 | // 异步等待加载完成会后执行
598 | load(function(file) {
599 | document.open();
600 | document.write('' + file + '
');
601 | document.close();
602 | });
603 | ```
604 |
605 | 运行 `webpack` 命令之后就生成两个js 文件 `bundle.js` 和 `1.bundle.js` 页面 `index.html` 引用入口文件 `bundle.js` 。
606 |
607 | ## 普通模块React应用
608 |
609 | [demo12](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo12)当多个脚本有共同的部分,可以提取公共部分为一个单独的文件使用commonschunkplugin方法。
610 |
611 | ```js
612 | // main1.jsx
613 | var React = require('react');
614 | var ReactDOM = require('react-dom');
615 |
616 | ReactDOM.render(
617 | Hello World
,
618 | document.getElementById('a')
619 | );
620 |
621 | // main2.jsx
622 | var React = require('react');
623 | var ReactDOM = require('react-dom');
624 |
625 | ReactDOM.render(
626 | Hello Webpack
,
627 | document.getElementById('b')
628 | );
629 | ```
630 |
631 | index.html
632 |
633 | ```html
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 | ```
644 |
645 | webpack.config.js
646 |
647 | ```js
648 | var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
649 | module.exports = {
650 | entry: {
651 | bundle1: './main1.jsx',
652 | bundle2: './main2.jsx'
653 | },
654 | output: {
655 | filename: '[name].js'
656 | },
657 | module: {
658 | loaders:[
659 | {
660 | test: /\.js[x]?$/,
661 | exclude: /node_modules/,
662 | loader: 'babel-loader',
663 | query: {
664 | presets: ['es2015', 'react']
665 | }
666 | },
667 | ]
668 | },
669 | plugins: [
670 | new CommonsChunkPlugin('init.js')
671 | ]
672 | }
673 | ```
674 |
675 | ## jQuery加载
676 |
677 | [demo13](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo13)可以提取一些热门库如`jQuery`,我这个例子就加载一下`JSLite`吧,从脚本到一个单独文件也使用`commonschunkplugin`方法。
678 |
679 | 你需要安装它们才能加载
680 |
681 | ```bash
682 | $ npm install jquery --save
683 | # 或者
684 | $ npm install jslite --save
685 | ```
686 |
687 | main.js
688 |
689 | ```js
690 | var $ = require('jslite');
691 | $('h1').text('Hello World');
692 | ```
693 |
694 | index.html
695 |
696 | ```html
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 | ```
705 |
706 | webpack.config.js
707 |
708 | ```js
709 | var webpack = require('webpack');
710 |
711 | module.exports = {
712 | entry: {
713 | app: './main.js',
714 | vendor: ['jslite'],
715 | },
716 | output: {
717 | filename: 'bundle.js'
718 | },
719 | plugins: [
720 | new webpack.optimize.CommonsChunkPlugin(/* chunkName= */'vendor', /* filename= */'vendor.js')
721 | ]
722 | };
723 | ```
724 |
725 | ### 每个模块中使用JSLite或者jQuery
726 |
727 | [demo14](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo14)这个是有我们要使用 `ProvidePlugin` 方法。[官方文档](http://webpack.github.io/docs/shimming-modules.html)
728 |
729 | index.html
730 |
731 | ```html
732 |
733 |
734 |
735 |
736 |
737 |
738 | ```
739 |
740 | main.js
741 |
742 | ```js
743 | $('h1').text('Hello World');
744 | ```
745 |
746 | webpack.config.js
747 |
748 | ```js
749 | var webpack = require('webpack');
750 | module.exports = {
751 | entry: {
752 | app: './main.js'
753 | },
754 | output: {
755 | filename: 'bundle.js'
756 | },
757 | plugins: [
758 | new webpack.ProvidePlugin({
759 | $: "jslite",
760 | JSLite: "jslite",
761 | "window.JSLite": "jslite"
762 | })
763 | ]
764 | };
765 | ```
766 |
767 |
768 | ## 暴露全局变量
769 |
770 | [demo15](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo15)可以在 `webpack.config.js` 中使用 `externals`。[官方文档](http://webpack.github.io/docs/library-and-externals.html)
771 |
772 | 例如我们有一个`data.js`
773 |
774 | ```js
775 | var data = 'Hello World';
776 | ```
777 |
778 | 我们将`data`作为一个全局变量。webpack.config.js
779 |
780 | ```js
781 | module.exports = {
782 | entry: './main.jsx',
783 | output: {
784 | filename: 'bundle.js'
785 | },
786 | module: {
787 | loaders:[
788 | {
789 | test: /\.js[x]?$/,
790 | exclude: /node_modules/,
791 | loader: 'babel-loader',
792 | query: {
793 | presets: ['es2015', 'react']
794 | }
795 | },
796 | ]
797 | },
798 | externals: {
799 | // require('data') 应用当做一个全局变量引用进来
800 | 'data': 'data'
801 | }
802 | };
803 | ```
804 |
805 | 现在你可以在你的`main.jsx`文件中可以把 `data` 全局变量当一个包引用进来,实际上它是一个全局变量。
806 |
807 | ```js
808 | var data = require('data');
809 | var React = require('react');
810 | var ReactDOM = require('react-dom');
811 |
812 | ReactDOM.render(
813 | {data}
,
814 | document.getElementById('title')
815 | );
816 | ```
817 |
818 | ## 模块热替换
819 | [demo16](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo16)[hot module replacement with webpack](https://github.com/webpack/docs/wiki/hot-module-replacement-with-webpack) [翻译](https://segmentfault.com/a/1190000003872635) [官方文档Hot Module Replacement](https://github.com/webpack/docs/wiki/hot-module-replacement-with-webpack) 添加或删除模块,在运行应用程序时,无需重新加载刷新页面。现在有[两种方法](http://webpack.github.io/docs/webpack-dev-server.html#hot-module-replacement)让webpack服务端模块热更换。
820 |
821 | ### 使用webpack命令的两个子命令
822 |
823 | ```bash
824 | $ webpack-dev-server --hot --inline
825 | ```
826 |
827 | 这两个命令参数的意思是:
828 | - `--hot`: 加`HotModuleReplacementPlugin`切换服务器热加载模式。
829 | - `--inline`: 嵌入运行的`webpack-dev-server`中。
830 | - `--hot --inline`: 添加一个指向 `webpack/hot/dev-server`.
831 |
832 | ### 修改webpack配置方法
833 |
834 | - 将`new webpack.HotModuleReplacementPlugin()`添加到`plugins`中。
835 | - 将`'webpack/hot/dev-server'` 和 `'webpack-dev-server/client?http://localhost:8080',`添加到 `entry`
836 |
837 | 这样的话你只需要运行下面命令即可。
838 |
839 | ```bash
840 | $ webpack-dev-server
841 | ```
842 |
843 | webpack.config.js
844 |
845 | ```js
846 | var webpack = require('webpack');
847 | var path = require('path');
848 | module.exports = {
849 | entry: [
850 | 'webpack/hot/dev-server',
851 | 'webpack-dev-server/client?http://localhost:8080',
852 | './index.js'
853 | ],
854 | output: {
855 | filename: 'bundle.js',
856 | publicPath: '/static/'
857 | },
858 | plugins: [
859 | new webpack.HotModuleReplacementPlugin()
860 | ],
861 | module: {
862 | loaders: [{
863 | test: /\.jsx?$/,
864 | loaders: ['babel-loader?presets[]=es2015&presets[]=react'],
865 | include: path.join(__dirname, '.')
866 | }]
867 | }
868 | };
869 | ```
870 |
871 | index.html
872 |
873 | ```html
874 |
875 |
876 |
877 | Hot Module Replacement
878 |
879 |
880 |
881 | ```
882 |
883 | index.js
884 |
885 | ```js
886 | import React from 'react';
887 | import ReactDOM from 'react-dom';
888 | import Main from './main';
889 |
890 | ReactDOM.render(, document.getElementById('root'));
891 | ```
892 |
893 | main.js
894 |
895 | ```js
896 | import React, { Component } from 'react';
897 | export default class Main extends Component {
898 | render() {
899 | return (
900 | Hello World
901 | );
902 | }
903 | }
904 | ```
905 |
906 |
907 | ## React 路由
908 |
909 | [demo17](https://github.com/jaywcjlove/webpack-react-demo/tree/master/demo17) 使用`Webpack` 使用[React-router](https://github.com/reactjs/react-router/tree/master/docs) 建立路由。这里需要安装`react-router`依赖,v2.x 的React-router与v1.x有区别所以你还是要看看[官方文档](https://github.com/reactjs/react-router/blob/master/upgrade-guides/v2.0.0.md)。
910 |
911 | ```bash
912 | $ npm install --save React-router
913 | $ webpack-dev-server --history-api-fallback
914 | ```
915 |
916 | ### React Router 配置
917 |
918 | - Router 与 Route 一样都是 react 组件 ,它的 history 对象是整个路由系统的核心,它暴漏了很多属性和方法在路由系统中使用;
919 | - Redirect 是一个重定向组件,有 from 和 to 两个属性;
920 | - browserHistory :
921 | ```
922 | Browser history 是由 React Router 创建浏览器应用推荐的 history。它使用 History API 在浏览器中被创建用于处理 URL,新建一个像这样真实的 URL example.com/some/path。
923 | ```
924 | - hashHistory :
925 | ```
926 | 这是一个你会获取到的默认 history ,如果你不指定某个 history 。它用到的是 URL 中的 hash(#)部分去创建形如 example.com/#/some/path 的路由。
927 | 这个 支持 ie8+ 的浏览器,但是因为是 hash 值,所以不推荐使用。
928 | ```
929 | - createMemoryHistory :不会在地址栏被操作或读取。
930 |
931 | ### 路由匹配
932 |
933 | ```js
934 | // 匹配 /hello/michael 和 /hello/ryan
935 | // 匹配 /hello, /hello/michael, 和 /hello/ryan
936 | // 匹配 /files/hello.jpg 和 /files/hello.html
937 | // 匹配 /files/hello.jpg 和 /files/path/to/file.jpg
938 | ```
939 |
940 | # 学习资料
941 |
942 | 其它例子你可以研究研究 😄
943 |
944 | - [redux应用的例子](https://github.com/matthew-sun/redux-example) [说明文档](http://www.cnblogs.com/matthewsun/p/4773646.html)
945 | - [React+Redux系列教程](https://github.com/lewis617/react-redux-tutorial)
--------------------------------------------------------------------------------
/demo01/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Webpack demo
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/demo01/main.js:
--------------------------------------------------------------------------------
1 | document.write('Hello World
');
2 |
--------------------------------------------------------------------------------
/demo01/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: './main.js',
3 | output: {
4 | filename: 'bundle.js'
5 | }
6 | };
--------------------------------------------------------------------------------
/demo02/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Webpack demo
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/demo02/main.jsx:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const ReactDOM = require('react-dom');
3 |
4 | ReactDOM.render(
5 | Hello, world!
,
6 | document.querySelector('#wrapper')
7 | );
--------------------------------------------------------------------------------
/demo02/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: './main.jsx',
3 | output: {
4 | filename: 'bundle.js'
5 | },
6 | module: {
7 | // loaders:[
8 | // {
9 | // test: /\.js[x]?$/,
10 | // exclude: /node_modules/,
11 | // loader: 'babel-loader?presets[]=es2015&presets[]=react'
12 | // },
13 | // ]
14 | loaders: [
15 | {
16 | test: /\.jsx?$/,
17 | exclude: /node_modules/,
18 | loader: 'babel',
19 | query: {
20 | presets: ['es2015', 'react']
21 | }
22 | }
23 | ]
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/demo03/app.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: blue;
3 | }
--------------------------------------------------------------------------------
/demo03/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Hello World
7 |
8 |
--------------------------------------------------------------------------------
/demo03/main.js:
--------------------------------------------------------------------------------
1 | require('./app.css');
--------------------------------------------------------------------------------
/demo03/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: './main.js',
3 | output: {
4 | filename: 'bundle.js'
5 | },
6 | module: {
7 | loaders:[
8 | { test: /\.css$/, loader: 'style-loader!css-loader' },
9 | ]
10 | }
11 | };
--------------------------------------------------------------------------------
/demo04/big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaywcjlove/webpack-react-demo/84e3ab9ae16a340afe23e0db0dea5ab0b25d0100/demo04/big.png
--------------------------------------------------------------------------------
/demo04/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |