文章目录
1、context – 配入口和loaders的基准路径
context: path.resolve(__dirname, "app")
context(上下文)配置会影响入口
和loaders
的解析,入口和loaders的相对路径会以context的配置作为基准路径,这样,你的配置会独立于CWD(current working directory 当前执行路径)
module.exports = {
mode: "development",
devtool: "source-map",
entry: {
//index: "./src/index.js",
//a:"./src/index.js"
index: "./index.js", // 2. 修改路径,为相对src的相对路径
a:"./index.js"
},
context: path.resolve(__dirname, "src") //1 . 这样配置后,相对路径是相对这个目录
}
命令行
中运行npx webpack的路径
,就是cwd,当前执行路径
,如果执行命令的位置改变,路径就不正确了默认``入口 和loaders
的相对路径 是相对当前webpack命令的执行路
- 配置 context 后,相对路径是相对与context指定的路径
__dirname
是当前运行的js –webpack.config.js 所在的路径
- 这样的好处,可以
让配置独立与当前执行路径
2、output
webpack 打包结果是一个自执行函数,library 用来处理把自执行结果暴露给谁
library – 工程,库–存入口文件导出的结果
var path = require("path")
module.exports = {
entry:{
index:"./src/index.js"
},
output:{
filename:"[name]-[hash:5].js",
path:path.resolve(__dirname, "target"), //打包的目录,默认是dist 目录,这里要写绝对路径
library:"abc", //打包结果是一个立即执行函数,把自执行函数的结果赋值给abc,这样暴露了一个变量abc,abc里是入口文件导出的结果
libraryTarget: "var"
}
}
library: "abc"
是打包后的结果中,会将自执行函数的执行结果暴露给abc
,abc里是入口文件导出的结果
libraryTarget
libraryTarget: "var"
该配置可以更加精细的控制如何暴露入口包的导出结果
- library 是暴露结果所存变量的名称,libraryTarget 是如何暴露
其他可用的值有:
var:默认值,暴露给一个普通变量 – 默认 var abc = …
window:暴露给window对象的一个属性
this:暴露给this的一个属性
global:暴露给global的一个属性
commonjs:暴露给exports的一个属性 – commonjs的语法暴露,exports[“abc”] =…
其他:https://www.webpackjs.com/configuration/output/#output-librarytarget
3、target – 构建的目标环境
target:"web" //默认值- 浏览器环境
设置打包结果最终要运行的环境
,常用值有:
- web: 打包后的代码运行在
web环境
中 - node:打包后的代码运行在
node环境
中
其他:https://www.webpackjs.com/configuration/target/
4、module.noParse – 不需要解析的模块
noParse: /jquery/
不解析正则表达式匹配的模块,通常用它来忽略那些大型的单模块库,以提高构建性能
- 例如jquery 用的就是打包后的代码,里面没有需要分析的依赖的,所以可以不再进一步解析了,这样可以提高打包的效率,和打包结果的执行效率无关
- 如果不是单模块,里面有依赖,放在noParse里会报错
5、resolve
resolve的相关配置主要用于控制模块解析过程
var path = require("path")
module.exports = {
mode: "development",
devtool: "source-map",
entry: {
index: "./index.js", // 2. 修改路径,为相对src的相对路径
a:"./index.js"
},
context: path.resolve(__dirname, "src"), //1 . 这样配置后,相对路径是相对这个目录
resolve:{
modules: ["node_modules"], //默认值 --当模块依赖没有./ 的时候,从这里开始查找
extensions: [".js", ".json",, ".css", ".vue", ".jsx"], //配置后 就不用写相应后缀名了
alias: { //别名
"@": path.resolve(__dirname, 'src'),
"_": __dirname
}
}
}
modules – 模块的查找位置
modules: ["node_modules"] //默认值 --当模块依赖没有./ 的时候,从这里开始查找
- 当解析模块时,如果遇到导入语句,
require("test"),webpack会从下面的位置寻找依赖的模块
,当模块依赖没有./ 的时候,从这里开始查找 - 值是一个数组,可以位置多个位置,第一个位置没有找到,依次查找
问题:如下,在./src/index.js里写了如下代码,这个代码会在node_modules里找jqery模块,这种
查找模块,是谁在查找
?
当前目录下的node_modules目录
上级目录下的node_modules目录
…// ./src/index.js var $ = require('jquery');
答:webapck 在查找,打包的时候,把require 后面的路径,
当作普通文件读出来,分析依赖
,不会运行这个文件
只是webpack查找方式,和 node 一样
,没有./ 就在node_modules里找,有的话再按相对路径找
问:如下代码,打包结果中,包含:
A. index 和 a
B. index
C. index 有可能有a// ./src/index.js if(Math.random() < 0.5){ require('./a') }
答: A , webpack 读取index.js文件内容后,
根据require 和 import 查找依赖
,只有有依赖 就肯定会打包
extensions – 配置 自动补全 后缀名
extensions: [".js", ".json"] //默认值
- 当解析模块时,遇到
无具体后缀的导入语句,例如require("test"),会依次测试它的后缀名
- 默认是js,json 当文件没有写后缀名的时候,会去查找相应目录下有没有a.js ,没有的话 再看有没有 a.json , 然后依次查找
extensions: [".js", ".json",, ".css", ".vue", ".jsx"] //配置后 就不用写相应后缀名了
问:为什么没有书写后缀名,仍然可以找到a.js
// ./src/index.js require('./a')
答:因为
webpack会自动补全后缀名
,根据 extensions 配置的自动补全
alias – 别名 - 方便导入依赖
alias: {
"@": path.resolve(__dirname, 'src'),
"_": __dirname
}
- 别名必须配置
绝对路径
- 工程很大时,源码结构
文件夹可能会嵌套很深
,比如下面的a 和 other.js同级,a/b/c/d.js要使用other.js , 使用别名更加方便的导入依赖
require("../../../other.js") //层次多了 就很混乱
require(@/other.js") // 如上配置了@ 指向src 路径,就可以直接再src下查找
- 有了alias(别名)后,导入语句中可以加入配置的键名,例如require("@/abc.js"),webpack会将其看作是require(src的绝对路径+"/abc.js")。
- 导入模块的时候,路径的书写,可以使用别名, 配置别名不影响打包结果中的路径
6、externals
externals: {
jquery: "$", //表示外部模块
lodash: "_"
}
- 没有这个配置的话,会再打包结果中,把jquery的源代码,放在打包文件的对应路径的属性值里,但我们实际希望,
打包结果里使用的juery 是cdn上的,打包结果里不需要存放jquery的源码
了
从最终的bundle中排除掉配置的配置的源码,例如,入口模块是
//index.js
require("jquery")
require("lodash")
生成的bundle是:
(function(){
...
})({
"./src/index.js": function(module, exports, __webpack_require__){
__webpack_require__("jquery")
__webpack_require__("lodash")
},
"jquery": function(module, exports){
//jquery的大量源码
},
"lodash": function(module, exports){
//lodash的大量源码
},
})
但有了上面的配置后,则变成了
(function(){
...
})({
"./src/index.js": function(module, exports, __webpack_require__){
__webpack_require__("jquery")
__webpack_require__("lodash")
},
"jquery": function(module, exports){
module.exports = $; //cdn引入jqery 后会有个全局变量$,所以其他页面可以使用$ 了
},
"lodash": function(module, exports){
module.exports = _;
},
})
这比较适用于一些第三方库来自于外部CDN
的情况,这样一来,即可以在页面中使用CDN
,又让bundle的体积变得更小
,还不影响源码的编写
stats
stats控制的是构建过程中控制台的输出内容
,也就是命令行里会打印的内容
stats:{
colors:true , //打印结果带颜色
modules:false, //打包时,不在命令行中显示打包的模块
hash:false, //不显示hash
}