# 追本溯源

在学习 Webpack 之前,我们有必要来了解一些前端领域的开发历程,只有明白了这些开发历程,才能更加清楚 Webpack 是怎么应运而生的,又能给我们解决什么样的问题。

# 面向过程开发

特征: 一锅乱炖
在早期 js 能力还非常有限的时候,我们通过面向过程的方式把代码写在同一个.js文件中,一个面向过程的开发模式可能如下所示。

<!-- index.html代码 -->
<p>这里是我们网页的内容</p>
<div id="root"></div>
<script src="./index.js"></script>
1
2
3
4
// index.js代码
var root = document.getElementById('root');

// header模块
var header = document.createElement('div');
header.innerText = 'header';
root.appendChild(header);

// sidebar模块
var sidebar = document.createElement('div');
sidebar.innerText = 'sidebar';
root.appendChild(sidebar);

// content模块
var content = document.createElement('div');
content.innerText = 'content';
root.appendChild(content);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 面向对象开发

特征: 面向对象开发模式便于代码维护,深入人心。
随着 js 的不断发展,它所能解决的问题也越来越多,如果再像面向过程那样把所有代码写在同一个.js文件中,那么代码将变得非常难以理解和维护,此时面向对象开发模式便出现了,一个面向对象开发模式可能如下所示。

index.html中引入不同的模块:

<!-- index.html代码 -->
<p>这里是我们网页的内容</p>
<div id="root"></div>
<script src="./src/header.js"></script>
<script src="./src/sidebar.js"></script>
<script src="./src/content.js"></script>
<script src="./index.js"></script>
1
2
3
4
5
6
7

header.js代码:

// header.js代码
function Header() {
  var header = document.createElement('div');
  header.innerText = 'header';
  root.appendChild(header);
}
1
2
3
4
5
6

sidebar.js代码:

// sidebar.js代码
function Sidebar() {
  var sidebar = document.createElement('div');
  sidebar.innerText = 'sidebar';
  root.appendChild(sidebar);
}
1
2
3
4
5
6

content.js代码:

// content.js代码
function Content() {
  var content = document.createElement('div');
  content.innerText = 'content';
  root.appendChild(content);
}

1
2
3
4
5
6
7

index.js代码:

var root = document.getElementById('root');
new Header();
new Sidebar();
new Content();
1
2
3
4

不足: 以上的代码示例中,虽然使用面向对象开发模式解决了面向过程开发模式中的一些问题,但似乎又引入了一些新的问题。

  1. 每一个模块都需要引入一个.js文件,随着模块的增多,这会影响页面性能
  2. index.js文件中,并不能直接看出模块的逻辑关系,必须去页面才能找到
  3. index.html页面中,文件的引入顺序必须严格按顺序来引入,例如:index.js必须放在最后引入,如果把header.js文件放在index.js文件后引入,那么代码会报错

# 现代开发模式

特征: 模块化加载方案让前端开发进一步工程化
根据面向对象开发模式中的一系列问题,随后各种模块化加载的方案如雨后春笋,例如:ES ModuleAMDCMD以及CommonJS等,一个ES Module模块化加载方案可能如下所示。

index.html代码:

<!-- index.html代码 -->
<p>这里是我们网页的内容</p>
<div id="root"></div>
<script src="./index.js"></script>
1
2
3
4

header.js代码:

// header.js
export default function Header() {
  var root = document.getElementById('root');
  var header = document.createElement('div');
  header.innerText = 'header';
  root.appendChild(header);
}
1
2
3
4
5
6
7

sidebar.js代码:

// sidebar.js
export default function Sidebar() {
  var root = document.getElementById('root');
  var sidebar = document.createElement('div');
  sidebar.innerText = 'sidebar';
  root.appendChild(sidebar);
}
1
2
3
4
5
6
7

content.js代码:

// content.js代码
export default function Content() {
  var root = document.getElementById('root');
  var content = document.createElement('div');
  content.innerText = 'content';
  root.appendChild(content);
}
1
2
3
4
5
6
7

index.js代码:

// index.js代码
import Header from './src/header.js';
import Sidebar from './src/sidebar.js';
import Content from './src/content.js';

new Header();
new Sidebar();
new Content();
1
2
3
4
5
6
7
8

注意: 以上代码并不能直接在浏览器上执行,因为浏览器并不能直接识别ES Module代码,需要借助其他工具来进行翻译,此时 Webpack 就粉墨登场了。

# Webpack初体验

不建议跟随此小结一起安装,此次示例仅仅作为一个例子,详细学习步骤请直接阅读下一章节安装

# 生成package.json文件

参数说明

-y参数表示直接生成默认配置项的package.json文件,不加此参数需要一步步按需进行配置。

$ npm init -y
1

生成的package.json文件:

{
  "name": "webpack-vuepress",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

1
2
3
4
5
6
7
8
9
10
11
12
13

# 安装Webpack

参数说明

-D参数代表在本项目下安装 Webpack ,它是--save-dev的简写

$ npm install webpack webpack-cli -D
1

# 修改代码

配置说明

webpack默认打包路径到dist文件夹,打包后的.js文件名字叫main.js

其他代码不动,将index.html中的.js文件改成如下引用方式(引用打包后的文件):

<!-- index.html代码 -->
<p>这里是我们网页的内容</p>
<div id="root"></div>
<script src="./dist/main.js"></script>
1
2
3
4

# Webpack打包

参数说明

  1. npx webpack代表在本项目下寻找 Webpack 打包命令,它区别于npm命令
  2. index.js参数代表本次打包的入口是index.js
$ npx webpack index.js
1

打包结果:

webpack打包结果

正如上面你所看到的那样,网页正确显示了我们期待的结果,这也是 Webpack 能为我们解决问题的一小部分能力,下面将正式开始介绍 Webpack 。