一、output对象常用的几个属性
(1)publicPath
默认情况下,webpack-dev-server 会把打包后的文件放到项目的根目录下(path) ,文件名是在output配置中的filename. 但是当有publicPath 配置的时候,就不一样了。
Webpack 会把所有的文件打包到publicPath指定的目录下,就是相当于在项目根目录下创建了一个publicPath目录, 然后把打包成的文件放到了它里面,只不过我们看不到而已, 文件名还是output配置中的filename。
当打包的时候,webpack会在静态文件路径前面添加publicPath的值,当我们把资源放到CDN上的时候,把publicPath的值设为CDN的值就可以了。
Vue CLI 默认值为/,假设你的应用是被部署在一个域名的根路径上,被部署在一个域名的根路径上。
(2)path
经打包代码输出的目录
const path = require('path');
module.exports = {
//...
output: {
path: path.resolve(__dirname, 'dist/assets'),
},
};
注意,[fullhash] 在参数中被替换为编译过程(compilation)的 hash。详细信息请查看指南 - 缓存。
output 目录对应一个绝对路径。__dirname项目的路径。
(3)filename
决定了每个输出 bundle 的名称。 filename 是一个很常见的配置,就是对应于 entry 里面的输入文件,经过webpack 打包后输出文件的文件名。
比如说经过下面的配置,生成出来的文件名为 index.min.js。
// vue-cli 写法。
chainWebpack(config) {
const hash = process.env.NODE_ENV === 'development' ? 'hash' : 'contenthash';
config
.output
.filename(`[name].[${hash}:8].js`)
.end();
},
// 源webapck写法
{
entry: {
index: "../src/index.js" // 【name】为index
},
output: {
filename: "[name].min.js", // index.min.js
}
}
(4)chunkFilename
决定了每个懒加载的输出 bundle 的名称
背景:
懒加载 (按需加载),初始化不需要加载此代码块,等到具体的执行需要时候,再加载,从而优化性能。
chunkFilename 指未被列在 entry 中,却又需要被打包出来的 chunk 文件的名称。一般来说,这个 chunk 文件指的就是要懒加载的代码。
output:{
filename,
chunkFilename: filename
path:path.resolve(__dirname,'dist')
}
vue-router中路由懒加载写法:
基本语法:import(/* webpackChunkName: "chunk名称(用于代码分割)" */ "组件路径")
在动态import()代码处添加注释webpackChunkName告诉webpack打包后的chunk的名称(注释中的内容很重要,不能省掉),这里打包以后的name就是about。
// 一个路由懒加载的语法
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') // 指定chunkName以及可以将多个路由懒加载的组件打包为一个chunk。
}
默认情况下:
chunkFilename 默认使用 [id].js 或从 output.filename 中推断出的值,ps就是用fileName,不过【name】用id来替换。(其中, [id] 或 [id].去 预替换 [name] )。
懒加载import()写webpackChunkName 时,替换过去【name】。
理解:
output.filename 的输出文件名是 [name].min.js,[name] 根据 entry 的配置推断为 index,所以输出为 index.min.js;
由于 output.chunkFilename 没有显示指定,就会把 [name] 替换为 chunk 文件的 id 号,这里文件的 id 号是 1,所以文件名就是 1.min.js。
webapck显式配置chunkFilename,就会按配置的名字生成文件。
output:{
filename:'[name].bundle.js',
chunkFilename:'[name].bundle.js',// 决定非入口chunk的名称,动态导入分离代码
path:path.resolve(__dirname,'dist')
}
二、filename与chunkFilename
filename 指列在 entry 中,打包后输出的文件的名称。
chunkFilename 指未列在 entry 中,却又需要被打包出来的文件的名称,例如懒加载。
三、如何解决浏览器缓存问题?
通过wepack打包时的hash,hash值变了,用户就访问新的了。
filename的hash值可以有三种hash生成方式,分别为hash、chunkHash、contentHash,那它们的区别?
(1) hash
说明:
- hash是跟整个项目的构建相关,
- 只要项目里有文件更改,整个项目构建的hash值都会更改,
- 并且全部文件都共用相同的hash值
举例:
output: {
filename: '[name].[hash:8].js',
path: __dirname + '/build'
}
效果分析:
环境:用于webpack的开发环境
优点:每次的开发中,文件都不会让浏览器器缓存,保证了文件的更新率,提高了开发效率。
问题:多个js文件任何一个改动都会影响另外两个文件的最终文件名。上线后,另外两个文件的浏览器缓存也全部失效。
(2) chunkHash
说明:
chunk 代表模块,根据模块内容计算出来的hash值。
某个文件的改动只会影响它本身的hash指纹,不会影响其他文件。配置webpack的output如下。
从字面上就能猜出它是跟webpack打包的chunk相关的。具体来说webpack是根据入口entry配置文件来分析其依赖项并由此来构建该entry的chunk,并生成对应的hash值。不同的chunk会有不同的hash值。
在生产环境中,我们会把第三方或者公用类库进行单独打包(chunk-vendors),所以不改动公共库的代码,该chunk的hash就不会变,可以合理的使用浏览器缓存了。
举例:
output: {
filename: '[name].[chunkhash:8].js',
path: __dirname + '/built'
}
效果分析:
环境:用于webpack的生产环境
优势:每个文件的hash指纹都不相同,上线后无改动的文件不会失去缓存。
问题:生产环境中我们会用webpack的插件,将css代码打单独提取出来打包(前提) 。这时候chunkhash的方式就不够灵活,因为只要同一个chunk里面的js修改后,css的chunk的hash也会跟随着改动。失去了缓存的意义。因此我们需要contenthash
(3) contentHash
说明:
contenthash主要是处理关联性。
webpack默认将js/style文件统统编译到一个js文件中,可以借助mini-css-extract-plugin将style文件单独编译输出。从这点可以看出,webpack将style文件视为js的一部分。
将css单独编译输出并且打上hash指纹,按照前文所述的使用chunkhash配置输出文件名时,编译的结果是js和css文件的hash指纹完全相同。不论是单独修改了js代码还是style代码,编译输出的js/css文件都会打上全新的相同的hash指纹。
失去了css缓存或者js缓存的优势
举例:
output: {
filename: '[name].[content:8].js',
path: __dirname + '/built'
}
效果分析:
环境:用于webpack的生产环境
优势:解决了js和css未改动的缓存问题。
问题:无