No meu projeto, uso alguns recursos (principalmente imagens) no SASS e no Blade. Além disso, tenho alguns recursos usados apenas no SASS e outros usados apenas no Blade.
Por exemplo, eu poderia usar mix('images/logo.png')nos arquivos Blade e background: url('../images/logo.png')nos arquivos SASS.
Quanto à minha estrutura de diretórios, fiz o seguinte:
- resources
- js
- sass
- images // All images used by Blade, Sass, or both
- fonts
Para compilar meus recursos e colocá-los na publicpasta, eu uso o seguinte 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();
Como resultado, recebo esse URL no app.css:
background: url(/images/logo.png?0e567ce87146d0353fe7f19f17b18aca);
Enquanto eu recebo outro em HTML renderizado:
src="/images/logo.png?id=4d4e33eae039c367c8e9"
Eles são considerados dois recursos diferentes, não era o que eu esperava ...
Solução potencial
Eu descobri que os arquivos CSS gerados pelo uso SASS um Versioned URL mesmo se eu não especificar version()no webpack.mix.js. Então eu estava pensando que talvez eu pudesse usar algum truque, como este:
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
});
E use-o no SASS da seguinte forma:
background-image: url(versioned('/images/logo.png'));
Mas esta solução tem muitas desvantagens, sou obrigado a usar a versionedfunção todas as vezes, meu código-fonte não funcionará facilmente em outros projetos sem a webpack.mix.jsfunção e tenho que editar todos os arquivos que utilizo na minha pasta de recursos para usar a função.
Outra solução?
Acho que a origem do meu problema pode vir da maneira como estruturei meus arquivos. Tenho uma resources/imagespasta que contém imagens usadas pelo SASS, mas também usadas pelo Blade.
As imagens usadas no SASS serão copiadas public/imagesporque é assim que o SASS trabalha com o webpack, e essas imagens também serão copiadas uma segunda vez porque eu as usei mix.copy()(porque eu preciso que os outros arquivos estejam dentro da pasta pública para estarem acessíveis no Blade / HTML).
Tenho certeza de que estou enganando em algum lugar, procurei na Internet uma maneira adequada de trabalhar com os recursos SASS e Blade no Laravel, mas não encontrei nada relevante.
Talvez eu deva considerar outra estrutura de arquivos? Mas qual deles ?
mix.version()e para arquivos CSS, há seu próprio carregador de arquivos com sua própria função de hash. Não tem nada em comum com a estruturação de arquivos. Sua solução proposta parece ser uma boa opção, não acho que exista uma solução nativa para esse problema.