Skip to content

Commit fc7ad44

Browse files
committed
edit md
1 parent 9e1e504 commit fc7ad44

3 files changed

Lines changed: 378 additions & 0 deletions

File tree

react/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ React 是 facebook 开源的一套框架,可总结为以下几个特点:
1515
- [表单](https://github.com/wscats/react-tutorial/tree/master/react/component/src/form)
1616
- [组件通信](https://github.com/wscats/react-tutorial/tree/master/react/component/src/communication)
1717
- [生命周期](https://github.com/wscats/react-tutorial/tree/master/react/component/src/lifecycle)
18+
- [模块化(webpack)](https://github.com/wscats/react-tutorial/tree/master/react/webpack)
1819
- [路由(3.0)](https://github.com/wscats/react-tutorial/tree/master/react/router)
1920
- Redux
2021
- [Redux 简介和简单实现](https://github.com/wscats/react-tutorial/tree/master/react/redux)

react/webpack/README.md

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
# webpack
2+
3+
基于 NodeJS 的一个著名第三方模块,主要目的是来实现前端模块化和自动化的,在这之前还有一个跟它类似的 gulp ,也是一个自动化构建工具,主要功能是打包合并压缩重命名等...
4+
5+
webpack 其实也是一套自动化构建工具,在打包代码的时候也是跟 gulp 很相似的
6+
7+
<img src="what-is-webpack.png" />
8+
9+
左边比较多的文件(模块),也比较多的格式(js,css,html,jsx,scss),右边文件比较少,大部分都是转为JS格式,还有一些图片格式,所以 webpack 其实处理各种类型的文件,最终想把他们尽可能的转为JS类型的文件(打包,合并,压缩),webpack 多变少(或一个),多文件进少文件或者单文件出,而 gulp 更多的是多文件变相同多的文件,多进多出
10+
11+
一般开发目录是在`entry`里面,发布是在`output`文件夹
12+
13+
## 安装
14+
15+
16+
1. 在根目录下新建`webpack.config.js`
17+
```js
18+
gulp gulpfile.js
19+
webpack webpack.config.js
20+
```
21+
2. 用npm安装`webpack`的依赖包,全局安装一次,本地也安装一次
22+
23+
```bash
24+
npm install gulp -g //全局
25+
npm install gulp //本地
26+
27+
28+
npm install webpack -g
29+
npm install webpack-cli -g
30+
npm install webpack
31+
```
32+
33+
3. 往配置文件里面写对应的配置
34+
35+
四大概念
36+
1. 入口(entry)
37+
2. 输出(output)
38+
3. loader
39+
4. 插件(plugins)
40+
41+
## entry
42+
43+
跟我们的`gulp``gulp.src()`,入口其实就是要导入需要处理的文件,放文件名
44+
45+
`webpack.config.js`同级目录下,新建`entry`文件夹
46+
```js
47+
// 配置参数
48+
module.exports = {
49+
// 入口 把index.js导入进来处理
50+
entry: './entry/index.js'
51+
};
52+
```
53+
54+
## output
55+
56+
`webpack.config.js`同级目录下,新建`output`文件夹
57+
```js
58+
const path = require('path');
59+
// 配置参数
60+
module.exports = {
61+
// 入口 把index.js导入进来处理
62+
entry: './entry/index.js',
63+
output: {
64+
// 写一段路径,寻找output文件夹
65+
path: path.resolve(__dirname, 'output'),
66+
// 在output文件夹里面导出文件名为bundle.js
67+
filename: 'bundle.js'
68+
}
69+
};
70+
```
71+
72+
在入口文件夹`entry``index.js`里面写入以下代码
73+
```js
74+
import $ from "jquery";//记得先安装 npm install jquery
75+
$("body").html("helloworld");
76+
```
77+
78+
4. 编译
79+
80+
`webpack.config.js`文件夹的命令行里面执行`webpack`命令,如果成功的话会在`output`文件夹下生成一份新的`bundle.js`
81+
```js
82+
webpack
83+
```
84+
`require.js`模块化,分开模块管理项目,并且能重复使用模块
85+
86+
> webpack = gulp + requirejs
87+
88+
既做打包合并也做模块化,相对于`gulp`,它就是更偏重于模块化
89+
90+
`vue-cli`基于`webpack`,它就的模块化就是基于webpack的
91+
92+
93+
## loader
94+
95+
webpack 它默认只能处理JS类型文件,它不自带处理其他非JS文件的功能,如果你想 webpack 处理非 JS 类型文件,必须安装其他第三方插件来实现,webpack 里面这种插件称之为`loaders`(加载器)
96+
97+
> loader = 处理各种非JS类型文件
98+
99+
这个功能类似于 gulp 的拓展功能,需要装第三方插件
100+
```bash
101+
gulp-sass
102+
gulp-minify
103+
gulp-concat
104+
```
105+
比如`.vue`组件是非JS类型文件,我们就需要安装`vue-loader`来处理,类似的还有以下这些
106+
```bash
107+
npm install vue-loader
108+
npm install sass-loader
109+
npm install html-loader
110+
npm install css-loader
111+
npm install json-loader
112+
```
113+
安装完对应的loader之后,还需要在`webpack.config.js`文件里面进行配置
114+
115+
这些loader都是帮你处理不同类型的文件(非JS类型文件),`test`是正则,匹配文件名字,`use`是加上你对应`loader`的名字
116+
117+
```js
118+
module: {
119+
rules: [{
120+
test: /\.vue$/,
121+
use: 'vue-loader'
122+
}, {
123+
test: /\.css$/,
124+
use: ['style-loader', 'css-loader']
125+
}, {
126+
test: /\.png|jpg|jpeg$/,
127+
use: ['url-loader']
128+
}]
129+
},
130+
```
131+
132+
133+
# React项目结构
134+
```json
135+
--your project
136+
|--app
137+
|--components
138+
|--productBox.jsx
139+
|--main.js
140+
|--build
141+
|--index.html
142+
|--bundle.js(该文件是webpack打包后生成的)
143+
```
144+
145+
## 用npm安装react、webpack
146+
默认已经安装了[NodeJS](https://nodejs.org/en/),推荐用`cnpm`
147+
```bash
148+
npm install --save-dev react react-dom --save-dev
149+
npm install -g webpack --save-dev//建议webpack全局安装,方便我们后面使用webpack命令
150+
```
151+
![image](https://cloud.githubusercontent.com/assets/17243165/25302403/d4e0b600-276f-11e7-9c4a-1cae78b0ceaf.png)
152+
153+
## 安装和配置Babel
154+
Babel其实是一个编译JavaScript的平台,它的强大之处表现在可以通过编译帮你达到以下目的:
155+
156+
> 下一代的JavaScript标准(ES6,ES7),这些标准目前并未被当前的浏览器完全的支持;
157+
> 使用基于JavaScript进行了拓展的语言,比如React的JSX
158+
> Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中,不过webpack把它们整合在一起使用,但是对于每一个你需要的功能或拓展,你都需要安装单独的包(用得最多的是解析Es6的babel-preset-es2015包和解析JSX的babel-preset-react包)。
159+
```
160+
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
161+
```
162+
在项目根目录下新建`.babelrc`文件,就是只有后缀名的文件,添加如下代码
163+
```json
164+
//.babelrc
165+
{
166+
"presets": [
167+
"react",
168+
"es2015"
169+
]
170+
}
171+
```
172+
173+
## 安装其他loader
174+
讲到这里,我们基本上就可以迅速搭建一个简单的web项目,但不得不提的是webpack loader。它是我个人认为相比于其他模块加载更牛X的地方,将它用于react的开发,结合react与生俱来的优越性能,两者天衣无缝的配合简直就是黄金组合。
175+
176+
总的来说 webpack 的 loader可以实现:
177+
178+
> 可以将React JSX语法转为js语句
179+
> React开发中支持ES6语法
180+
> 支持通过import来直接引入css、less、sass甚至是图片
181+
> 支持css中引用的图片大小在某一大小范围之内直接转为BASE64格式等等等
182+
183+
为了能够让以上功能奏效,我们要先安装对应的:
184+
babel-loader
185+
```bash
186+
npm install babel-loader --save-dev
187+
//css-loader
188+
npm install css-loader --save-dev
189+
//less-loader
190+
npm install less-loader --save-dev
191+
//style-loader
192+
npm install style-loader --save-dev
193+
//url-loader
194+
npm install url-loader --save-dev
195+
```
196+
而具体的实现,我们只要在下面webpack的配置文件中加入module属性里的loaders:
197+
198+
## 配置webpack.config.js
199+
webpack.config.js 是 webpack 的配置文件
200+
```js
201+
//__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
202+
module.exports = { //注意这里是exports不是export
203+
devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map
204+
entry: __dirname + "/app/main.js", //唯一入口文件
205+
output: { //输出目录
206+
path: __dirname + "/build", //打包后的js文件存放的地方
207+
filename: 'bundle.js', //打包后的js文件名
208+
},
209+
module: {
210+
loaders: [{
211+
test: /\.jsx?$/,
212+
exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选)
213+
loader: 'babel-loader'
214+
//npm install babel-loader
215+
//npm install babel-core
216+
}, {
217+
test: /\.css$/,
218+
loader: 'style-loader!css-loader'
219+
}, {
220+
test: /\.less$/,
221+
loader: 'style-loader!css-loader!less-loader'
222+
}, {
223+
test: /\.(png|jpg)$/,
224+
loader: 'url-loader?limit=25000'
225+
}]
226+
}
227+
};
228+
```
229+
使用 Source Maps,使调试更容易
230+
231+
|devtool选项|配置结果|
232+
|-|-|
233+
|source-map|在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包文件的构建速度|
234+
|cheap-module-source-map|在一个单独的文件中生成一个不带列映射的map,不带列映射提高项目构建速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便|
235+
|eval-source-map|使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。不过在开发阶段这是一个非常好的选项,但是在生产阶段一定不要用这个选项|
236+
|cheap-module-eval-source-map|这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点|
237+
238+
## 组件productBox.jsx
239+
新版本推荐使用ES6书写React组件
240+
```js
241+
var React = require('react');
242+
//旧版本的写法,会有警告
243+
/*var ProductBox = React.createClass({
244+
render: function() {
245+
return(
246+
<div className = "productBox" >
247+
Hello World!
248+
</div>
249+
);
250+
}
251+
});*/
252+
//新版本的写法 推荐
253+
class ProductBox extends React.Component {
254+
render() {
255+
return(
256+
<div>Hello World!</div>
257+
)
258+
}
259+
}
260+
module.exports = ProductBox;
261+
```
262+
用旧版本写法会出现以下警告
263+
![image](https://cloud.githubusercontent.com/assets/17243165/25302952/6f052124-277c-11e7-9377-2ebec113e1ce.png)
264+
265+
## 前端页面index.html
266+
index.html是最终要呈现的页面文件,代码如下
267+
```html
268+
<!DOCTYPE html>
269+
<html>
270+
<head lang="en">
271+
<meta charset="UTF-8">
272+
<title>React Test</title>
273+
</head>
274+
<body>
275+
<!--要插入React组件的位置-->
276+
<div id="content"></div>
277+
<script src="bundle.js"></script>
278+
</body
279+
</html>
280+
```
281+
282+
## 入口文件main.js
283+
main.js是入口文件,用来将React组件放在真正的html中
284+
```js
285+
var React = require('react');
286+
var ReactDom = require('react-dom');
287+
var AppComponent = require('./components/productBox.jsx');
288+
ReactDom.render(
289+
<AppComponent / >
290+
, document.getElementById('content')
291+
);
292+
```
293+
294+
## 依赖的描述文件package.json
295+
296+
package.json是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等
297+
```json
298+
{
299+
"devDependencies": {
300+
"babel-core": "^6.24.1",
301+
"babel-loader": "^7.0.0",
302+
"babel-preset-es2015": "^6.24.1",
303+
"babel-preset-react": "^6.24.1",
304+
"less-loader": "^4.0.3",
305+
"react": "^15.5.4",
306+
"react-dom": "^15.5.4",
307+
"style-loader": "^0.16.1",
308+
"url-loader": "^0.5.8",
309+
"webpack": "^2.4.1"
310+
}
311+
}
312+
313+
```
314+
315+
## 执行打包
316+
在命令行执行`webpack`命令
317+
![这里写图片描述](http://img.blog.csdn.net/20170422171745796?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjcwODAyNDc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
318+
319+
## 安装并启用webpack-dev-server
320+
321+
> 想不想让你的浏览器监测你都代码的修改,并自动刷新修改后的结果,其实Webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建,可以实现你想要的这些功能,不过它是一个单独的组件,在webpack中进行配置之前需要单独安装它作为项目依赖
322+
```
323+
npm install --save-dev webpack-dev-server
324+
```
325+
在webpack.config.js增加devServer的配置
326+
```js
327+
//__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
328+
module.exports = { //注意这里是exports不是export
329+
devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map
330+
entry: __dirname + "/app/main.js", //唯一入口文件
331+
output: { //输出目录
332+
path: __dirname + "/build", //打包后的js文件存放的地方
333+
filename: 'bundle.js', //打包后的js文件名
334+
},
335+
module: {
336+
loaders: [{
337+
test: /\.jsx?$/,
338+
exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选)
339+
loader: 'babel-loader'
340+
//npm install babel-loader
341+
//npm install babel-core
342+
}, {
343+
test: /\.css$/,
344+
loader: 'style-loader!css-loader'
345+
}, {
346+
test: /\.less$/,
347+
loader: 'style-loader!css-loader!less-loader'
348+
}, {
349+
test: /\.(png|jpg)$/,
350+
loader: 'url-loader?limit=25000'
351+
}]
352+
},
353+
devServer: {
354+
contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录)
355+
historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
356+
inline: true, //设置为true,当源文件改变时会自动刷新页面
357+
port: 8080, //设置默认监听端口,如果省略,默认为"8080"
358+
}
359+
};
360+
```
361+
![这里写图片描述](http://img.blog.csdn.net/20170422175523108?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjcwODAyNDc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
362+
在命令行执行`webpack-dev-server`命令就会运行服务器
363+
```
364+
webpack-dev-server
365+
```
366+
如果需要停止服务,在终端按两次`ctrl+c`
367+
368+
369+
# 思考
370+
371+
- webpack和gulp的区别
372+
373+
- webpack的四大概念入口(entry)输出(output)loader插件(plugins)
374+
375+
- webpack如何实现模块化的
376+
377+
- webpack的打包后执行代码的原理`eval("console.log(1)")`

react/webpack/what-is-webpack.png

360 KB
Loading

0 commit comments

Comments
 (0)