陌上人如玉
公子世无双

从零搭建webpack4之output输出

持续更新中。。。

昨天

我们我们主要讨论了webpack配置中的两个属性

  • mode(模式)
  • entry(入口)

简单回顾一下,
mode(模式),有两个值 production和development,默认值是 production,如果设置为none会抛出警告⚠️;
entry(入口),可以理解为输入,有三种类型,字符串类型,数组类型,对象类型;字符串和数组类型都是对象类型的简写
不在这里详细介绍了,需要复习的可以戳这里(从零搭建webpack4(mode和entry)
接着昨天的entry,我们在根目录下创建src文件夹,然后创建man.js文件,作为项目的入口文件
我们的webpack.config.js已经更新到如下:

const webpack = require('webpack');
const path = require('path');
let env = process.env.NODE_ENV == "development" ? "development" : "production";
const config = {
  mode: env,
  entry: {
    app: './src/main.js',
  }
}

module.exports = config;

今天

今天我们继续讨论webpack的核心概念

output(出口)

有输入就会有输出,有入口就会有出口,output和entry遥相呼应,

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output 字段,来配置这些处理过程。

就是配置如何输出最终想要的代码,output是一个对象类型,是对象就有属性,就支持我们更改属性值进行配置,不过他的属性有点多
看来自官网的一张图片

这还只是一部分,我们挑几个常用的介绍一些,具体的可以看官网,但是官网的介绍并不是那么通俗易懂,需要度娘辅助。

filename

filename 这个是输出文件的名称,字符串类型,如果只有一个输出文件,可以写成静态名称。例如

output:{
     filename:'bundle.js'
}

当然了,在我们日常工作中,一般情况下是不会有这种情况的,当项目很大的时候,如果不分块打包,bundle.js会惊人的大,项目越大,bundle.js就会越大,这不是我们今天讨论的重点,以后再说
多个chunk的时候怎么办呢?我们昨天说过,回忆一下
webpack会为每个生成的Chunk取一个名称,Chunk的名称和Entry的配置有关:

  1. 如果entry是一个string或者array,就只会生成一个chunk,这个chunk的名称是main;
  2. 如果entry是一个object,就可能出现多个chunk,这时chunk的名称是object键值对里键的名称

然而,当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin)创建多个 bundle,应该使用以下一种替换方式,来赋予每个 bundle 一个唯一的名称……
使用入口名称:

output:{
     filename: "[name].bundle.js"
}

使用内部 chunk id

output:{
    filename: "[id].bundle.js"
}

使用每次构建过程中,唯一的 hash 生成

output:{
filename: "[name].[hash].bundle.js"
}

使用基于每个 chunk 内容的 hash:

output:{
filename: "[chunkhash].bundle.js"
}

这里多出来几个陌生词汇hash、chunkhash,它们是什么?

hash、chunkhash和contenthash三者的区别

hash
我做了一个[name]_[hash].js的测试

看到了问题了吧,hash的值是相同的,如果都使用hash的话,因为这是工程级别的,即每次修改任何一个文件,所有文件名的hash至都将改变。所以一旦修改了任何一个文件,整个项目的文件缓存都将失效。所以对于没有改变的模块而言,这样做显然不恰当,因为缓存失效了嘛。此时,chunkhash的用途随之而来。
chunkhash
只有被修改了的文件的文件名,hash值修改

filename: '[name]-[chunkhash].js'

当我们使用mini-css-extract-plugin拆分css的时候,就需要使用chunkhash,我一个js文件里面引入了css文件。这时要是我修改了js,但没修改css,可以通过chunkhash缓存css文件
contenthash
对css使用了chunkhash之后,我们测试会发现,如果修改了js,css文件名的hash值确实没变,但这时要是我们修改css文件的话,我们就会发现css文件名的chunkhash值居然没变化,这样就导致我们的非覆盖发布css文件失效了。所以这里需要注意就是css文件必须使用contenthash。
上面介绍的 id、name、hash、chunkhash等都是webpack内置变量,
id是唯一标示,不会重复,从0开始,
name 是模块名称,是你自己起的,在配置路由懒加载的时候可以自己命名
官网介绍的很清楚,我就不再这里啰嗦了,

chunkFilename

官网解释:此选项决定了非入口(non-entry) chunk 文件的名称,
什么场景需要呢?
在按需加载(异步)模块的时候,也就是路由懒加载,这样的文件是没有被列在entry中的,
比如

{
    entry: {
        "index": "pages/index.jsx"
    },
    output: {
         filename: "[name].min.js",
        chunkFilename: "[name].min.js"
    }
}
const myModel = r => require.ensure([], () => r(require('./myVue.vue')), 'myModel')

上面的例子,通过filename输出的是index.min.js
异步加载的模块是要以文件形式加载哦,所以这时生成的文件名是以chunkname配置的,通过chunkFilename输出的是myModel.min.js
所以chunkFilename也很重要哦!!!

path

path是配置输出文件存放在本地的目录,字符串类型是绝对路径

output:{
    path: path.resolve(__dirname, 'dist/assets')
}

__dirname,这个昨天说过,可以回顾一下,就是当前文件所在的文件夹的名字

publicPath

对构建出的资源进行异步加载(图片,文件),该选项的值是以 runtime(运行时) 或 loader(载入时) 所创建的每个 URL 为前缀。因此,在多数情况下,此选项的值都会以/结束。
默认值是一个空字符串 “”,即相对路径,配置错误会导致404
简单说,就是静态文件托管在cdn上
举个栗子:
如果你这么配置:

output:{
    filename:'[name]_[chunkhash:8].js',
    publicPath:'https://www.qdtalk.com/assets/'
}

打包编译后,html页面就是这样的

<script src="https://www.qdtalk.com/assets/a_12345678.js"></script>

path 和publicPath都支持字符串模板

总结

今天讨论了output(出口/输出),filename, path,publicPath以及hash、chunkhash和contenthash三者的区别
关于output的属性还有很多,常用的也就以上几个,想要获取更多信息,可以参见官网
今天就到这里,明天不见不散

福利

整理了一些关于node的一些教程,公众号后台回复“node教程四”即可领取

参考链接
缓存
webpack中hash、chunkhash、contenthash区别
怎么理解webpack中的output.filename 和output.chunkFilename

赞(0) 打赏
未经允许不得转载:陌上寒 » 从零搭建webpack4之output输出

评论 抢沙发

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

微信扫一扫

支付宝扫一扫