详解Webpack loader 之 file

npm install --save-dev file-loader

用法

默认情况下,生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名。

import img from './webpack-logo.png'

webpack.config.js

module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: {} } ] } ] } }

生成文件 bd62c377ad80f89061ea5ad8829df35b.png (默认的文件名为 [hash].[ext]),输出到输出目录并返回 public URL。

"/public/path/bd62c377ad80f89061ea5ad8829df35b.png"

当然如果不想使用默认的文件名,我们也可以通过配置 options.name 选项来设置输出的文件名命名规则,需要注意的是 name 选项支持的类型为: {String|Function} :

String 类型

webpack.config.js

{ loader: 'file-loader', options: { name: '[path][name].[ext]' } }

Function 类型

webpack.config.js

{ loader: 'file-loader', options: { name (file) { if (env === 'development') { return '[path][name].[ext]' } return '[hash].[ext]' } } }

以上的示例中,我们使用了 [path] , [name] , [hash] 和 [ext] 占位符,它们对应的含义是:

[ext]:String,默认值为 file.extname,表示资源扩展名;

[name]:String,默认值为 file.basename,表示资源的基本名称;

[path]:String,默认值为 file.dirname,表示资源相对于 context 的路径;

[hash]:String,默认值为 md5,内容的哈希值,支持灵活的 hashes 配置,配置规则为:[<hashType>:hash:<digestType>:<length>],对应的说明如下:

详解Webpack loader 之 file

其实除了以上常用的四个占位符之外,还有支持 [N] ,N 是数值类型,表示当前文件名按照查询参数 regExp 匹配后获得到第 N 个匹配结果。介绍完 name 配置项,接下来我们来继续介绍几个常用的配置。

常用配置项 outputPath

outputPath 用于配置自定义 output 输出目录,支持 String|Function 类型,默认值为 ‘undefined',用法如下:

webpack.config.js

{ loader: 'file-loader', options: { name: '[path][name].[ext]', outputPath: 'images/' } }

需要注意的是,outputPath 所设置的路径,是相对于 webpack 的输出目录。

publicPath

publicPath 用于配置自定义 public 发布目录,支持 String|Function 类型,默认值为 __webpack_public__path__ ,用法如下:

webpack.config.js

{ loader: 'file-loader', options: { name: '[path][name].[ext]', publicPath: 'assets/' } }

emitFile

emitFile 用于设置是否生成文件,类型是 Boolean,默认值为 true。但我们可以通过将 emitFile 设置为 false 来禁用该默认行为。

webpack.config.js

{ loader: 'file-loader', options: { emitFile: false } }

outputPath vs publicPath

outputPath 仅仅告诉 webpack 结果存储在哪里,然而 publicPath 选项则被许多 webpack 的插件用于在生产模式下更新内嵌到 css、html 文件内的 url 值。例如:

// Development: Both Server and the image are on localhost .image { background-image: url('./test.png'); } // Production: Server is on Heroku but the image is on a CDN .image { background-image: url('https://some-cdn/test.png'); }

loader 准则

编写 loader 时应该遵循以下准则:

简单易用。

使用链式传递。

模块化的输出。

确保无状态。

使用 loader utilities。

记录 loader 的依赖。

解析模块依赖关系。

提取通用代码。

避免绝对路径。

使用 peer dependencies。

以上的准则按重要程度排序,但某些仅适用于某些场景。若想进一步了解自定义 loader,可以阅读 编写一个 loader 这个文档。接下来,我们来基于上述的准则分析一下 file-loader 的源码。

file-loader 源码简析

所谓 loader 只是一个导出为函数对象的 JavaScript 模块。 loader runner 会调用这个函数,然后把上一个 loader 产生的结果或者资源文件传入进去。 函数的 this 上下文将由 webpack 填充,并且 loader runner 具有一些有用方法,可以使 loader 改变为异步调用方式,或者获取 query 参数 。

其实本文介绍的 file-loader 并不会对文件的内容进行任何转换,只是复制一份文件内容,并根据相关的配置生成对应的文件名,所生成的文件名一般会带上 hash 值,从而避免文件重名导致冲突。接下来我们来简单分析一下 file-loader 的部分源码。

导入依赖模块

import path from 'path'; import loaderUtils from 'loader-utils'; import validateOptions from 'schema-utils'; import schema from './options.json';

获取配置对象及验证

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/4272b3f64001582c0e52bdcebf0415f6.html