TLDR
我需要在Laravel Mix中同步执行一项任务。它需要在我所有的CSS文件编译后运行。我该如何做到这一点?
背景信息
在order.less
中,有必要导入main.less
,因为其中有很多对LESS定义(CSS选择器(的依赖
order.less
中经常使用的一种技术是通过使用mixin语法来重用现有样式(在main.less
中定义(,例如:.section-title();
.btn();
等。
要知道main.less
和order.less
是比较大的文件,包含了很多@import
规则,包括其他文件。这是一个大项目。
之后我选择放弃双CSS(通过使用npm包postcss-discard
(的原因是因为我唯一的其他解决方案是:
- 重写整个LESS结构(忽略mixin调用(
- 或者直接在与订单相关的页面中应用CSS类(通过修改HTML(
但这两项任务都相当耗时。完成这项工作需要几天时间。
因此,我选择了以下方法:
@import "main.less"
在order.less
内的第一行- 之后删除重复的CSS(从webpack.mix.js中的
order.css
到postcss-discard
(
问题
因为与main.less
相比,order.less
是一个相对较小的文件,所以它的编译速度比main.css
快得多。因此,当我在main.css
相关文件中应用更改时,会出现竞争条件,并且order.css
将包含我新添加的(不需要的(CSS。之所以会发生这种情况,是因为"postCSS"任务在main.css
中应用新的更改之前就已经获取了内容。
我过于简化了我的webpack.mix.js设置:
mix.less('resources/less/main.less', 'public/css/main.css');
// Write to temporary file containing both main.css + order.css (itself)
mix.less('resources/less/order.less', 'public/css/order.tmp.css');
// Remove double CSS (after main.css is compiled)
mix.postCss('public/css/order.tmp.css', 'public/css/order.css', [
require('postcss-discard')({
css: 'public/css/main.css',
})
]);
订单较少
@import "main.less"; // Load dependencies
@import "order/helpers.less";
@import "order/grid.less";
@import "order/form.less";
@import "order/lightbox.less";
@import "order/payment.less";
@import "order/preview.less";
@import "order/responsive.less";
// etc.
main.less
@import "variables.less";
@import "base/fonts.less";
@import "base/global.less";
@import "base/utilities.less";
// etc.
如何确保order.tmp.css
和main.css
生成后执行postcss-discard
?
为了防止这种前面描述的竞争条件,他将postcss-discard
任务移到了mix.after
钩子中。看起来像这样:
const fs = require('fs');
mix.after(stats => {
console.log('Compilation complete, starting PostCSS');
let remove = 'public/css/main.css';
let from = 'public/css/order.css';
const options = {
css: fs.readFileSync(remove, {encoding:'utf8', flag:'r'}) // Remove double CSS
}
const processed = postcss([discard(options)]).process(
fs.readFileSync(from, {encoding:'utf8', flag:'r'})
).css;
fs.writeFileSync(from, processed);
console.log('PostCSS completed');
});
现在,我们确信在所有Laravel Mix任务完成执行后,双CSS会被删除。