Webpack配置中output.filename方括号参数的含义及与纯文本的差异
先说说方括号的含义
嘿,这些带方括号的内容是Webpack的占位符(placeholders),相当于动态变量,打包过程中会被实际的项目信息替换成具体的值。
拿你给的示例[name].js来说,[name]会被你配置的入口chunk名称替换。比如你在entry里写了main: './src/main.js',那打包后就会生成main.js;如果有多个入口,比如还有login: './src/login.js',就会对应生成login.js。
除了[name],常用的占位符还有这些:
[hash]: 整个项目的构建哈希值,每次构建只要项目内容有变化,这个值就会变[chunkhash]: 当前chunk的专属哈希,只有这个chunk里的代码变了,哈希才会更新[contenthash]: 输出文件内容的哈希,比chunkhash更精准,比如CSS文件用它,哪怕JS chunk变了但CSS内容没改,哈希也不会变,特别适合做缓存优化
和纯文本文件名的核心区别
1. 动态生成 vs 固定不变
纯文本比如写bundle.js,不管你有多少个入口、多少次构建,输出的文件名永远是bundle.js;但用占位符的话,文件名会跟着你的项目配置、代码内容动态变化,能适配更多场景。
2. 缓存优化能力天差地别
这是最关键的一点!用带哈希的占位符(比如[name].[contenthash].js),只要文件内容没改,哈希就不变,浏览器会一直缓存旧文件;一旦内容更新,哈希变了,文件名就变了,浏览器会自动请求新文件。而纯文本文件名每次打包都会覆盖旧文件,很容易出现用户浏览器缓存没更新,看到的还是旧内容的问题。
3. 多入口/代码分割场景不冲突
如果是多入口项目,用纯文本文件名的话,后面打包的文件会直接覆盖前面的,最后只能得到一个文件;但用[name].js的话,每个入口都会生成对应名称的文件,完全不会冲突。
另外当你用代码分割(比如按需加载组件、拆分公共代码)时,Webpack会生成多个chunk文件,占位符能自动给每个chunk分配唯一的文件名,纯文本根本做不到这一点。
举个实际例子对比:
假设你的入口配置是:
entry: { main: './src/main.js', cart: './src/cart.js' }
- 如果用
filename: 'bundle.js',打包后dist/里只有一个bundle.js,是最后一个入口cart的打包结果,main的内容被覆盖了 - 如果用
filename: '[name].js',打包后会生成main.js和cart.js两个文件,各自对应自己的入口代码
你给出的示例配置:
output: { filename: '[name].js', publicPath: 'dist/' }
这个配置就是典型的适配多入口场景的写法,能保证每个入口都有自己独立的输出文件。
内容的提问来源于stack exchange,提问作者kumar

