fs.unlinkSync 在 Sails 上的 Grunt 错误
Grunt error with fs.unlinkSync on Sails
我正在使用 skipper 接收文件,使用 sharp 调整大小(并保存)并使用 fs unlink 删除旧图像。但是这次我遇到了一个非常奇怪的错误,这让我很担心:
error: ** Grunt :: An error occurred. **
error:
Aborted due to warnings.
Running "copy:dev" (copy) task
Warning: Unable to read "assets/images/users/c8e303ca-1036-4f52-88c7-fda7e01b6bba.jpg" file (Error code: ENOENT).
error: Looks like a Grunt error occurred--
error: Please fix it, then restart Sails to continue running tasks (e.g. watching for changes in assets)
error: Or if you're stuck, check out the troubleshooting tips below.
error: Troubleshooting tips:
error:
error: *-> Are "grunt" and related grunt task modules installed locally? Run npm install
if you're not sure.
error:
error: *-> You might have a malformed LESS, SASS, CoffeeScript file, etc.
error:
error: *-> Or maybe you don't have permissions to access the .tmp
directory?
error: e.g., (edited for privacy)/sails/.tmp
?
error:
error: If you think this might be the case, try running:
error: sudo chown -R 1000 (edited for privacy)/sails/.tmp
Grunt 停止了 运行 并且在生产中使用它是一个很大的禁忌......我相信这是由于 fs.unlinkSync(fname) 的并发造成的。该错误也是间歇性的,并且在某些机器上很难重现(也许是 IO ops/sec?)。
我有以下控制器操作:
var id = 1; // for example
req.file('avatar').upload({
dirname: require('path').resolve(sails.config.appPath, 'assets/images')
}, function(err, files){
var avatar = files.pop();
//file name operations here. output is defined as the path + id + filetype
//...
sharp(avatar.fd)
.resize(800, 800)
.toFile(output, (err, info)=>{
if(err){
res.badRequest();
} else {
fs.unlinkSync(avatar.fd);
res.ok();
}
});
});
现在我一直在思考几个解决方案:
- 将新图片直接输出到
.temp
.tmp
上存在文件时取消链接。解释:Grunt 已经复制了旧文件,所以删除它是安全的!
但我不知道这是否是一些意大利面条代码,或者是否存在更好的解决方案。
编辑:按照 arbuthnott 的建议,我的解决方案是像这样包装一个控制器:
get : function(req, res){
var filepath = req.path.slice(1,req.path.length);
//remove '/' root identifier. path.resolve() could be used
if(fs.existsSync(path.resolve(filepath))){
return res.sendfile(filepath);
} else {
return res.notFound();
}
}
我认为您对错误的看法是正确的。您正在对 assets 文件夹进行一些快速更改。如果我没看错你的代码:
- 将带有用户生成文件名的图像添加到
assets/images
(例如 cat.jpg
)
- Copy/resize 文件到
assets/images
中的 id 文件名(例如 abc123.jpg
)
- 删除原上传(
cat.jpg
)
(我不知道 sharp 的细节,那里可能还有更多内容)
如果 sails 运行 处于开发模式,那么 Grunt 将尝试监视整个 assets/
文件夹,并将所有更改复制到 .tmp/public/
。很容易想象 Grunt 可能会注册一个更改,但是当它开始复制添加的文件时 (assets/images/cat.jpg
) 它已经消失了。
我有两个解决方案的建议:
一个:
按照您的建议,将您的原件上传到 .tmp
文件夹(甚至可以是 .tmp
的自定义子文件夹)。仍然将您的尺寸副本放入 /assets/images/
,它将被复制到 /.tmp/public/
,运行 应用程序可以将其作为资产访问。但是 Grunt 将忽略 .tmp
文件夹中的快速添加然后删除。
两个:
对您希望包含在版本控制中的内容以及您希望在生产中成为 运行 的 Grunt 任务做一些一般性的思考。请注意,如果您使用 sails lift --prod
,则默认情况下 Grunt watch 是关闭的,甚至不会出现此错误。一般来说,我不觉得我们希望 Grunt 在生产中做太多,它更像是一条开发捷径。具体来说,Grunt watch 会在生产服务器上使用大量资源。
关于版本控制的注意事项只是您可能希望 assets/images/
的某些内容在版本控制中(站点使用的图像等),但在用户的情况下可能不是-上传的头像。确保你有办法区分这些内容(子目录或其他)。然后他们可以很容易地 .git-ignore
' 或任何合适的。
希望对您有所帮助,祝您好运!
我正在使用 skipper 接收文件,使用 sharp 调整大小(并保存)并使用 fs unlink 删除旧图像。但是这次我遇到了一个非常奇怪的错误,这让我很担心:
error: ** Grunt :: An error occurred. ** error: Aborted due to warnings. Running "copy:dev" (copy) task Warning: Unable to read "assets/images/users/c8e303ca-1036-4f52-88c7-fda7e01b6bba.jpg" file (Error code: ENOENT).
error: Looks like a Grunt error occurred-- error: Please fix it, then restart Sails to continue running tasks (e.g. watching for changes in assets) error: Or if you're stuck, check out the troubleshooting tips below.
error: Troubleshooting tips: error: error: *-> Are "grunt" and related grunt task modules installed locally? Run
npm install
if you're not sure. error: error: *-> You might have a malformed LESS, SASS, CoffeeScript file, etc. error: error: *-> Or maybe you don't have permissions to access the.tmp
directory? error: e.g.,(edited for privacy)/sails/.tmp
? error: error: If you think this might be the case, try running: error: sudo chown -R 1000 (edited for privacy)/sails/.tmp
Grunt 停止了 运行 并且在生产中使用它是一个很大的禁忌......我相信这是由于 fs.unlinkSync(fname) 的并发造成的。该错误也是间歇性的,并且在某些机器上很难重现(也许是 IO ops/sec?)。
我有以下控制器操作:
var id = 1; // for example
req.file('avatar').upload({
dirname: require('path').resolve(sails.config.appPath, 'assets/images')
}, function(err, files){
var avatar = files.pop();
//file name operations here. output is defined as the path + id + filetype
//...
sharp(avatar.fd)
.resize(800, 800)
.toFile(output, (err, info)=>{
if(err){
res.badRequest();
} else {
fs.unlinkSync(avatar.fd);
res.ok();
}
});
});
现在我一直在思考几个解决方案:
- 将新图片直接输出到
.temp
.tmp
上存在文件时取消链接。解释:Grunt 已经复制了旧文件,所以删除它是安全的!
但我不知道这是否是一些意大利面条代码,或者是否存在更好的解决方案。
编辑:按照 arbuthnott 的建议,我的解决方案是像这样包装一个控制器:
get : function(req, res){
var filepath = req.path.slice(1,req.path.length);
//remove '/' root identifier. path.resolve() could be used
if(fs.existsSync(path.resolve(filepath))){
return res.sendfile(filepath);
} else {
return res.notFound();
}
}
我认为您对错误的看法是正确的。您正在对 assets 文件夹进行一些快速更改。如果我没看错你的代码:
- 将带有用户生成文件名的图像添加到
assets/images
(例如cat.jpg
) - Copy/resize 文件到
assets/images
中的 id 文件名(例如abc123.jpg
) - 删除原上传(
cat.jpg
)
(我不知道 sharp 的细节,那里可能还有更多内容)
如果 sails 运行 处于开发模式,那么 Grunt 将尝试监视整个 assets/
文件夹,并将所有更改复制到 .tmp/public/
。很容易想象 Grunt 可能会注册一个更改,但是当它开始复制添加的文件时 (assets/images/cat.jpg
) 它已经消失了。
我有两个解决方案的建议:
一个:
按照您的建议,将您的原件上传到 .tmp
文件夹(甚至可以是 .tmp
的自定义子文件夹)。仍然将您的尺寸副本放入 /assets/images/
,它将被复制到 /.tmp/public/
,运行 应用程序可以将其作为资产访问。但是 Grunt 将忽略 .tmp
文件夹中的快速添加然后删除。
两个:
对您希望包含在版本控制中的内容以及您希望在生产中成为 运行 的 Grunt 任务做一些一般性的思考。请注意,如果您使用 sails lift --prod
,则默认情况下 Grunt watch 是关闭的,甚至不会出现此错误。一般来说,我不觉得我们希望 Grunt 在生产中做太多,它更像是一条开发捷径。具体来说,Grunt watch 会在生产服务器上使用大量资源。
关于版本控制的注意事项只是您可能希望 assets/images/
的某些内容在版本控制中(站点使用的图像等),但在用户的情况下可能不是-上传的头像。确保你有办法区分这些内容(子目录或其他)。然后他们可以很容易地 .git-ignore
' 或任何合适的。
希望对您有所帮助,祝您好运!