阅读《深入浅出的webpack》:入门
一、安装webpack
【要确保系统需安装5.0.0及以上版本的node.js】
1、安装webpack到本地项目:
安装Webpack到本项目时,可根据自己的需求选择以下任意命令运行:
# npm i -D 是npm install --save-dev的简写,是指安装并保存到package.json的devDependencies
# 安装最新的稳定版
npm i -D webpack
# 安装指定版本
npm i -D webpack@<version>
# 安装最新的体验版本
npm i -D webpack@beta
安装完成后,我们可以通过一下途径运行安装到本项目的Webpack:
a. 在项目根目录下对应的命令行里通过node_modules/.bin/webpack运行Webpack的可执行文
件。
b. 在Npm Script里定义的任务会优先使用本项目下的webpack,代码如下:
json "scripts":{"start":"webpack--config webpack.config.js"}
2、安装webpack到全局
npm i -g webpack
二、使用webpack
由于Webpack构建运行在Node.js环境下,所以该文件最后需要通过CommonJS规范导出一个描述如何构建的
Object对象。
此时,项目目录如下:
index.html main.js show.js webpack.config.js
使用示例:
1)页面入口文件index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="app"></div>
<!--导入webpack输出的javascript文件-->
<script src="./dist/bundle.js"></script>
</body>
</html>
2)存放工具函数的show.js文件的内容:
// 操作DOM元素,将content显示到网页上
function show(content){
window.document.getElementById('app').innerText = 'Hello,' + content;
}
// 通过CommonJS规范导出show函数
module.exports = show;
3)包含执行入口的main.js文件的内容如下:
// 通过CommonJS规范导入show函数
const show = require('./show.js')
// 执行show函数
show('Webpack');
4)webpack新建时默认会从项目根目录下的webpack.config.js文件中读取配置,所以我们还需新建它,
其内容如下:
const path = require('path');
module.exports = {
// Javascript执行入口文件
entry: './main.js',
output: {
// 将所有依赖的模块合并输出到一个bundle.js文件
filename: 'bundle.js',
// 将输出文件都放到dist目录下
path: path.resolve(_dirname,'./dist')
}
};
三、使用Loader
Loader可以看作是具有文件转化功能的翻译员,配置里的module.rules数组配置了一组规则,告诉
webpack在遇到哪些文件时使用哪些Loader去加载和转换。
配置Loader时的注意事项:
a. use属性的值需要是一个由Loader名称组成的数组,Loader的执行顺序是由后到前的。
b. 每个Loader都可以通过URL querystring的方式传入参数,例如:
css-loader?minimize中的minimize来告诉css-loader要开启CSS压缩
c. 向Loader传入属性的方式除了通过querystring实现,还可以通过Object实现:
use:[
'style-loader',
{
loader:'css-loader',
options:{
minimize:true,
}
}
]
在重新执行webpack构建前,要先安装新引入的Loader:
npm i -D style-loader css-loader
【注:
除了在webpack.config.js配置文件中配置Loader,还可以在源码中指定用什么Loader去处理文件。
例:修改上例中的main.js,如下:
require('style-loader!css-loader?minimize!./main.css');
这样就能指定对 ./main.css这个文件先采用css-loader再采用style-loader进行转换。
】
四、使用Plugin
Plugin是用来扩展webpack功能的,通过在构建流程里注入钩子实现,它为webpack带来了很大的灵活性。
示例:
通过Plugin将注入bundle.js文件里的CSS提取到单独的文件中,配置修改如下:
首先安装新引入的插件:
npm i -D extract-text-webpack-plugin
const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
// javascript执行入口文件
entry: './main.js',
output: {
// 将所有依赖的模块合并输出到一个bundle.js文件中
filename: 'bundle.js',
// 将输出文件都放到dist目录下
path: path.resolve(_dirname, './dist'),
},
module:{
rules: [
{
// 用正则去匹配要用该Loader转换的CSS文件
test: /\.css$/,
loaders: ExtractTextPlugin.extract({
// 转换.css文件需要使用的Loader
use: ['css-loader'],
}),
}
]
},
plugins: [
new ExtractTextPlugin({
// 从 .js文件提取出来的 .css文件的名称
filename: `[name]_[contenthash:8].css`,
}),
]
}
执行构建后,dist目录下多出一个main——1a87a56a.css文件,bundle.js文件里也没有CSS代码了,再将该文件引入index.html里就完成了。
注:webpack是通过plugins属性来配置需要使用的插件列表的。plugins属性是一个数组,里面的每一项都是插件的一个实例,在实例化一个组件时可以通过构造函数传入这个组件支持的配置属性。
五、使用DevServer
1、原因:
以上几节可让Webpack正常运行起来,但在实际开发中可能会需要:
1)提供HTTP服务而不是使用本地文件预览
2)监听文件的变化并自动刷新网页,做到实时预览
3)支持Source Map,以方便调试
注:webpack支持上述第2、3点内容,再结合官方提供的开发工具DevServer可以很方便的做到第 1 点。
2、作用:
DevServer会启动一个HTTP服务器用于服务网页请求,同时会帮助启动Webpack,并接收Webpack发出
的文件更变信号,通过WebSocket协议自动刷新网页做到实时预览。
3、使用方法:
首先需要安装DevServer:
npm i -D webpack-dev-server
安装成功后:
执行 webpack-dev-server命令,可启动 DevServer
启动后,控制台会有一串日志输出:
Preject is running at http://locahost:8080/
wepack output is served from /
4、实时预览
webpack在启动时可以开启监听模式,之后webpack会监听本地文件系统的变化,在发生变化时重
新构建出新的结果。webpack默认关闭监听模式,我们可以在启动webpack时通过webpack --watch来
开启监听模式。
通过DevServer启动的webpack会开启监听模式,当发生变化时重新执行构建,然后通知
DevServer。DevServer会让Webpack在构建出的Javascript代码里注入一个代理客户端用于控制网页
,网页和DevServer之间通过WebSocket协议通信,以方便DevServer主动向客户端发送命令。
DevServer在收到来自Webpack的文件变化通知时,通过注入的客户端控制网页刷新。
如果尝试修改index.html文件并保存,则我们会发现这并不会触发以上机制,导致这个问题的原因
是webpack在启动时会以配置里的entry为入口去递归解析出entry所依赖的文件,只有entry本身和依
赖的文件才会被Webpack添加到监听列表里。而index.html文件时脱离了Javascript模块化系统的,所
以webpack不知道它的存在。
5、模块热替换
作用:
模块热替换能做到在不重新加载整个网页的情况下,通过将已更新的模块替换老模块,再重新执
行一次来实现实时预览。
优点:
模块热替换相对于默认的刷新机制能提供更快的响应速度和更好的开发体验。
使用:
模块热替换默认是关闭的,要开启模块热替换,只需在启动DevServer时带上--hot参数,重启
DevServer后再去更新文件就可体验到模块热替换的效果了。
6、支持Source Map
原因:
在浏览器中运行的Javascrpt代码都是编译器输出的代码,这些代码的可读性很差。如果在开发过
程中遇到一个不知道原因的bug,则我们可能需要通过断点调试去找出问题。在编译器输出的代码上进
行断点调试是一件辛苦且不优雅的事情。
作用:
调试工具可以通过Source Map映射代码,让我们在源代码上断点调试。
使用:
webpack支持生成Source Map,只需在启动时带上--devtool source-map参数,重启DevServer后
刷新页面,再打开Chrome浏览器的开发者工具,就可以在Sources栏中看到可调试的源代码了
六、webpack核心概念:
Entry: 入口,Webpack执行构建的第一步将从Entry开始,可抽象成输入。
Module: 模块,在Webpack里一切皆模块,一个模块对应一个文件。Webpack会从配置的Entry开始
递归找出所有依赖的模块。
Chunk: 代码块,一个Chunk由多个模块组合而成,用于代码合并与分割。
Loader: 模块转换器,用于将模块的原内容按照需求转换成新内容。
Plugin: 扩展插件,在webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果或做我们想要
的事情。
Output: 输出结果,在webpack经过一系列处理并得出最终想要的代码后输出结果。
这些概念是如何工作的?
webpack在启动后会从Entry里配置的Module开始,递归解析Entry依赖的所有Module。每找到
一个Module,就会根据配置的Loader去找对应的转换规则,对Module进行转换后,再解析出当前
Module依赖的Module。这些模块会以Entry为单位进行分组,一个Entry及其所有依赖的Module被分
到一个组也就是一个Chunk。最后,webpack会将所有Chunk转换成文件输出。在整个流程中,
webpack会在恰当的时机执行Plugin里定义的逻辑。