- 跨平台
- 前端
- 移动开发
- 小程序
- 构建工具
【免费下载链接】chameleon
🦎 一套代码运行多端,一端所见即多端所见
mvvm-file-loader是 Chameleon(一套代码运行多端)生态中负责处理图片、字体、音视频等二进制静态资源的核心 webpack loader,其配置 API 与经典的file-loader完全一致。本文将以其官方文档为主体,完整讲解安装、用法、全部可配置项(name、regExp、context、publicPath、outputPath、useRelativePath、emitFile)、占位符与哈希规则,并结合 chameleon 仓库源码揭示它在多端构建链中的真实调用方式,帮助你写出可落地、可调试的静态资源打包配置。
一、认识 mvvm-file-loader:它在 Chameleon 生态中的位置
mvvm-file-loader(版本 1.0.8)是 chameleon 仓库中用于处理二进制资源(图片、字体、媒体文件)的 loader 包,其职责一句话概括:让 webpack 将引入的资源作为一个独立文件发射(emit)到输出目录,并返回该文件的公开 URL。它的元信息可以在 packages/mvvm-file-loader/package.json 中查看:主要依赖loader-utils(解析 options)、mime(资源 MIME 类型推断)、schema-utils(配置校验),由 Chameleon-Team 维护。
它并非独立使用,而是作为chameleon-tool构建体系的一部分被装配进 webpack 配置。在扩展新端(mvvm 编译模式)时,packages/chameleon-tool/configs/mvvm/getExtendConfig.js 会把公共配置中所有chameleon-url-loader与file-loader的规则统一替换为mvvm-file-loader,并注入commonConfig.output.publicPath作为publicPath选项:
commonConfig.module.rules.forEach(item => { // 静态资源的处理 if (~['chameleon-url-loader', 'file-loader'].indexOf(item.loader)) { item.loader = 'mvvm-file-loader'; item.options.publicPath = commonConfig.output.publicPath } // ... })因此,理解mvvm-file-loader的配置,实际上就是理解 Chameleon 处理静态资源的最终行为。
二、安装与基础用法
按 webpack 官方 file-loader 的惯例安装(在非 lerna 单包场景):
npm install --save-dev file-loader在 Chameleon 仓库中,该包已通过chameleon-tool的依赖关系内置,无需手动安装即可随cml命令工作;若需单独调试,可参照 packages/mvvm-file-loader/package.json 的依赖声明还原环境。
默认情况下,生成文件的文件名是文件内容的 MD5 哈希值加上原始扩展名。先在业务代码中引入资源:
import img from './file.png'然后在 webpack 配置中为其声明规则:
module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: {} } ] } ] } }构建后,loader 会把file.png作为独立文件发射到输出目录,并返回其公开 URL,形如:
"/public/path/0dcbbaa7013869e351f.png"这就是“发射文件 + 返回 URL”这一核心行为的直接体现。值得一提的是,同仓库的url-loader在资源超过limit时,正是把file-loader作为默认回退方案(packages/url-loader/src/index.js):
const fallback = require(options.fallback ? options.fallback : 'file-loader'); return fallback.call(this, src);即:小文件内联为 base64 DataURL,大文件交给 file-loader 发射为独立文件。
三、Options 配置总览
mvvm-file-loader的全部可配置项如下表所示:
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | {String\|Function} | [hash].[ext] | 为文件配置自定义文件名模板 |
regExp | {RegExp} | 'undefined' | 从文件路径中提取部分片段,供name复用 |
context | {String} | this.options.context | 自定义文件上下文,默认取 webpack.config.js 的context |
publicPath | {String\|Function} | __webpack_public_path__ | 为文件配置自定义public路径 |
outputPath | {String\|Function} | 'undefined' | 为文件配置自定义output输出路径 |
useRelativePath | {Boolean} | false | 设为true时为每个文件生成相对context的 URL |
emitFile | {Boolean} | true | 默认发射文件;可在必要时关闭(如服务端包) |
name
通过name选项自定义文件名模板。例如希望从context目录复制文件到输出目录并保留完整目录结构:
字符串形式{String}
{ loader: 'file-loader', options: { name: '[path][name].[ext]' } }函数形式{Function}
{ loader: 'file-loader', options: { name (file) { if (env === 'development') { return '[path][name].[ext]' } return '[hash].[ext]' } } }函数形式非常适合按环境区分打包策略:开发环境保留可读路径便于调试,生产环境退化为内容哈希便于长缓存。
regExp
用regExp匹配文件路径中的部分片段,捕获组可在name中通过[N]占位符复用。注意:[0]代表整个被匹配的字符串,[1]是第一个捕获括号,依此类推。
import img from './customer01/file.png'{ loader: 'file-loader', options: { regExp: /\/([a-z0-9]+)\/[a-z0-9]+\.png$/, name: '[1]-[name].[ext]' } }输出结果:
customer01-file.png这适合将按目录组织的资源(如按客户、按模块)在输出文件名中保留业务标识。
占位符(placeholders)
name模板中可用的占位符:
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
[ext] | {String} | file.extname | 资源的扩展名 |
[name] | {String} | file.basename | 资源的 basename(不含扩展名) |
[path] | {String} | file.dirname | 资源相对于context的路径 |
[hash] | {String} | md5 | 内容的哈希,哈希配置见下 |
[N] | {String} | `` | 当前文件名与regExp匹配得到的第 N 个捕获组 |
哈希(hashes)
哈希占位符支持完整语法[<hashType>:hash:<digestType>:<length>],可选配置:
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
hashType | {String} | md5 | 哈希算法:sha1、md5、sha256、sha512 |
digestType | {String} | hex | 编码方式:hex、base26、base32、base36、base49、base52、base58、base62、base64 |
length | {Number} | 9999 | 哈希字符串长度(字符数) |
默认情况下,name中指定的路径与文件名会同时作为输出目录路径与访问 URL 路径使用。
context
自定义上下文目录,name中的[path]将相对于它计算:
{ loader: 'file-loader', options: { name: '[path][name].[ext]', context: '' } }配合outputPath、publicPath、useRelativePath可以分别定制输出路径与公开 URL 路径,实现“输出到 A 目录、从 B 路径访问”的分离。
publicPath
自定义文件公开访问路径前缀:
{ loader: 'file-loader', options: { name: '[path][name].[ext]', publicPath: 'assets/' } }outputPath
自定义输出目录(相对于 webpack 的output.path):
{ loader: 'file-loader', options: { name: '[path][name].[ext]', outputPath: 'images/' } }useRelativePath
希望为每个文件生成相对于context的 URL 时设为true:
{ loader: 'file-loader', options: { useRelativePath: process.env.NODE_ENV === "production" } }emitFile
默认会发射文件;对于纯服务端包等不需要产物落盘的场景可关闭:
import img from './file.png'{ loader: 'file-loader', options: { emitFile: false } }⚠️ 关闭后只返回公开 URL,不会发射文件
返回结果形如:
`${publicPath}/0dcbbaa701328e351f.png`四、典型使用示例集
结合以上选项,官方文档给出三组可直接套用的完整示例:
示例一:指定子目录输出
import png from 'image.png'{ loader: 'file-loader', options: { name: 'dirname/[hash].[ext]' } }dirname/0dcbbaa701328ae351f.png示例二:自定义哈希算法、编码与长度
{ loader: 'file-loader', options: { name: '[sha512:hash:base64:7].[ext]' } }gdyb21L.png即使用sha512算法、base64编码、截取 7 个字符,产出极短且唯一的文件名,适用于 CDN 场景。
示例三:查询参数形式携带内容哈希
import png from 'path/to/file.png'{ loader: 'file-loader', options: { name: '[path][name].[ext]?[hash]' } }path/to/file.png?e43b20c069c4a01867c31e98cbce33c9此时文件本身保留可读路径,内容变更通过 URL 查询参数体现,便于缓存失效控制。
五、在 Chameleon 多端构建链中的实战调用
前面提到mvvm-file-loader的配置 API 继承自file-loader,而 Chameleon 构建体系对file-loader的调用可从两处源码得到印证:
1. 公共构建配置中的媒体与字体规则(packages/chameleon-tool/configs/getCommonConfig.js)。图片(png/jpeg/gif/svg)由chameleon-url-loader处理(limit: false时不做 base64 转换,需显式加?inline参数);而音视频与字体文件交给file-loader:
{ test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'file-loader', options: { name: getstaticPath('media'), outputPath: function(output) { // 处理图片中的@符号 改成_ 解决在支付宝小程序中上传失败的问题 output = cml.utils.handleSpecialChar(output) return output; } } }, { test: /\.(woff|woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'file-loader', options: { name: getstaticPath('fonts'), outputPath: function(output) { /* 同上处理特殊字符 */ } } }可以看到:name通过getstaticPath('media'/'fonts')生成按类型归档的目录模板;outputPath以函数形式做后处理,将文件名中的@替换为_,以规避支付宝小程序上传失败问题——这正是函数型outputPath的典型生产应用。
2. 组件导出(export)场景(packages/chameleon-tool/configs/component_export/getWebExportConfig.js)。导出模式为媒体与字体配置了useRelativePath: mode !== 'production',并在开发/中间模式下通过outputPath追加?__export标记,配合导出 loader 实现资源的按需输出:
{ test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'file-loader', options: { name: getstaticPath('media'), useRelativePath: mode !== 'production', outputPath: function(url) { return mode === 'production' ? url : url + '?__export'; } } }3. 扩展新端的替换逻辑。如第一节所述,getExtendConfig.js 将上述规则中的file-loader统一替换为mvvm-file-loader并补齐publicPath,保证扩展端与内置端使用同一套静态资源处理行为。
由此可见,本文介绍的所有选项在 Chameleon 中均有真实落点:name用于资源分类归档,outputPath函数用于特殊字符清洗,useRelativePath用于导出模式,publicPath由构建系统统一注入。理解这些配置,即可在多端(Web/小程序/Weex/扩展新端)构建中精确控制静态资源的输出路径、访问 URL 与缓存策略。
- 跨平台
- 前端
- 移动开发
- 小程序
- 构建工具
【免费下载链接】chameleon
🦎 一套代码运行多端,一端所见即多端所见
相关推荐
DeepSearcher 文件加载器详解:File Loader 的选型、配置与源码级实现分析
DeepSearcher 文件加载器详解:File Loader 的选型、配置与源码级实现分析 DeepSearcher 通过 file_loader 组件决定
人工智能大模型RAGAI Agent深度研究知识库Midway 静态资源组件实战指南:基于 @midwayjs/static-file 的静态文件服务与缓存配置
Midway 静态资源组件实战指南:基于 @midwayjs/static file 的静态文件服务与缓存配置 @midwayjs/static file 是
后端微服务云原生Notepad--文本编辑器:从使用者到创造者的国产软件替代之路
Notepad 文本编辑器:从使用者到创造者的国产软件替代之路 你是否曾在多个操作系统间切换工作时,因为文本编辑器的不兼容而感到困扰?或者在使用国外编辑器时,对
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考