背景
在微信小程序的开发中,我们使用LESS
进行样式开发,并通过easy-less
编译成WXSS
。然而,由于历史原因,有些开发者只修改了WXSS
文件而没有同步更新对应的LESS
文件。这导致在后续开发中,修改LESS
文件会覆盖前一个开发者在WXSS
文件中的样式,更严重地影响了项目的维护和更新。
问题描述
- 样式不一致:由于直接修改
WXSS
文件,LESS
与WXSS
文件之间缺乏一致性,导致样式管理混乱。😤 - 代码覆盖:当有人修改
LESS
文件并重新编译时,会覆盖之前直接在WXSS
文件中进行的修改,导致样式冲突和混乱。 - 维护困难:由于无法直接从
LESS
文件反映WXSS
文件的最新状态,维护和更新样式变得极为困难。
优化方案
1. 编译所有less成wxss
由于我们之前用的是easy-less
的插件编译,所以为了保证wxss转换后的一致性。我在easy-less的源码中添加了一个新功能,该功能可以将项目下所有的LESS文件编译成对应的WXSS文件。顺便给该项目提交了一个PR哈哈哈哈。🥸
// 在源码的/src/easyLess.ts
// compile all less files in workspace
const compileAllLessCommand = vscode.commands.registerCommand('extension.compileAllLess', async () => {
const files = await vscode.workspace.findFiles('**/*.less', '**/node_modules/**');
files.forEach(file => {
vscode.workspace.openTextDocument(file).then(document => {
new CompileLessCommand(document, lessDiagnosticCollection).setPreprocessors(preprocessors).execute();
});
});
});
context.subscriptions.push(compileAllLessCommand);
// package.json
"contributes": {
"menus": {
"editor/context": [
{
"command": "extension.compileAllLess",
"group": "navigation"
}
]
},
"commands": [
{
"command": "extension.compileAllLess",
"title": "Compile All Less Files"
}
],
}
点击F5调试,打开项目目录,点击F1输入Compile All Less Files
,或者右键选择。
2. 还原未被修改的LESS
借助VSCode的Git功能,对比这些编译生成的WXSS文件的变更情况。对于有改动的WXSS文件,就代表这个wxss文件被更改过。然后在对应的LESS文件上进行修改,确保所有的LESS和WXSS文件都可以一一对应。(从270几个文件中找到26个文件被修改过)😫😫
3. 删除WXSS文件
在确保所有的LESS和WXSS文件一一对应后,我将项目中的所有有LESS依赖的WXSS文件全部删除(因为有几个公用的样式文件是直接用WXSS写的)
。之后,在小程序打包时才将WXSS文件从LESS文件编译出来。这样一来,项目中只保留LESS文件,避免了之前的样式冲突问题。
const fs = require('fs');
const path = require('path');
function deleteFile(filePath) {
fs.unlink(filePath, (err) => {
if (err) {
console.error(`Error deleting file ${filePath}:`, err);
} else {
console.log(`File ${filePath} deleted.`);
}
});
}
function traverseDir(dir) {
fs.readdir(dir, (err, files) => {
if (err) {
console.error(`Error reading directory ${dir}:`, err);
return;
}
files.forEach((file) => {
const filePath = path.join(dir, file);
fs.stat(filePath, (err_, stats) => {
if (err_) {
console.error(`Error getting stats for file ${filePath}:`, err_);
return;
}
if (stats.isDirectory()) {
traverseDir(filePath);
} else if (path.extname(filePath) === '.less') {
const wxssFilePath = filePath.replace(/\.less$/, '.wxss');
fs.access(wxssFilePath, fs.constants.F_OK, (err__) => {
if (!err__) {
deleteFile(wxssFilePath);
}
});
}
});
});
});
}
traverseDir('.');
4. 实时监听LESS文件变更,生成对应WXSS
由于我们项目是原生和Taro混编项目,在开发阶段需要监听原生项目的文件改动,并将改动的文件copy到dist文件夹内🤬。当LESS文件发生变更时,我会先把LESS文件copy到编译的文件夹中,然后直接利用gulp-less对less编译成wxss。(注意是在编译的文件夹中操作,不是在源码中) 确保了开发过程中样式文件的一致性和实时性。(此操作用的是chokidar
进行监听)🤯
5. 使用Gulp在打包时编译LESS到WXSS
在打包过程中,我使用了Gulp进行自动化编译。Gulp会将项目中的LESS文件转换成WXSS文件,并将其放置在编译后的dist文件夹中对应的位置。
// gulpfile.js
const path = require('path')
const fs = require('fs')
const glob = require('glob')
var gulp = require('gulp') // 载入Gulp模块
var less = require('gulp-less') // 载入gulp-less模块
var cssnano = require('gulp-cssnano') //css优化分离
const rename = require('gulp-rename')
const rootPath = path.resolve(__dirname, './')
const distPath = path.join(rootPath, './dist/wxapp') // 原生小程序项目打包后的目录
gulp.task('less', function () {
return gulp
.src([`${distPath}/**/*.less`])
.pipe(less())
.on('error', function (err) {
console.error('Less compilation error:', err.message)
})
.pipe(
cssnano({
reduceIdents: false, // 不压缩动画名字
autoprefixer: false, // 不需要自动前缀
zindex: false, // 不压缩z-index
}),
)
.on('error', function (err) {
console.error('Cssnano error:', err.message)
})
.pipe(
rename(function (_) {
_.extname = '.wxss'
}),
)
.pipe(gulp.dest(distPath))
.on('error', function (err) {
console.error('Gulp dest error:', err.message)
})
.on('end', function () {
glob(`${distPath}/**/*.less`, (err, files) => {
if (err) {
console.error('Glob error:', err.message)
} else {
files.forEach((file) => {
fs.unlinkSync(file)
console.log(`Deleted ${file}`)
})
}
})
})
})
优化效果
项目在以下方面取得了显著改善:
- 工具单一性:删除了无依赖的WXSS,只剩下LESS进行开发。🫡
- 维护便利:以后所有样式修改都集中在LESS文件中,简化了维护工作。🫠
结论
通过此优化手段,终于解决了微信小程序开发中的样式管理的历史问题。此优化方案不仅提升了项目的开发效率,还确保了代码的一致性和可维护性。🫨😑
有更好方案或者有疑问的小伙伴欢迎在评论区留言