Webpack
本质上是一个Javascript
应用程序的静态模块打包器(module bundler),当应用程序经Webpack
处理时, 会从入口文件开始,递归地构建整个应用所依赖的关系图,其中包含应用程序需要的每个模块;然后将所有这些模块打包成一个或多个bundle
文件.
Webpack核心概念
Webpack
是一个打包模块化Javascript
工具,在Webpack
里一切文件(html、js、jsx、less、css、图片)皆模块,进Webpack
对模块组合打包处理后生成浏览器能直接使用的静态资源;通俗的说想要使用Webpack
,就需要搞明白Webpack
的打包原理,以及各个配置项的含义跟使用规则;Webpack
主要核心概念包括entry
、output
、module
、resolve
、plugins
等;
全局安装Webpack
命令
npm install webpack webpack-cli -g
局部安装Webpack
npm install Webpack Webpack-cli --save-dev
通常我们直接在命令行中执行Webpack
命令时,执行的是当前全局安装的Webpack
命令;当我们想要使用安装在项目内部中的Webpack
时,可以通过在package.json
文件中的script
脚本下定义执行Webpack
命令;项目中我们推荐使用局部命令,防止项目所需依赖包版本不同而导致冲突。
script: {
"build": "Webpack"
}
Webpack
在执行构建时默认会从项目根目录下的webpack.config.js
文件中读取配置,也可以通过命令行参数--config
指定配置文件名;由于Webpack
构建运行在Node.js
环境下,所以该文件最后需要通过CommonJS
规范导出一个描述如何构建的Object
对象
入口( entry )
配置模块入口;指定Webpack
执行构建的起点入口,来作为构建其内部依赖图的开始。可以是单入口或多入口:
用法 entry: String|Array|Object<String|Array>
/*
* String 单入口、单出口
* 这是最简单也最常用的入口起点配置方式,Webpack从该主入口文件递归构建依赖图,最终打包生成一个chunk输出
*/
module.exports = {
entry: "./main.js"
}
//Array 多入口,但是打包后也是生成单个出口文件
module.exports = {
entry: ["./main1.js","./main2.js"]
}
/*
* Object 多入口,每个入口生成一个Chunk
* 对象写法的可配置性最强,
*/
module.exports = {
entry:{
main1: "./main1.js",
main2: "./main2.js"
}
}
出口( output )
配置如何输出最终想要的代码,output
是一个Object
,里面包含一系列配置项;下面分别介绍它们:
path: 指明存放文件的目录地址, 必须是绝对路径,默认为/dist
filename: 打包生成的文件名, 可以配合entry使用占位符
占位符名称 | 含义 |
---|---|
id | 模块的唯一标识,从0开始 |
name | 模块名称 |
hash | 本次构建的hash |
chunkhash | chunk内容的hash |
[hash]和[chunhash]的长度是可以指定的,[hash:8]代表取8位hash值,默认20位
publicPath: 配置线上资源的URL
前缀, 当我们把打包生成后的资源文件托管到CDN
上时,就需要该配置项; 在前期写配置文件时我们可能还不知道输出文件的publicPath
, 可以先留空,后期可以直接在入口文件中通过使用自由变量 __webpack_public_path__
来设置
module.exports = {
output:{
path:path.resolve(__dirname, './dist'),
filename: 'bundle.js'
}
}
crossOriginLoading: Webpack
输出的部分代码块可能需要异步加载,而异步加载是通过JSONP
方式实现的,JSONP
的原理是动态的向HTML
中插入一个标签,通过src
去加载跨域资源;而这个crossOriginLoading
就是用来设置这个值:
- false: 禁止跨域加载(默认)
- anonymous : 在加载此脚本资源时不会带上用户的Cookies
- use-credentials: 在加载此脚本资源时带上用户的Cookies
模块( module )
配置处理模块规则;Webpack
默认只能处理js
或json
文件,module
选项决定如何处理这些其他类型的文件
rules: 配置模块的读取和解析规则,通常用于配置loader
。对于其他类型的文件需要使用各种loader
将其转化为Webpack
能够处理的文件,然后再构建打包输出。这可以使我们打包除JavaScript
之外的任何资源;常用loader
file-loader
对文件不做任何处理,直接输出到指定文件夹,并返回相对URL, 输出的文件名可配置
module: {
rules: [
{
test: /\.(png|jpg|jpeg)$/,
use: {
loader: 'file-loader',
options: {
name: [name]-[hash].[ext] ,
outputPath: 'imgs',
publicPath: 'assests/'
}
}
}
]
}
/** placeholders 占位符
* name:资源文件原名称
* hash:根据文件内容生成的哈希值
* ext:资源文件扩展名
*/
url-loader
功能类似于file-loader
,但是在文件大小低于指定限制时,可以返回base64
的DataURL
;大于制定限制时,功能同file-loader
一样,不做任何处理直接输出到目标文件夹内。
module: {
rules: [
{
test: /\.(png|jpg|jpeg)$/,
use: {
loader: 'url-loader',
options: {
limit: '1024'
}
}
}
]
}
/** placeholders 占位符
* name:资源文件原名称
* hash:根据文件内容生成的哈希值
* ext:资源文件扩展名
*/
css相关loader
less-loader: 将less转换为css
css-loader: 将css转换为CommomJs模块
style-loader: 创建style标签,将css添加到页面中
noParse:可以让Webpack
忽略跳过那些没采用模块化的文件,从而提高构建性能。
解析( resolve )
配置寻找模块规则,设置模块如何被解析;Webpack
在启动后会从配置的入口模块出发找出所有依赖的模块,resolve
配置Webpack
如何寻找模块所对应的文件。
alias
给常用路径配置别名,可以减少模块路径解析时间,也方便文件在不同地方引用
module.exports = {
resolve: {
alias: {
"react": '/node_modules/react/react.min.js'
}
}
}
extensions:在导入语句没带文件后缀时,Webpack
会自动带上后缀去尝试访问文件是否存在,默认['.js', '.json']
modules:配置Webpack
去那些目录下寻找第三方模块,默认node_modules
文件夹
devtool
控制是否生成,以及如何生成source map
;不同格式的source map
值回明显影响到构建和重构建的速度
那么何为source map
? 通常我们用于部署到生产环境的代码,一般是经过压缩后的(删除了注释、空格、换行等不必要的字符串)来减小代码体积。当代码出错调试时,我们就无法在控制台快速定位到问题位置,这就是source map
想要解决的问题。
plugins
用于扩展Webpack
的功能,可以让Webpack
做任何与构建有关的事情,Plugin
的配置也很简单,Plugins 配置项接收一个数组,数组里的每一项都是一个要使用new关键字生成的
Plugin的实例,
Plugin`需要的参数都是通过构造函数传入。常用的一些插件:
html-webpack-plugin
clean-webpack-plugin
DevServer
DevServer
会启动一个http
服务器用于服务网页请求,同时会帮助启动Webpack
,并接收Webpack
发出的文件变更信号,通过WebSocket
协议自动刷新网页做到实时预览。
host: 指定要使用的host
port:指定监听的端口
proxy:配置服务代理
hot:启用模块热替换功能,DevServer
的默认行为是在发现源代码被更新后通过自动刷新整个页面来做到实时预览,开启热模块替换功能后,将在不刷新整个页面的情况下,通过用新模块替换老模块来做到实时预览
contentBase:devServer.contentBase
配置DevServer
服务器的文件根目录,默认情况下为当前的执行目录(即配置文件所在目录)
open:服务启动后,自动打开默认浏览器
compress:为每个静态文件开启gzip
,为boolean
类型,默认值为false