使用uniapp开发微信小程序时,图片处理最佳实践
江阳小道 2024-09-13 13:33:01 阅读 80
前言:受限于微信小程序对包体积的限制,小程序包体积优化一直是一个让人头疼的问题。其中最简单也最容易做到的就是把图片放到<code>CDN或者服务器,就能减小包体积。
但
uniapp
由于框架的限制存在一个问题,无法通过简单的配置,实现编译后将图片路径自动替换成CDN
或者服务器连接。网上的一些通过配置全局变量实现链接替换的方式也不够优雅,于是就有了这篇文章。
一、定义全局方法或者变量
网上一般的解决方案是,定义全局方法或者变量,然后在页面中使用。
在vue2
中的写法
Vue.prototype.staticUrl = (img) { -- -->
return `https://www.xxx.com/${ img}`
}
在vue3
中的写法
app.config.globalProperties.staticUrl = (img) {
return `https://www.xxx.com/${ img}`
}
使用方法
<image :src="staticUrl('/static/images/logo.png')"></image>code>
这个方案虽然写起来简单,但不够灵活,一旦页面图片过多,每个路径都需要进行转换,而且写法也不够优雅,实在不是一个好的解决方案。
二、自定义loader,解析指定前缀
设置指定的前缀的,通过自定义loader
的方式动态替换前缀为CDN
地址。
在vue2
中使用
创建一个replace-image-loader.js
的文件,使用正则匹配,替换所有指定的图片路径前缀。
module.exports = function(source) { -- -->
return source.replace(/@images\//g, 'https://www.xxx.com/');
};
修改 vue.config.js
的配置文件,使用你创建的loader
。
module.exports = {
chainWebpack: config => {
config.module
.rule('replace-image')
.test(/\.(js|vue)$/)
.use('replace-image-loader')
.loader(path.resolve(__dirname, 'replace-image-loader.js'))
.end();
}
};
在vue3
中使用
创建一个插件文件vite-plugin-image-replace.js
的文件,使用正则匹配,替换所有指定的图片路径前缀。
export default function imageReplacePlugin() {
return {
name: 'vite-plugin-image-replace',
transform(code, id) {
// 替换为 CDN 地址
const replacedCode = code.replace(/@images\//g, 'https://www.xxx.com/');
return {
code: replacedCode,
map: null,
};
}
};
}
修改vite.config.js
export default defineConfig({
plugins: [imageReplacePlugin()],
});
使用方法
<image src="@images/static/images/logo.png"></image>code>
这个方法虽然不错,但引入了@image
这个前缀,图片过多就增加了额外的成本,以后项目维护起来也麻烦。
注意:这个方案来源于网络,未经过严格验证,如果发现问题欢迎指出。
三、只通过配置实现图片链接的动态替换(推荐)
为了避免不必要的开发维护和学习成本,经过思考后,发现最佳的方式是所有的写法都不变,在配置文件中实现动态替换。
在vue2
中使用
在uniapp
中的vue2
采用的是webpack
编译,可以直接通过现有的插件来实现图片路径的动态替换。
在 vue.config.js
文件中修改的配置即可。
module.exports = { -- -->
chainWebpack: config => {
config.module
.rule('vue')
.test([/.vue$/, /.nvue$/])
.use('vue-loader')
.tap((options) =>
Object.assign({ }, options, {
// 配置小程序image标签的src 也进行资源路径转换
transformAssetUrls: {
image: 'src',
},
}),
)
.end();
config.module
.rule('images')
.use('url-loader')
.tap((args) => {
return Object.assign({ }, args, {
// 配置转换规则,-1 表示任何大小的资源都不进行base64转换
limit: -1,
// 这里重要,publicPath 配置给url-loader 会不生效,必须配置到fallback里传递给file-loader
fallback: {
loader: 'file-loader',
options: {
publicPath(url, resourcePath, context) {
return 'https://cdn.example.com' + path.relative(process.env.UNI_INPUT_DIR, resourcePath)
},
emitFile: false,
},
},
})
.end();
}
};
在vue3
中使用
在uniapp
中的vue3
采用的是vite
编译,由于没有相应的插件,我自己实现了一个图片路径替换插件vite-plugin-replace-image-url来使用。
在vite.config.vue
中直接使用即可。
import replaceImageUrl from 'vite-plugin-replace-image-url';
export default {
plugins: [replaceImageUrl(
{
publicPath: 'https://www.xxx.com/',
sourceDir: path.resolve(__dirname, './src/static'),
include: ['**/*.svg', '**/*.png', '**/*.jp(e)?g', '**/*.gif', '**/*.webp'],
exclude: ['**/logo.png'],
verbose: true,
}
)],
}
具体用法参考插件链接:vite-plugin-replace-image-url - npm (npmjs.com)
使用方法
这里的使用方式和正常的写法没有啥变化,需要注意的是想要地址能够成功替换,必须采用绝对路径。
<image src="@/static/images/logo.png"></image>code>
图片转换地址到这里就告一段落了,现在还存在一个问题。每次构建打包后图片不会自动删除,每次都手动删除,实在不方便,于是又有了下面的方案。
四、将构建后的图片自动删除
在vue2
中使用
这里需要引入一个clean-webpack-plugin
插件来实现自动删除。
const { -- --> CleanWebpackPlugin } = require('clean-webpack-plugin');
configureWebpack: (config) => {
// 生产环境,删除部分图片资源
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new CleanWebpackPlugin({
// 清除编译后的图片资源
cleanAfterEveryBuildPatterns: [
'static/images/**',
'!static/images/tabbar*'
]
})
)
}
}
更多用法,参考插件链接:clean-webpack-plugin - npm (npmjs.com)
在vue3
中使用
在vite
插件中找了一圈,没找到现成的插件,于是我参考clean-webpack-plugin
实现了一个vite-plugin-clean-build插件。
使用方法如下:
import CleanBuild from 'vite-plugin-clean-build';
export default {
plugins: [CleanBuild(
{
outputDir: 'dist',
patterns: [
'static/images/**',
'!static/images/tabbar*'
]
}
)],
}
到这里整个图片处理的方案都有了,开发效率又提升了不少。
如果还不知道怎么使用,可以看看我的实践方案,这个模板里采用了vue3
的图片处理方案,并已经在实际开发中稳定使用。
使用uniapp+vite+vue3+uview-plus3.0 搭建的微信小程序快速开发模版 (github.com)
温馨提示:本文部分内容来源于网络,部分方案没有亲自验证过,如有问题,欢迎指出。
五、参考资料
vue.js - UNI-APP 实践问题记录 - 码游杂记 - SegmentFault 思否在 uni-app 中自定义 webpack loader 处理图片路径 - 掘金 (juejin.cn)
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。