Trong dự án của tôi, tôi sử dụng một số tài nguyên (chủ yếu là hình ảnh) trong cả SASS và Blade. Ngoài ra, tôi có một số tài nguyên chỉ được sử dụng trong SASS và một số tài nguyên chỉ được sử dụng trong Blade.
Ví dụ: tôi có thể sử dụng mix('images/logo.png')
trong các tệp Blade và background: url('../images/logo.png')
trong các tệp SASS.
Đối với cấu trúc thư mục của tôi, tôi đã làm như sau:
- resources
- js
- sass
- images // All images used by Blade, Sass, or both
- fonts
Để biên dịch tài nguyên của tôi và đặt chúng vào public
thư mục, tôi sử dụng như sau webpack.mix.js
:
mix.copy('resources/images/**/*.*', 'public/images');
mix.copy('resources/fonts/**/*.*', 'public/fonts');
mix.version('public/images/**/*.*');
mix.version('public/fonts/**/*.*');
mix.js('resources/js/app.js', 'public/js')
.js('resources/js/vendor.js', 'public/js')
.scripts([ // Old not ES6 JS
'resources/js/tpl/core.min.js'
], 'public/js/core.min.js')
.sass('resources/sass/app.scss', 'public/css')
.sourceMaps()
.version();
Kết quả là tôi nhận được URL đó trong app.css:
background: url(/images/logo.png?0e567ce87146d0353fe7f19f17b18aca);
Trong khi tôi nhận được một cái khác trong HTML được kết xuất:
src="/images/logo.png?id=4d4e33eae039c367c8e9"
Chúng được coi là 2 tài nguyên khác nhau, đó không phải là điều tôi mong đợi ...
Cách giải quyết tiềm năng
Tôi phát hiện ra rằng các file CSS được tạo ra bởi Sass sử dụng một phiên bản URL ngay cả khi tôi không chỉ định version()
trong webpack.mix.js
. Vì vậy, tôi đã tự hỏi có lẽ tôi có thể sử dụng một số mẹo, như thế này:
const sass = require('sass');
// Custom SASS function to get versioned file name
// Uses Mix version md5 hash
const functions = {
'versioned($uri)': function(uri, done) {
uri = uri && uri.getValue() || uri;
const version = File.find(path.join(Config.publicPath, uri)).version();
done(new sass.types.String(`${uri}?id=${version}`));
}
};
mix.sass('resources/sass/all.scss', 'public/css', {
sassOptions: {
functions
}
})
.options({ // Do not process URLs anymore
processCssUrls: false
});
Và sử dụng nó trong SASS như vậy:
background-image: url(versioned('/images/logo.png'));
Nhưng giải pháp này có rất nhiều nhược điểm, tôi bắt buộc phải sử dụng versioned
chức năng này mỗi lần, mã nguồn của tôi sẽ không hoạt động dễ dàng trong các dự án khác mà không có webpack.mix.js
chức năng này và tôi phải chỉnh sửa mọi tệp mà tôi sử dụng trong thư mục tài nguyên của mình để sử dụng chức năng.
Giải pháp nào khác?
Tôi nghĩ rằng nguồn gốc của vấn đề của tôi có thể đến từ cách tôi cấu trúc các tệp của mình, tôi có một resources/images
thư mục chứa hình ảnh được sử dụng bởi SASS nhưng cũng được sử dụng bởi Blade.
Hình ảnh được sử dụng trong SASS sẽ được sao chép vào public/images
vì đó là cách SASS hoạt động với webpack và những hình ảnh này cũng sẽ được sao chép lần thứ hai vì tôi đã sử dụng mix.copy()
(vì tôi cần các tệp khác ở trong thư mục công cộng để có thể truy cập trong Blade / HTML).
Tôi khá chắc chắn rằng tôi đang nhầm lẫn ở đâu đó, tôi đã tìm trên internet một cách thích hợp để làm việc với các tài nguyên SASS và Blade trong Laravel nhưng tôi không tìm thấy bất cứ điều gì có liên quan.
Có lẽ tôi nên xem xét một cấu trúc tập tin khác? Nhưng cái nào?
mix.version()
và cho các tệp CSS, có trình tải tệp riêng với chức năng băm riêng. Nó không có gì chung với cấu trúc tập tin. Giải pháp đề xuất của bạn dường như là một lựa chọn tốt, tôi không nghĩ có một giải pháp riêng cho vấn đề này.