Webpack会从文件入口开始检索,并将具有依赖关系的模块生成一颗依赖树,最终得到一个chunk。由这个chunk得到的打包产物一般称之为bundle。
Webpack通过context和entry这两个配置项来公共决定入口文件的路径。
在配置入口时,实际上做了两件事:
context可以理解为资源入口的路径前缀,在配置时要求必须使用绝对路径的形式。context可以省略,默认值为当前工程的根目录。context只能为字符串。
const path = require('path');
module.exports = {
context:path.join(__dirname,'./src'),
entry:'./index.js',
}
entry的配置可以多多种形式:字符串、数组、对象、函数,可以根据不同的需求场景来选择。
在使用字符串或数组定义单入口时,并没有办法更改chunk name,只能使用默认的main;在使用对象来定义多入口时,则必须为每一个入口定义chunk name。
module.exports = {
entry:'./src/index.js'
}
module.exports = {
entry:['babel-polyfill','./src/index.js']
}
上面的配置等同于://webpack.config.js
module.exports = {
entry:'./src/index.js'
}
//index.js
import 'babel-polyfill'
module.exports = {
entry:{
index:'./src/index.js',
lib:'./src/lib.js'
}
}
module.exports = {
entry:()=>'./src/index.js'
}
传入一个函数的优点在于可以在函数体里添加一些动态的逻辑来获取工程的入口。此外,函数也支持返回一个Promise对象来进行异步操作。module.exports = {
entry:()=> new Promise((resolve)=>{
//模拟异步操作
setTimeout(()=>{
resolve('./src/index.js');
},1000)
})
}
对于单页应用来说,一般定义单一入口即可。无论是框架、库,还是各个页面的模块,都由app.js单一的入口进行引用。这样做的好处是只会产生一个JS文件,依赖关系清晰。而这种做法也有弊端,即所有模块都打包到一起,当应用的规模上升到一定程度之后会导致产生的资源体积过大,降低用户的页面渲染速度。
module.exports = {
entry:'./src/app.js',
}
对于多页应用的场景,为了尽可能减少资源的体积,希望每个页面都只加载各自必要的逻辑,而不是将所有页面都打包到同一个bundle中,因此每个页面都需要一个独立的bundle,这种情形使用多入口来实现。
module.exports = {
entry:{
pageA:'./src/pageA.js',
pageB:'./src/pageB.js'
}
}
在上面的配置中,入口与页面是一一对应的关系,这样每个HTML只要引入各自的JS就可以加载其所需要的模块。
所有与出口相关的配置都集中在output对象里。output对象里可以包含数十个配置项,其中的大多数在日常开发中使用频率都不高。
filename的作用是控制输出资源的文件名,其形式为字符串。
module.exports = {
entry:'./src/app.js',
output:{
filename:'bundle.js'
}
}
filename可以不仅仅是bundle的名字,还可以是一个相对路径,即便路径中的目录不存在也没关系,Webpack在输出资源时创建该目录。
module.exports = {
entry:'./src/app.js',
output:{
filename:'.js/bundle.js'
}
}
在多入口的场景中,需要为对应产生的每个bundle指定不同的名字,Webpack支持使用一种类似模板语言的形式动态地生成文件名。
filename配置项模板变量:
上述变量一般有如下两种作用:
在实际工程中,使用比较多的是[name],它与chunk是一一对应的关系,并且可读性较高。如果要控制客户端缓存,最好还要加上[chunkhash],因为每个chunk所产生的[chunkhash]只与自身内容有关,单个chunk内容的改变不会影响其他资源,可以最精确地让客户端缓存得到更新。
module.exports = {
entry:{
app:'./src/app.js',
vendor:'./src/vendor.js'
},
output:{
filename:'[name].js'
}
}
在资源输出时,上面配置的filename中的[name]会被替换为chunk name,因此最后项目中实际生成的资源是app.js和vendor.js。
path可以指定资源输出的位置,要求值必须为绝对路径。
const path = require('path');
module.exports = {
entry:'./src/index.js',
output:{
path:path.join(__dirname,'./dist'),
filename:'bundle.js'
}
}
上述配置将资源输出位置设置为工程的dist目录。在Webpack 4以前的版本中,打包资源默认会生成在工程根目录,因此需要上述配置;而在Webpack 4之后,output.path已经默认为dist目录,除非需要更改它,否则不必单独配置。