Node实战学习:浏览器预览项目所有图片
时间:2023-01-06 21:00
在前端实际项目开发中,会有这样一种场景。每次引入新的图片,并不知道这个资源是否被引用过,所以会点开存放图片的资源一个个去看。实际问题是: 1.图片并不是放到一个目录下的,可能存在任何的地方,不好查找 2.费时间,费力 3.可能会重复引入图片资源 如果有个能力,将项目图片资源罗列到一起查看,并方便看到引入路径的话,就会大大节约开发的体力活。 如果要做这样的能力,应该考虑什么呢? 可以集成到任何前端项目中,那就要求是个 读取文件,分析哪些是图片,将图片资源通过 创建一个服务器,将html渲染出来 这就需要借助Node来实现,需要用到的 创建一个项目 包名字是 在package.json 中加入如下代码 在入口文件index.js 中加入测试代码 含义是这个文件是可执行的node文件 将当前模块链接到全局node_modules模块内,方便调试 执行 执行 就看到输出111 了 到此就实现了通过命令使用npm包的使用了,当项目安装了这个包,并配置执行命令,就可以在别的项目执行设计的npm包了,后面就实现这个 执行 就能看到当前项目执行了读取文件的包的代码了。
现在只输出了 111距离读取文件还很远,下面来实现读取文件 这里解释一下 ,各函数作用 主流程就是这样。 实现 分析一下这个文件具体要做什么 循环读取文件,直到将所有文件查找完,将图片资源过滤出来,读取文件要异步执行,如何知道何时读取完文件呢,这里用 具体代码如下: 实现 这里读取 实现 这里读取html 文件,并返回给服务器。
这里仅仅实现了对 以上就是实现过程,执行一下 为什么用异步读取文件? 因为js是单线程,同步读取文件的话会卡在那里,不能执行其他了。 为什么要用Promise 收集图片 因为不知道什么时候读取完文件,当异步读取完再用 为什么 不读取新的html文件,而将结果直接返回给浏览器? 如果将转换后 如果将转化后的 更多node相关知识,请访问:nodejs 教程! 以上就是Node实战学习:浏览器预览项目所有图片的详细内容,更多请关注gxlsystem.com其它相关文章!需求分析
npm包
img标签
写入到html文件中fs
path
http
模块。【相关教程推荐:nodejs视频教程、编程教学】实现
1 实现可发布npm包
npm init
test-read-img
"bin": {
"readimg": "./index.js"
},
#!/usr/bin/env node
console.log('111')
npm link
readimg
"scripts": {
"test": "readimg"
},
2 集成到别的项目
npm init
npm link test-read-img
"scripts": {
"test": "readimg"
},
npm run test
3 读取文件
test-read-img
项目中,声明一个执行函数,并执行. #!/usr/bin/env node
const init = async () => {
const readFiles = await getFileFun();
const html = await handleHtml(readFiles);
createServer(html);
}
init();
getFileFun
: 读取项目文件,并将读取的图片文件路径返回,这里不需要图片资源,后面解释为什么。handleHtml
: 读取模版html文件, 将图片资源通过 img
承载 生成新的html文件。createServer
: 将生成的html ,放到服务器下去渲染出来。getFileFun
功能promise
实现,这里仅仅实现了单层文件的读取
,因为发布到公司内部的npm,请见谅。 聪明的你这里想想如何递归实现呢?getFileFun
: 应该先读取完文件,才能将图片返回,所以异步收集器应该在后面执行。 const fs = require('fs').promises;
const path = require('path');
const excludeDir = ['node_modules','package.json','index.html'];
const excludeImg = ['png','jpg','svg','webp'];
let imgPromiseArr = []; // 收集读取图片,作为一个异步收集器
async function readAllFile(filePath) { // 循环读文件
const data = await fs.readdir(filePath)
await dirEach(data,filePath);
}
async function handleIsImgFile(filePath,file) {
const fileExt = file.split('.');
const fileTypeName = fileExt[fileExt.length-1];
if(excludeImg.includes(fileTypeName)) { // 将图片丢入异步收集器
imgPromiseArr.push(new Promise((resolve,reject) => {
resolve(`${filePath}${file}`)
}))
}
}
async function dirEach(arr=[],filePath) { // 循环判断文件
for(let i=0;i<arr.length;i++) {
let fileItem = arr[i];
const basePath = `${filePath}${fileItem}`;
const fileInfo = await fs.stat(basePath)
if(fileInfo.isFile()) {
await handleIsImgFile(filePath,fileItem)
}
}
}
async function getFileFun() { // 将资源返回给调用使用
await readAllFile('./');
return await Promise.all(imgPromiseArr);
}
module.exports = {
getFileFun
}
handleHtml
test-read-img
的html文件,并替换。 const fs = require('fs').promises;
const path = require('path');
const createImgs = (images=[]) => {
return images.map(i => {
return `<div class='img-warp'>
<div class='img-item'> <img src='${i}' /> </div>
<div class='img-path'>文件路径 <span class='path'>${i}</span></div>
</div>`
}).join('');
}
async function handleHtml(images=[]) {
const template = await fs.readFile(path.join(__dirname,'template.html'),'utf-8')
const targetHtml = template.replace('%--%',`
${createImgs(images)}
`);
return targetHtml;
}
module.exports = {
handleHtml
}
createServer
png
的文件的展示,对于其他类型的图片如何支持呢,这里提示一下对 content-type
进行处理。 const http = require('http');
const fs = require('fs').promises;
const path = require('path');
const open = require('open');
const createServer =(html) => {
http.createServer( async (req,res) => {
const fileType = path.extname(req.url);
let pathName = req.url;
if(pathName === '/favicon.ico') {
return;
}
let type = ''
if(fileType === '.html') {
type=`text/html`
}
if(fileType === '.png') {
type='image/png'
}
if(pathName === '/') {
res.writeHead(200,{
'content-type':`text/html;charset=utf-8`,
'access-control-allow-origin':"*"
})
res.write(html);
res.end();
return
}
const data = await fs.readFile('./' + pathName );
res.writeHead(200,{
'content-type':`${type};charset=utf-8`,
'access-control-allow-origin':"*"
})
res.write(data);
res.end();
}).listen(3004,() => {
console.log('project is run: http://localhost:3004/')
open('http://localhost:3004/')
});
}
module.exports = {
createServer
}
效果
npm run test
就可以看到浏览器执行在http://localhost:3004/, 效果如下:发布
npm login
npm publish
思考
Promise.all
整体处理html放到
test-read-img
文件,就必须将图片资源也要生成在当前目录,要不然html 读取的相当路径资源是找不到的,因为资源都在使用项目中。结束的时候还要将图片资源删除,这也无形增加了复杂度;html 写入放到使用项目
中,这样就可以直接用图片的路径,并能正确加载,但是这样会多了一个html文件,程序退出的时候还要删除这个,如果忘记删除了,就可能被开发者提交到远程,造成污染,提供的预览应该是无害的。这两种方式都不可取。因此直接返回html资源,让它去加载相对目标项目路径,不会产生任何影响。