一、Webpack简介
1. 核心
① 入口(entry)
② 输出(output)
③ loader
④ 插件(plugins)
2. 优势
① 模块化开发(import,require)
② 预处理(Less,Sass,ES6,TypeScript……)
③ 主流框架脚手架支持(Vue,React,Angular)
④ 庞大的社区(资源丰富,降低学习成本)
详情请戳→我为什么要使用Webpack?
3. 初学者误区
① 要学会node.js
② 只能用于简单的代码压缩合并
③ 上线时要将整个项目文件上传服务器
以上几条都是初学者比较容易产生的误区,而事实上……
① 我们确实需要安装node.js,但基本只是需要它提供的环境及npm而已,你不一定要掌握node.js语法
② Webpack非常强大,不仅仅可以实现代码的压缩合并,还能进行一些预编译处理以及模块化开发等
③ 我们只需要将Webpack打包出来的文件目录上传到服务器即可,而不是上传整个项目文件
二、准备工作
1. 安装node.js
2. 新建项目
① 创建目录结构
在新创建的项目文件夹下,创建两个基础文件夹:src和dist,其中src是我们开发时源代码所放置的文件夹,dist是我们使用Webpack打包后代码输出的目标文件夹,也就是说最终我们上传服务器的代码都是从dist文件夹下获取。目录结构大致如下:
image② 新建一个package.json文件
package.json文件是在node.js环境下开发项目必须要使用到的文件,该文件主要用于配置项目入口、脚本和项目所需安装的依赖等等。我们可以自己手动创建,也可以通过命令行自动创建它。命令行创建很简单,直接在控制台终端输入npm init
,然后一直回车即可轻松创建一个最基础的package.json文件。
{
"name": "webpackdemo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
image小贴士: 建议使用开发工具中自带的控制台终端,非常方便,自动定位当前项目文件夹,无需手动切换。比如我使用的开发工具是WebStorm,控制台终端如下图:
3. 安装Webpack
依次输入命令行npm i -D webpack
和npm i -D webpack-cli
回车进行本地安装,其中i
是install
的缩写,-D
是--save-dev
的缩写,也就是说这两个命令行也可以写成npm install --save-dev webpack
和npm install --save-dev webpack-cli
。
安装后的目录结构如下:
imagepackage.json文件如下:
{
"name": "webpackdemo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.5.0",
"webpack-cli": "^2.0.14"
}
}
4. 新建webpack.config.js文件
该文件是Webpack的配置文件,也是项目运行的入口文件,基础写法如下:
module.exports = {
entry: './src/scripts/index.js', // 需要被打包的js文件路径及文件名
output: {
path: __dirname + '/dist', // 打包输出的目标文件的绝对路径(其中__dirname为当前目录的绝对路径)
filename: 'scripts/index.js' // 打包输出的js文件名及相对于dist目录所在路径
}
};
三、开始打包
1. 新建需要被打包的js文件
image我们给这个index.js文件写入点代码:
//index.js
alert('Hello Webpack!');
2. 开始打包
输入命令行:
npx webpack
,回车。
由于我们已经在webpack.config.js文件配置了打包的相关路径及文件名,所以最终打包后我们就可以在dist目录下看到我们想要的输出结果,打包后整体目录结构如下:
image3. 使用打包后的js代码
现在我们已经获得打包后的代码,接下来我们应该使用它,测试它是否能正常运行。
我们可以在dist目录下手动创建一个HTML文件,并引入这个已经打包成功的js文件。目录结构及HTML代码如下:
image<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="scripts/index.js"></script>
</body>
</html>
打开这个index.html页面后,我们发现浏览器弹出“Hello Webpack!”提示框,说明代码确实已经打包成功。
本文重点总结:
成功运行Webpack基本流程如下:
① 安装node.js
② 创建项目目录和新建package.json
③ 安装webpack和webpack-cli
④ 新建webpack.config.js
⑤ 开始打包你的js代码
<meta charset="utf-8">
二,打包css:
上一节讲到如何使用Webpack实现最基础的打包功能,但是发现以下几个比较突出的问题:
① 我们只打包了一个JS文件,多个文件该如何打包?
② CSS样式该如何打包?
③ 每次写完代码想要看运行结果都需要手动输命令打包,反而降低了开发效率
没关系,本文就是为解决这些问题而来的。继续上节实例,开始吧!
一、JS模块化
使用Webpack成功打包多个JS文件最核心的一点就是使用模块化的开发方式,而Webpack支持CommonJS和ES6两种模块化规范,其中有关CommonJS的语法可以看我之前的一篇文章→JavaScript模块化编程规范。本文也将以CommonJS规范来讲解Webpack中的JS模块化。
我们在scripts目录下添加一个module.js文件,目录结构如下:
image并写入以下代码:
// module.js
var text = 'Hello Webpack!';
module.exports = { // CommonJS规范中模块输出语法
text: text
};
然后在index.js中引入module.js文件:
// index.js
var module = require('./module.js'); // CommonJS规范中模块引入语法
alert(module.text); // 打包后同样输出“Hello Webpack!”
由于我们在上一节中已经对Webpack的打包入口和输出路径进行了基本配置,所以我们只需同样执行npx webpack
命令即可将两个JS文件进行打包输出到dist目录。
小贴士: 有时输入的命令比较长,我们可以将其写入package.json文件的
"scripts"
属性中。
改写后的package.json如下:
{
"name": "webpackdemo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.5.0",
"webpack-cli": "^2.0.14"
}
}
接着我们只需执行npm run start
命令即可(或直接输入npm start
)。
二、打包CSS样式
1. loader简介
由于Webpack打包入口目前只配置了一个index.js文件,那么其他需要被打包的文件都必须通过模块化方式引入该文件才行,而默认情况下,引入的文件必须是js文件(如上面添加的module.js)。
那么其他文件类型该如何进行打包呢?
这时我们就要用到Webpack中所提供的各种loader,它就是专门用于处理除JS文件之外的其他格式文件的编译、提取、合并、打包等工作的。
其中CSS文件的打包需要用到css-loader和style-loader两个loader,css-loader只是用于加载css文件(并没有添加到页面),而style-loader则是将打包后的css代码以<style>标签形式添加到页面头部。
2. 安装loader
输入命令npm i -D css-loader style-loader
同时安装这两个loader,安装结束后再在webpack.config.js文件中配置相应的loader,具体配置如下:
// webpack.config.js
module.exports = {
entry: './src/scripts/index.js', // 打包入口
output: {
path: __dirname + '/dist', // 输出路径
filename: 'scripts/index.js' // 输出文件名
},
module: {
rules: [
{
test: /\.css$/, // 正则表达式,表示.css后缀的文件
use: ['style-loader','css-loader'] // 针对css文件使用的loader,注意有先后顺序,数组项越靠后越先执行
}
]
}
};
3. 开始打包
在css目录下新建一个style.css文件,并写入样式:
/* style.css */
html{ background: #f00;}
然后在index.js中引入该文件:
// index.js
var module = require('./module.js');
require('../css/style.css'); // 引入css样式
alert(module.text);
最后输入命令npm start
,打包完成后打开index.html页面后,你会发现除了弹出之前的“Hello Webpack!”外,页面背景颜色也变为红色,说明样式也已经打包成功。
三、自动化打包
通过上面的讲解你会发现,虽然我们已经将命令改成了npm start
,然而实际操作上还是得每次手动输入命令打包,不开心。
我们能不能像以前不用Webpack时那样,写完了直接刷新页面就能看到效果呢?
答案当然是可以的,我们只需在webpack.config.js中添加watch: true
就好。
module.exports = {
entry: './src/scripts/index.js',
output: {
path: __dirname + '/dist',
filename: 'scripts/index.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
},
watch: true // 监听修改自动打包
};
本文重点总结
① 打包多个文件为一个文件,必须使用模块化开发方式
② 先后使用css-loader和style-loader可以打包CSS样式并添加至页面
③ 想要自动化打包,只需在webpack.config.js文件中添加watch: true
打包图片
上一节我们讲到如何使用css-loader和style-loader两个loader来打包CSS代码,这次我将继续讲解如何使用loader将图片类型文件进行打包处理。
一、上节回顾
为了让大家思路更加明朗,我还是先将上一节结束时的目录结构和一些关键文件内容展示一下吧。
imagewebpack.config.js:
module.exports = {
entry: './src/scripts/index.js', // 打包入口
output: {
path: __dirname + '/dist', // 输出路径
filename: 'scripts/index.js' // 输出文件名
},
module: {
rules: [ // 其中包含各种loader的使用规则
{
test: /\.css$/, // 正则表达式,表示打包.css后缀的文件
use: ['style-loader','css-loader'] // 针对css文件使用的loader,注意有先后顺序,数组项越靠后越先执行
}
]
},
watch: true // 监听文件改动并自动打包
};
index.js:
var module = require('./module.js');
require('../css/style.css');
二、图片打包
图片打包关键要用到file-loader或url-loader,其中url-loader与file-loader功能基本一致,只不过url-loader能将小于某个大小的图片进行base64格式的转化处理。
1. CSS中的图片
比如,我现在在src目录下新增一个images文件夹,再在images中添加一张图片“1.jpg”。然后我在style.css中添加以下代码:
html{ height: 100%; background: url("../images/1.jpg") no-repeat center;}
如果这时直接进行打包,那么肯定会报错,比如像这样的:
image第三行它提示你需要使用一个loader来处理图片这种类型的文件,这时,我们只需把file-loader装上,并在webpack.config.js中添加相应配置就ok了。
① 输入命令安装file-loader
npm i -D file-loader
② 在webpack.config.js中的rules数组中添加file-loader的相关配置
{
test: /\.(png|jpg|gif|svg)$/,
use: ['file-loader']
}
其实对于只有单个loader的,我们还可以将其简化成下面这样:
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader'
}
接下来,我们只需执行npm start
命令进行打包即可。
虽然我们已经将图片但是打包后,我们会发现打包后的图片名发生了变化:
image那么如何才能保持图片名不变,而且也能够添加到指定目录下呢?
我们只需要再添加一个options属性即可:
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: 'images/[name].[ext]'
}
}
其中name属性其实就是图片打包后的路径,其中包括图片名([name])和图片格式([ext])。
此时打包后的dist目录结构如下:
image2. JS中的图片
file-loader能自动识别CSS代码中的图片路径并将其打包至指定目录,但是JS就不同了,我们来看下面的例子。
// index.js
var img = new Image();
img.src = '../images/1.jpg';
document.body.appendChild(img);
如果不使用Webpack打包,正常情况下只要路径正确图片是能够正常显示的。然而,当使用Webpack打包后,我们会发现图片并未被成功打包到dist目录,自然图片也无法显示出来。
这其实是因为Webpack并不知道'../images/1.jpg'是一张图片,如果要正常打包的话需要先将图片资源加载进来,然后再将其作为图片路径添加至图片对象。具体代码如下:
// index.js
var imgSrc = require('../images/1.jpg');
var img = new Image();
img.src = imgSrc;
document.body.appendChild(img);
3. 浅谈url-loader
除了使用file-loader对图片进行打包处理外,我们同样也可以使用url-loader代替,另外我们还可以对小于某个大小的图片进行base64格式的转化处理。
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'url-loader',
options: {
name: './images/[name].[ext]',
limit: 8192
}
}
这里limit属性的作用就是将小于8192B(8.192K)大小的图片转成base64格式,而大于这个大小的图片将会以file-loader的方式进行打包处理,例如:
image当然,如果不写limit属性,那么url-loader就会默认将所有图片转成base64。
小贴士: 当我们配置watch为true进行打包后,Webpack会一直处于监听状态,然而当更改webpack.config.js后我们仍需要重新进行打包操作,这时我们只需在控制台简单的按下Ctrl+C后根据提示输入字母y回车确定即可成功退出监听状态。
本文重点总结
① 使用file-loader或url-loader可对图片进行打包操作
② url-loader可将图片转成base64格式
打包html
到目前为止,有关Webpack最基础的内容差不多已经讲完了,其中包括Webpack运行的基本流程、CSS的打包和图片的打包,也就是说,当你掌握这几节之后,基本上就能像以前不用Webpack时一样愉快地写代码了。
当然,我们其实还有很多需要优化的地方,就比如本文所要讲到的,如何将HTML进行打包?
在之前的实例中,Webpack虽然能够正常地将各种页面所需要的资源从src目录打包至dist目录,但是我们在最后必须在dist目录中手动去创建HTML页面,并引入这些打包后的资源。
事实上,Webpack能够自动的帮助我们完成这件事,只需要使用html-webpack-plugin插件即可。
1. 安装html-webpack-plugin插件
与安装loader一样,命令行输入以下命令回车即可。
npm i -D html-webpack-plugin
2. webpack.config.js中添加相关配置
const htmlWebpackPlugin = require('html-webpack-plugin'); // 引入html-webpack-plugin插件
module.exports = {
entry: './src/scripts/index.js', // 打包入口
output: {
path: __dirname + '/dist', // 输出路径
filename: 'scripts/index.js' // 输出文件名
},
module: {
rules: [ // 其中包含各种loader的使用规则
{
test: /\.css$/, // 正则表达式,表示打包.css后缀的文件
use: ['style-loader','css-loader'] // 针对css文件使用的loader,注意有先后顺序,数组项越靠后越先执行
},
{ // 图片打包
test: /\.(png|jpg|gif|svg)$/,
loader: 'url-loader',
options: {
name: './images/[name].[ext]',
limit: 8192
}
}
]
},
plugins: [ // 打包需要的各种插件
new htmlWebpackPlugin({ // 打包HTML
template: './src/index.html' // HTML模板路径
})
],
watch: true // 监听文件改动并自动打包
};
3. 添加HTML模板文件
imageHTML模板文件如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Hello Webpack</title>
</head>
<body>
</body>
</html>
是的,除了HTML本身,其他资源如CSS、图片等均无需手动添加,在打包结束后,所有资源均会自动添加至HTML文件相应位置并进入dist目录。
4. 打包结束
image打包后的index.html文件如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Hello Webpack</title>
</head>
<body>
<script type="text/javascript" src="scripts/index.js"></script></body>
</html>
本文重点总结
打包HTML,使用 html-webpack-plugin 插件即可
自动更新
Webpack中的自动打包功能,很简单,在webpack.config.js中添加 watch: true 配置,打包一次之后每次代码更新后都会自动进行打包而无需重复输入命令行。
当然,我们也可以直接给package.json中的scripts添加相关配置,而无需更改webpack.config.js。
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "webpack --watch"
}
换句话说,package.json中的webpack --watch与webpack.config.js中的watch: true效果相同。
实际上,Webpack还提供了一个比watch更方便的功能,它不仅可以实现自动打包,还具有自动打开浏览器和自动刷新页面的功能,可以说给我们这帮懒人服务到了极致,哈哈。
下面我们就来看看具体如何实现这样的功能。
-
安装webpack-dev-server
npm i -D webpack-dev-server -
package.json中的scripts添加相关配置
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "webpack",
"dev": "webpack-dev-server --open"
}
其中 --open 就代表打开默认浏览器。 -
输入命令行进行打包
npm run dev
打包结束后你会发现浏览器自动打开,并且正确显示打包后的页面。 -
更改任意代码
我们可以试着在index.js中添加以下代码:
var module = require('./module.js');
alert(module.text);
module.js:
var text = 'Hello Webpack!';
module.exports = {
text: text
};
保存后你会发现浏览器自动刷新并弹出弹框“Hello Webpack!”。
值得注意的是,通过webpack-dev-server打包后的代码并不会进入dist目录,而是直接创建一个开发服务器,并运行打包后的代码。因此,通常我们会将Webpack打包分为两种模式:开发模式和生产模式。
开发模式顾名思义就是给我们开发时候用的,这时候我们就可以用上webpack-dev-server,从代码自动打包到自动开启浏览器再到自动刷新全部自动化,提高了工作效率;生产模式顾名思义就是最终代码上线时候用的,这时候我们就只需使用其最基础的打包功能,最终打包后的代码会进入dist目录,我们只需要将其上传服务器即可。
本文重点总结
① 使用 webpack-dev-server 可自动创建开发服务器,实现代码从自动打包到自动刷新页面的自动化开发模式
② Webpack有两种打包模式:开发模式和生产模式,开发模式下可使用 webpack-dev-server 提高开发效率
网友评论