Open tourze opened 3 years ago
这个问题,也是够久的了。。。最后没办法只能自己写插件来解决,创建 config/plugins/raw-weapp-enhance.js
,内容是:
const fs = require('fs');
const path = require('path');
const copy = require('recursive-copy');
const projectRoot = path.resolve(__dirname, '../..'); // 本项目目录
// eslint-disable-next-line no-extend-native
String.prototype.trim = function (char, type = 'left') {
if (char) {
if (type === 'left') {
return this.replace(new RegExp('^\\' + char + '+', 'g'), '');
} else if (type === 'right') {
return this.replace(new RegExp('\\' + char + '+$', 'g'), '');
}
return this.replace(new RegExp('^\\' + char + '+|\\' + char + '+$', 'g'), '');
}
return this.replace(/^\s+|\s+$/g, '');
};
const copyKeys = [];
const copyList = {};
function copyFiles(fileName, sourceRoot, outputRoot) {
if (copyKeys.includes(fileName)) {
return;
}
copyKeys.push(fileName);
const extensions = ['jpg', 'png', 'gif', 'toff', 'jpeg', 'bmp', 'wxs'];
extensions.map((ext) => {
const srcExt = `${sourceRoot}/${fileName}.${ext}`;
if (fs.existsSync(srcExt)) {
copyList[srcExt] = srcExt.replace(`${sourceRoot}`, `${outputRoot}`);
}
});
const srcJson = `${sourceRoot}/${fileName}.json`;
if (fs.existsSync(srcJson)) {
copyList[srcJson] = srcJson.replace(`${sourceRoot}`, `${outputRoot}`);
const jsonConfig = require(srcJson);
// 依赖组件要复制一次
if (jsonConfig.usingComponents !== undefined) {
Object.keys(jsonConfig.usingComponents).map((k) => {
const compPath = jsonConfig.usingComponents[k];
const srcPath = compPath.startsWith('/')
? compPath.trim('/')
: path.relative(`${sourceRoot}`, path.resolve(path.dirname(srcJson), `${compPath}`));
// 一般来说,wxml是必不可少的吧?
if (fs.existsSync(`${sourceRoot}/${srcPath}.wxml`)) {
copyFiles(srcPath, sourceRoot, outputRoot);
}
});
}
}
// 依赖样式文件
const srcWXSS = `${sourceRoot}/${fileName}.wxss`;
if (fs.existsSync(srcWXSS)) {
copyList[srcWXSS] = srcWXSS.replace(`${sourceRoot}`, `${outputRoot}`);
}
// 复制wxml
const srcWXML = `${sourceRoot}/${fileName}.wxml`;
if (fs.existsSync(srcWXML)) {
copyList[srcWXML] = srcWXML.replace(`${sourceRoot}`, `${outputRoot}`);
// 复制wxml中的图片等资源
const code = fs.readFileSync(srcWXML, { encoding: 'utf8', flag: 'r' });
const res1 = code.match(/src="(.*?)"/g);
if (res1) {
res1.map((text) => {
text = text.replace('src="', '');
text = text.trim('"', 'right');
if (text.startsWith('//:')) {
return;
}
if (text.startsWith('http://')) {
return;
}
if (text.startsWith('https://')) {
return;
}
if (text.includes('{')) {
return;
}
if (text.includes('+')) {
return;
}
text = text.startsWith('/')
? text.trim('/')
: path.relative(`${sourceRoot}`, path.resolve(path.dirname(srcWXML), `${text}`));
text = `${text.split('.').slice(0, -1).join('.')}`;
copyFiles(text, sourceRoot, outputRoot);
});
}
const res2 = code.match(/src='(.*?)'/g);
if (res2) {
res2.map((text) => {
text = text.replace("src='", '');
text = text.trim("'", 'right');
if (text.startsWith('//:')) {
return;
}
if (text.startsWith('http://')) {
return;
}
if (text.startsWith('https://')) {
return;
}
if (text.includes('{')) {
return;
}
if (text.includes('+')) {
return;
}
text = text.startsWith('/')
? text.trim('/')
: path.relative(`${sourceRoot}`, path.resolve(path.dirname(srcWXML), `${text}`));
text = `${text.split('.').slice(0, -1).join('.')}`;
copyFiles(text, sourceRoot, outputRoot);
});
}
}
// 依赖JS
const srcJS = `${sourceRoot}/${fileName}.js`;
if (fs.existsSync(srcJS)) {
copyList[srcJS] = srcJS.replace(`${sourceRoot}`, `${outputRoot}`);
}
const srcTS = `${sourceRoot}/${fileName}.ts`;
if (fs.existsSync(srcTS)) {
copyList[srcTS] = srcTS.replace(`${sourceRoot}`, `${outputRoot}`);
}
}
module.exports = (ctx, options) => {
// plugin 主体
// 原生小程序混编功能优化
// ctx.onBuildStart(() => {
// console.log('编译开始!');
// });
// ctx.onBuildFinish(() => {
// console.log('编译结束!');
// });
// console.log('原生小程序混编功能优化 ctx', ctx);
const initialConfig = ctx.ctx.initialConfig;
// console.log('原生小程序混编功能优化 initialConfig:', initialConfig);
ctx.modifyBuildAssets(({ assets }) => {
// console.log('modifyBuildAssets', assets);
// 输出一个数组
// 可以获得文件路径和文件内容
const ignoreList = [
'comp.wxml',
'base.wxml',
'custom-wrapper.wxml',
];
Object.keys(assets).forEach(src => {
if (ignoreList.includes(src)) {
return;
}
if (src.endsWith('.wxml')) {
// console.log('转换的文件', src);
// source() 函数可以获得文件内容
// 原生组件为 buffer 对象,需要 toString
// const source = assets[src].source().toString();
// parserXML 添加id
// const domStr = parserXML(source);
// 覆写source函数
// assets[src].source = function() {
// return domStr;
// };
// 一般来说,要处理的内容主要是资源文件
const fileName = src.split('.').slice(0, -1).join('.');
copyFiles(fileName, `${projectRoot}/${initialConfig.sourceRoot}`, `${projectRoot}/${initialConfig.outputRoot}`);
}
});
//console.log(copyList);
Object.keys(copyList).map((src) => {
const dest = copyList[src];
if (fs.existsSync(dest)) {
return;
}
copy(src, dest, function(error, results) {
if (error) {
console.error(`Copy ${src} failed: ${error}`);
} else {
console.info(`Copy ${src} to ${dest}`);
}
});
});
});
};
然后在 config/index.js
中修改配置:
plugins: [
[`${projectRoot}/config/plugins/raw-weapp-enhance`],
],
这样可以解决。
相关平台
微信小程序
小程序基础库: 2.14.3 使用框架: React
复现步骤
使用原生语法创建一个页面,wxml大概如:
使用taro起后,发现编译后的文件汇中并没有 images/1.png
期望结果
在混编时,如果发现wxml中有图片资源,应同步到dist
实际结果
开发者工具提示图片不存在,查看dist目录发现实际也是没有。
环境信息
补充信息
正常没问题的,只有混编才有问题。其实在config中配置copy也能解决,但是这样就不够优雅了