一、什么是webpack
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。在3.0出现后,Webpack还肩负起了优化项目的责任。
有三个重点:
- 打包:可以把多个
js
打包成一个文件,减少服务器压力和下周带宽。 - 转换:把拓展语言转换成普通的
js
,让浏览器顺利运行。 - 优化:前端变得越来越复杂之后,性能也会遇到问题,而
webpack
也开始肩负起了优化和提升性能得责任。
安装 Webpack
// 全局
npm install -g webpack
// 局部安装
npm install webpack@3.6 --save-dev
如果安装失败,一般三种可能:
- 检查你的 node 版本号,如果太低,升级为最新
- 网络问题,可以使用 cnpm
- 权限问题,在 liux、mac 安装时需要权限的,windows,可以使用管理员方式安装
注意:全局安装是可以,但是 webpack 不推荐,这会将您项目中的 webpack 指定到某个版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。
对项目目录进行安装
安装前,需要进行初始化,其目的就是生成 package.json 文件
npm init
然后执行 局部安装 webpack 命令
npm install [email protected] --save-dev
--save 是要保存到 package.json 中, dev 是在开发的时候使用这个包,而生产环境中不使用。
二、快速写个demo
建立基本的项目结构
随便新建个文件夹,然后 初始化 npm init
,然后局部安装 webpack npm install [email protected] --save-dev
,在根目录下新建 dist、src目录。
dist 下新建 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="./bundle.js"></script>
</body>
</html>
bundle.js 是没有的,是 webpack 打包之后生成的 js 文件
在 src 下新建 entery.js,项目的入口文件
document.getElementById('app').innerHTML = 'hello webpack'
第一次webpack打包
webpack 可以在终端使用:
// 3.6
webpack entery.js bundle.js
// 在4 之后的版本,更加严格
webpack ./src/entery.js --output-filename bundle.js
执行完打包命令之后,dist 目录下会生成一个 bundle.js 文件
配置文件:入口和出口
上面对webpack有了初步的了解,但是在终端打包在实际开发中并不实用,而是使用 webpack 的配置文件的方式进行设置。
配置文件 webpack.config.js
webpack.config.js
就是 webpack 的配置文件,这个文件需要自己手动在项目根目录下添加,如下是一个没有内容的标准 webpack 配置模板
// webpack.config.js
module.exports = {
// 入口文件的配置项
entry: {
},
// 出口文件的配置项
output: {
},
// 模块:例如解析css,图片转换,压缩等
module: {
},
// 插件:用于生产模板和各项功能
plugins: [],
// 配置 webpack 的开发服务功能
devServer: {
}
}
- entry:配置入口文件地址,可以是单一入口,也可以是多入口
- output:配置出口文件的地址,在 webpack2.x 之后,支持多出口配置
- module:配置模块,主要是解析CSS和图片转换压缩等功能
- plugins:配置插件,根据你的需要配置不同功能的插件
- devServer:配置开发服务功能,后期我们会详细讲解
entry 选项(入口配置)
这个选项就是配置我们要压缩的文件,一般为 js 入口文件,当前css...也可以
entry: {
entry: './src/entery.js'
},
output 选项(出口配置)
出口配置用来告诉 webpack 最后打包文件的地址和文件名称的。在编写出口文件时,需要一点 node
知识
const path = require('path'); // webpack.config.js 先引入 path 模块
output: {
// 打包生成的目录
path: path.resolve(__dirname, 'dist'),
// 打包生成的文件名称
filename: 'bundle.js'
},
配置完之后,可以直接 webpack 命令进行打包
多入口、多出口配置
const path = require('path');
module.exports = {
// 入口文件的配置项
entry: {
entry: './src/entery.js',
// 这里又引入了一个 js 入口文件
entry1: './src/entery1.js'
},
// 出口文件的配置项
output: {
// 打包生成的目录
path: path.resolve(__dirname, 'dist'),
// 打包生成的文件名称
filename: '[name].js' // [name] 对应入口文件的名称(多个)
},
// 模块:例如解析css,图片转换,压缩等
module: {
},
// 插件:用于生产模板和各项功能
plugins: [],
// 配置 webpack 的开发服务功能
devServer: {
}
}
需要注意的是,在多入口文件配置中,增加了一个 entert.js 的入口文件,此时两个入口文件。
多出口配置中,我们把原来的bundle.js修改成了[name].js
[name]
的意思是根据入口文件的名称,打包成相同的名称,有几个入口文件,就可以打包出几个出口文件。
运行 webpack 命令打包测试一下,如下:
配置文件:服务和热更新
设置 webpack-dev-server
需要先 npm install webpack-dev-server --save-dev
来进行安装。安装之后在 devServer
中配置。最简单的配置为四项。
webpack.config.js
devServer: {
// 设置基本目录结构
contentBase: path.resolve(__dirname, 'dist'),
// 服务器的ip地址,可以使用ip也可以用localhost
host: 'localhost',
// 服务器压缩是否开启
compress: true,
// 配置服务端口号
port: 8082
}
- contentBase:配置服务器基本运行路劲,用于找到程序打包地址
- host:服务器运行地址,建议使用本机 ip,也可以使用 localhost
- compress:服务器端压缩选型,一般设置为开启
- port:服务运行端口,不建议
80
,容易被占用
配置好之后,可以在 终端输入 webpack-dev-server,可能成功,但一般都是如下错误:
此时需要在 package.json
里面配置一下scripts 选项:
"scripts": {
"server": "webpack-dev-server"
},
配置保存之后,在终端运行 npm run server
,如果成功,在浏览器地址栏输入http://localhost:1717就可以看到结果了。
注意:也可能报错如下信息
经过排查,是由于 webpack 与 webpack-dev-server
版本不兼容问题。以下版本是兼容的:
webpack 3.x 要使用 webpack-dev-server 2.x
webpack 4.x 要使用 webpack-dev-server 3.x
只需要重新安装对应的版本,就可以运行成功了。
支持热更行
在 npm run server
启动之后,它是有一种监控机制的(也叫watch)。可以监控到我们修改的源码,并立即进行自动编译,在浏览器中自动更新。
在 3.6 之前要支持热更新还需要更多的操作。
模块:css文件打包
loaders
loaders 是 webpack 最重要的功能之一,也是 webpack 如此盛行的原因。通过使用不同的 loader,webpack 可以的脚本和工具,从而对不同的文件格式进行特定的处理。
loader使用举例:
- 可以把
sass
文件的写法转换成 css,而不在使用其他工具转换。 - 可以把
es6 或者更高的代码
,转换成大多浏览器能兼容的 js 代码。 - 可以把
react 中的 jsx
转成 js 代码
注意:所以需要使用的 loaders 都需要在 npm 中单独安装,并且在 webpack.config.js 进行配置,如下是简单的配置说明”
test
用于匹配处理文件的扩展名的表达式,这个是必须配置的use
loader 名称,就是你要使用模块的名称,也是必须配置include/exclude
手动添加必须要处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹),配置是可选
的query
为 loaders 提供额外的设置选择,配置是可选
的
打包css文件
在 src 先新建 css/index.css
body{
background-color: red;
color: white;
}
建立 css 文件之后,需要 引入到入口文件中:
import './css/index.css'
之后在 webpack 打包编译的时候,就需要使用 loader 来解析 css 文件了。这里我们需要使用两个 loader,为 style-loader
和 css-loader
style-loader:
是用来处理 css 文件中的 url() 等, 说明文档
npm install style-loader --save-dev // 进行安装
css-loader:
是用来将 css 插入到页面的 style 标签中,说明文档
npm install css-loader --save-dev // 进行安装
loaders配置
在 webpack.config.js 中,对 module 属性配置如下:
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
配置全部完成之后,运行 npm run server 进行编译,编译完成之后,浏览器中可能会有如下报错:
因为现在使用的是 webpack3.6版本,css-loader和style-loader 版本过高导致的,需要修改为 webpack3.6 兼容的版本
"css-loader": "^2.0.2",
"style-loader": "^0.23.1",
然后重新编译就可以了。
插件配置:配置 js 压缩
loader的三种写法:
第一种写法:直接用 use
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
},
第二种写法:把use换成loader
module:{
rules:[
{
test:/\.css$/,
loader:['style-loader','css-loader']
}
]
},
第三种写法:用 use + loader 的写法
module:{
rules:[
{
test:/\.css$/,
use: [
{
loader: "style-loader"
}, {
loader: "css-loader"
}
]
}
]
},
压缩 js 代码:
需要引入 uglifyhs-webpack-plugin
注意: 虽然 uglifyjs 是插件,但是 webpack 版本里面默认已经集成,不需要再次安装。
只需要在 webpack.config.js 中引入
const uglify = `require`('uglifyjs-webpack-plugin');
然后在 plugins 配置里面使用:
plugins:[
new uglify()
],
配置完之后, 重新 编译 npm run server,可以看到代码已经被压缩
插件配置:html文件的发布
现在我们的项目结构是有问题的,我们把index.html直接放到了dist文件夹下,这肯定是不正确的,应该放到我们src目录下
打包html文件
我们先把dist中的html文件剪切到src目录中,并去掉我们的JS引入代码(webpack会自动为我们引入JS),因为这才是我们真实工作的目录文件结构
然后我们配置webpack.config.js文件,先引入我们的html-webpack-plugin插件
const htmlPlugin= `require`('html-webpack-plugin');
安装
npm install --save-dev html-webpack-plugin
最后在webpack.config.js里的plugins里进行插件配置,配置代码如下:
plugins: [
new uglify(), // 使用 js 压缩插件
new htmlPlugin({
minify: {
removeAttributeQuotes: true
},
hash: true,
template: './src/index.html'
})
],
- minify:是对 html 文件进行压缩,removeAttrubuteQuotes 是去掉属性的双引号
- hash:为了开发中 js 有缓存效果,所以加入 hash,这样可以有效避免缓存 js
- template:是要打包的 html 模板路劲和文件名称
之后运行编译,有可能报错,是因为 html-webpack-plugin 版本与 webpack3.6不兼容导致的,可以将 html-webpack-plugin 版本将为 2.30.1 即可
wenbpack3.6
常用包兼容版本:
配置 webpack 打包
在package.json 中
"scripts": {
"build": "webpack"
},
然后运行 npm run build
html文件的打包可以有效的区分开发目录和生产目录,在webpack的配置中也要搞清楚哪些配置用于生产环境,哪些配置用于开发环境,避免两种环境的配置冲突。