《三》Webpack资源输入和输出

资源处理流程:

Webpack会从文件入口开始检索,并将具有依赖关系的模块生成一颗依赖树,最终得到一个chunk。由这个chunk得到的打包产物一般称之为bundle。
在这里插入图片描述

配置资源入口:

Webpack通过context和entry这两个配置项来共同决定入口文件的路径。

在配置入口时,实际上做了两件事:

  1. 确定入口模块位置,告诉webpack从哪里开始进行打包。
  2. 定义chunk name。如果工程只有一个入口,那么默认其chunk name为main;如果工程有多个入口,需要为每个入口定义chunk name,来作为该chunk的唯一标识。
context:

context可以理解为资源入口的路径前缀,在配置时要求必须使用绝对路径的形式。context可以省略,默认值为当前工程的根目录。context只能为字符串。

const path = require('path');

module.exports = {
    context:path.join(__dirname,'./src'),
    entry:'./index.js',
}
entry:

entry的配置可以有多种形式:字符串、数组、对象、函数,可以根据不同的需求场景来选择。

在使用字符串或数组定义单入口时,并没有办法更改chunk name,只能使用默认的main;在使用对象来定义多入口时,则必须为每一个入口定义chunk name。

  1. 字符串类型入口:
    module.exports = {
        entry:'./src/index.js'
    }
    
  2. 数组类型入口:传入一个数组的作用是将多个资源预先合并,在打包时Webpack会将数组中的最后一个元素作为实例的入口路径。
    module.exports = {
        entry:['babel-polyfill','./src/index.js']
    }
    
    上面的配置等同于:
    //webpack.config.js
    module.exports = {
        entry:'./src/index.js'
    }
    
    //index.js
    import 'babel-polyfill'
    
  3. 对象类型入口:如果想要定义多入口,则必须使用对象的形式。对象的属性名是chunk name;属性值是入口路径,可以为字符串或数组。
    module.exports = {
    	 entry:{
    	 	index:'./src/index.js',
    	 	lib:'./src/lib.js'
    	 }
    }
    
  4. 函数类型入口:用函数定义入口时,只要返回上面介绍的任何配置形式即可。
    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:

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配置项模板变量:

  1. [name]:指代chunk name。
  2. [hash]:指代Webpack此次打包所有资源生成的hash。
  3. [chunkhash]:指代当前chunk内容的hash。
  4. [id]:指代当前chunk的id。
  5. [query]:指代filename配置项中的query。

上述变量一般有如下两种作用:

  1. 当有多个chunk存在时对不同的chunk进行区分。如[name]、[chunkhash]和[id],它们对于每个chunk来说都是不同的。
  2. 控制客户端缓存。[hash]和[chunkhash]都与chunk内容直接相关,在filename中使用了这些变量后,当chunk的内容改变时,可以同时引起资源文件名的更改,从而使用户在下一次请求资源文件时会立即下载新的版本而不会使用本地缓存。[query]也可以起到类似的效果,只不过它与chunk内容无关,要由开发者手动指定。

在实际工程中,使用比较多的是[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:

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目录,除非需要更改它,否则不必单独配置。

publicPath:

publicPath用来指定资源的请求位置。

path用来指定资源的输出位置。
输出位置:打包完成后资源产生的目录,一般将其指定为工程中的dist目录。
请求位置:由JS或CSS所请求的间接资源路径。页面中的资源分为两种,一种是由HTML页面直接请求的,比如通过script标签加载的JS;另一种是由JS或CSS请求的,如异步加载的JS、从CSS请求的图片字体等。publicPath的作用就是指定这部分间接资源的请求位置。

publicPath有三种形式:

  1. HTML相关:将publicPath指定为HTML的相对路径,在请求这些资源时会以当前页面HTML所在路径加上相对路径构成实际请求的url。
    //假设当前HTML地址为https://example.com/app/index.html
    //异步加载的资源名为0.chunk.js
    publicPath:"" //实例路径https://example.com/app/0.chunk.js
    publicPath:"./js" //实例路径https://example.com/app/js/0.chunk.js
    publicPath:"../assets" //实例路径https://example.com/assets/0.chunk.js
    
  2. Host相关:若publicPath的值以"/"开始,则代表此时publicPath是以当前页面 的host name为基础路径的。
    //假设当前HTML地址为https://example.com/app/index.html
    //异步加载的资源名为0.chunk.js
    publicPath:"/" //实例路径https://example.com/0.chunk.js
    publicPath:"/js/" //实例路径https://example.com/js/0.chunk.js
    
  3. CDN相关:上面两种配置都是相对路径,也可以使用绝对路径的形式配置publicPath。这种情况一般发生于静态资源放在CDN上面时,由于其域名与当前页面域名不一致,需要以绝对路径的形式进行指定。当publicPath以协议头或相对协议的形式开始时,代表当前路径是CDN相关。
    //假设当前HTML地址为https://example.com/app/index.html
    //异步加载的资源名为0.chunk.js
    publicPath:"http://cdn.com/" //实例路径http://cdn.com/0.chunk.js
    publicPath:"//cdn.com/assets/" //实例路径//cdn.com/assets/0.chunk.js
    

猜你喜欢

转载自blog.csdn.net/wsln_123456/article/details/107224614