简介
https://github.com/webpack/webpack
https://www.webpackjs.com/
https://webpack.js.org/
为什么需要构建(打包)
开发分工变化
前端越来越复杂
框架的变化
JS库(例如jquery, yui, dojo, prototype, Mootools, kissy)
->MVC(jquery, backbone.js, underscore.js)
->MVP
->MVVM(Vue, React, Angular)
语言的变化
HTML1-3 HTML3.2; HTML4.0; XHTML1.0; HTML5
CSS1; CSS2; CSS2.1; CSS3; Sass; Less; stylus
VBscript; JavaScript; CoffeeScript; TypeScript
ES6
环境的变化
浏览器、移动端
社区的变化
GitHub、npm
工具的变化
GRUNT, Gulp, webpack
开发复杂化;框架去中心化(零散);语言编译化;开发模块化
为什么使用Webpack
Vue-cli/React-starter/Angular-cli
Code-splitting
天生的模块化
JS模块化
命名空间
COMMONJS(服务器端使用)
AMD/CMD/UMD
ES 6 module
库名.类别名.方法名
| var NameSpace = {}
NameSpace.type = NameSpace.type || {}
NameSpace.type.method = function () {
}
|
CommonJS
Modules/1.1.1
一个文件为一个模块
通过 module.exports 暴露模块接口
通过 require 引入模块
同步执行
AMD
Async Module Definition
使用 define 定义模块
使用 require加载模块
RequireJS
依赖前置,提前执行
CMD
Common Module Definition
一个文件为一个模块
使用 define 来定义一个模块
使用 require 来加载一个模块
SeaJS
尽可能懒执行
UMD
Universal Module Definition
通用解决方案
三个步骤:判断是否支持AMD;判断是否支持CommonJS;如果都没有 使用全局变量
ESM
EcmaScript Module
一个文件一个模块
export/import
Webpack支持
AMD(RequireJS)
ES Modules(推荐的)
CommonJS
CSS 模块化
CSS 模式设计
OOCSS; SMACSS; Atomic CSS; MCSS; AMCSS; BEM
CSS Modules
面向过程
index.html
1
2
3
4
5
6
7
8
9
10
11
12 | <!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>这是最原始的网页开发</title>
</head>
<body>
<p>这是我们的网页内容</p>
<div id='root'></div>
<script src="./index.js"></script>
</body>
</html>
|
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13 | var dom = document.getElementById('root')
var header = document.createElement('div')
header.innerText = 'header'
dom.append(header)
var sidebar = document.createElement('div')
sidebar.innerText = 'sidebar'
dom.append(sidebar)
var content = document.createElement('div')
content.innerText = 'content'
dom.append(content)
|
面向对象
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | <!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>这是最原始的网页开发</title>
</head>
<body>
<p>这是我们的网页内容</p>
<div id='root'></div>
<script src="./header.js"></script>
<script src="./sidebar.js"></script>
<script src="./content.js"></script>
<script src="./index.js"></script>
</body>
</html>
|
<script src="./index.js"></script>
要放在最下面
index.js
| var dom = document.getElementById('root')
new Header()
new Sidebar()
new Content()
|
header.js
| function Header() {
var header = document.createElement('div')
header.innerText = 'header'
dom.append(header)
}
|
sidebar.js
| function Sidebar() {
var sidebar = document.createElement('div')
sidebar.innerText = 'sidebar'
dom.append(sidebar)
}
|
content.js
| function Content() {
var content = document.createElement('div')
content.innerText = 'content'
dom.append(content)
}
|
面向对象的方式编程代码还是不是很容易维护
ES Moudule 模块引入方式
index.js
| import Header from './header.js'
import Sidebar from './sidebar.js'
import Content from './content.js'
var dom = document.getElementById('root')
new Header()
new Sidebar()
new Content()
|
但是浏览器不支持这种写法
简单使用webpack
所以需要 webpack 进行翻译给浏览器
index.js
| import Header from './header.js';
import Sidebar from './sidebar.js';
import Content from './content.js';
new Header();
new Sidebar();
new Content();
|
sidebar.js
| function Sidebar() {
var dom = document.getElementById('root');
var sidebar = document.createElement('div');
sidebar.innerText = 'sidebar';
dom.append(sidebar);
}
export default Sidebar;
|
content.js
| function Content() {
var dom = document.getElementById('root');
var content = document.createElement('div');
content.innerText = 'content';
dom.append(content);
}
export default Content;
|
header.js
| function Header() {
var dom = document.getElementById('root');
var header = document.createElement('div');
header.innerText = 'header';
dom.append(header);
}
export default Header;
|
npm init
npm install webpack-cli --save-dev
npm install webpack --save-dev
使用npx webpack index.js
翻译
会生成一个dist
目录,目录下有一个main.js
然后可以改变index.html
的写法
1
2
3
4
5
6
7
8
9
10
11
12 | <!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>这是最原始的网页开发</title>
</head>
<body>
<p>这是我们的网页内容</p>
<div id='root'></div>
<script src="./dist/main.js"></script>
</body>
</html>
|
什么是模块打包工具
webpack 是一个模块打包工具
import后面的内容就是一个模块
除了 ES Moudule 模块引入方式;还有ComoonJS模块引入规范、CMD、AMD等
ES Moudule 引入方式写法
index.js
| var Header = require('./header.js');
var Sidebar = require('./sidebar.js');
var Content = require('./content.js')
new Header();
new Sidebar();
new Content();
|
sidbar.js
| function Sidebar() {
var dom = document.getElementById('root');
var sidebar = document.createElement('div');
sidebar.innerText = 'sidebar';
dom.append(sidebar);
}
module.exports = Sidebar;
|
content.js
| function Content() {
var dom = document.getElementById('root');
var content = document.createElement('div');
content.innerText = 'content';
dom.append(content);
}
module.exports = Content;
|
header.js
| function Header() {
var dom = document.getElementById('root');
var header = document.createElement('div');
header.innerText = 'header';
dom.append(header);
}
module.exports = Header;
|
最早webpack是一个js的模块打包工具
随着发展,可以打包任何形式的模块(例如css、图片等)
正确安装方式
| ➜ ~ node -v
v12.4.0
➜ ~ npm -v
6.11.3
mkdir webpack-demo
cd webpack-demo
npm init
Is this OK? (yes) yes
|
| {
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
|
添加"private": true,
,去掉"main": "index.js",
和"test": "echo \"Error: no test specified\" && exit 1"
| {
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {},
"author": "NoCilantro",
"license": "ISC"
}
|
全局安装:
| npm install webpack webpack-cli -g
➜ ~ webpack -v
4.41.0
➜ ~ webpack-cli -v
3.3.9
|
不建议全局安装 webpack
卸载全局的webpack
| npm uninstall webpack webpack-cli -g
➜ ~ webpack-cli -v
zsh: command not found: webpack-cli
➜ ~ webpack -v
zsh: command not found: webpack
|
项目内安装 webpack
npm install webpack webpack-cli --dev
或者npm install webpack webpack-cli -D
使用npx
运行项目内的webpack
| ➜ webpack-demo npx webpack -v
4.41.0
|
安装指定版本的 webpack
| ➜ nocilantro mkdir webpack-demo2
➜ nocilantro cd webpack-demo2
➜ webpack-demo2 npm init -y
➜ webpack-demo2 npm install webpack@4.16.5 webpack-cli -D
➜ webpack-demo2 npx webpack -v
4.16.5
|
在其它地方运行:
| ➜ webpack-demo2 rm -r node_modules
➜ webpack-demo2 npm install
➜ webpack-demo2 npx webpack -v
4.16.5
|
配置文件
默认配置文件:webpack.config.js
在其中写入
| const path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'bundle')
}
}
|
执行npx webpack
即可进行打包
生成一个bundle
目录,目录中有一个bundle.js
文件
可以指定配置文件:npx webpack --config xxx.js
npm scripts 方式进行打包:
修改package.json
文件中scripts
中的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | {
"name": "lesson",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"bundle": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9"
}
}
|
此时运行npm run bundle
即可进行打包
webpack-cli使得可以在命令行中使用命令
打包知识点
是
| entry: {
main: './src/index.js',
}
|
的简写
| Asset Size Chunks Chunk Names
bundle.js 1.36 KiB 0 [emitted] main
|
所以Chunk Names
是main
默认mode
是production
| const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
|
production
会将打包出的内容压缩
设置为development
mode: 'development',
不会压缩打包出的代码