Laravel刀片、Mix和SASS资源版本控制共享
在我的项目中,我在SASS和Blade中使用了一些资源(主要是图像)。另外,我有一些资源仅用于SASS,还有一些资源仅用于Blade 例如,我可以在刀片文件中使用Laravel刀片、Mix和SASS资源版本控制共享,laravel,sass,frontend,laravel-blade,laravel-mix,Laravel,Sass,Frontend,Laravel Blade,Laravel Mix,在我的项目中,我在SASS和Blade中使用了一些资源(主要是图像)。另外,我有一些资源仅用于SASS,还有一些资源仅用于Blade 例如,我可以在刀片文件中使用mix('images/logo.png'),在SASS文件中使用background:url('../images/logo.png') 关于我的目录结构,我做了以下工作: - resources - js - sass - images // All images used by Blade, Sass,
mix('images/logo.png')
,在SASS文件中使用background:url('../images/logo.png')
关于我的目录结构,我做了以下工作:
- resources
- js
- sass
- images // All images used by Blade, Sass, or both
- fonts
为了编译我的资源并将它们放在public
文件夹中,我使用以下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();
结果,我在app.css中获得了该URL:
background: url(/images/logo.png?0e567ce87146d0353fe7f19f17b18aca);
当我在呈现的HTML中获得另一个时:
src="/images/logo.png?id=4d4e33eae039c367c8e9"
他们被认为是两种不同的资源,这不是我所期望的
潜在解决方案
我发现,即使我没有在webpack.mix.js
中指定version()。所以我想也许我可以用一些技巧,比如:
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
});
并在SASS中使用它,如下所示:
background-image: url(versioned('/images/logo.png'));
但是这个解决方案有很多缺点,每次我都必须使用版本控制的
函数,如果没有webpack.mix.js
函数,我的源代码在其他项目中很难工作,我必须编辑我在资源文件夹中使用的每个文件才能使用该函数
其他解决方案?
我认为问题的根源可能来自我构建文件的方式,我有一个resources/images
文件夹,其中包含SASS使用的图像,但Blade也使用这些图像。
SASS中使用的图像将被复制到public/Images
,因为这是SASS处理Web包的方式,这些图像也将被第二次复制,因为我使用了mix.copy()
(因为我需要其他文件位于公用文件夹中,以便在Blade/HTML中访问)
我很确定我在某个地方搞错了,我在互联网上查找了一种在Laravel中使用SASS和刀片资源的正确方法,但没有找到任何相关信息。
也许我应该考虑另一种文件结构?但是哪一个呢
我发现SASS生成的CSS文件使用版本化URL,即使我没有在webpack.mix.js中指定version()
在样式表中重写url()
是一个简单的过程,它将文件的计算MD5哈希附加到url<另一方面,code>mix.version()
由于
/**
*读取文件的内容。
*/
读(){
返回fs.readFileSync(this.path(),'utf8');
}
/**
*计算文件的正确版本哈希。
*/
版本({
返回md5(this.read()).substr(0,20);
}
Laravel Mix将文件读取为字符串(而不是缓冲区),对其进行散列并仅提取前20个字符。我想不出一个简单的方法来覆盖这个行为,一个快速而肮脏的解决方法是重新定义散列
函数:
const mix=require('laravel-mix');
设md5=require('md5');
设fs=require('fs-extra');
Mix.manifest.hash=函数(文件){
设f=新文件(path.join(Config.publicPath,File));
让hash=md5(fs.readFileSync(f.path());
让filePath=this.normalizePath(文件);
this.manifest[filePath]=filePath+'?'+哈希;
归还这个;
}
更好的方法是定义自己的
versionMD5()
方法,您可以从中复制一些代码。我想给出自己的想法,同时我也面临同样的问题。Laravel Mix以不同的方式处理.blade和CSS/JS文件。对于徽标图像,您不会得到与它使用的.blade资产相同的哈希值。对于CSS文件,它有自己的文件加载器和哈希函数。它与文件结构没有任何共同之处。您提出的解决方案似乎是一个不错的选择,我认为这个问题没有本机解决方案。