작은 프로젝트, 시작부터 배포까지
18828 단어 glitchwebdevtutorialjavascript
나는 이전에 MDN 웹 문서에서 이번 주 기사에 대한 연구 여행을 촉발할 무언가를 찾고 있었는데 임의의 페이지 링크가 없다는 것을 발견했습니다. 랜덤 페이지 기능은 웹 기술의 일반적인 수정에 유용할 것입니다. 흥미로워 보이는 항목을 클릭할 수 있습니다.
저는 JavaScript용 index page을 해킹하는 것으로 여행을 시작했습니다. 이것은 종종 DevTools를 사이트의 초안 버전으로 사용하여 직장에서 프런트 엔드 웹 문제를 해결하는 방법이기도 합니다.
HTML에는
document.querySelector("#wikiArticle > table > tbody")
에 테이블 본문이 있습니다. Chrome에서는 요소를 마우스 오른쪽 버튼으로 클릭하고 이동Copy -> Copy JS Path
하여 이를 찾을 수 있습니다. 각 항목은 세 개의 테이블 행을 사용합니다. 나는 페이지 링크와 요약을 쫓고 있습니다. 행을 각각 하나의 항목을 구성하는 그룹으로 분리해 보겠습니다.콘솔에서 이 줄을 실행할 수 있습니다.
// Index table
const indexTable = document.querySelector("#wikiArticle > table > tbody");
// There are three <tr>s to a row
const allRows = indexTable.querySelectorAll('tr');
const chunkRows = [];
for (var i = 0; i < allRows.length; i += 3) {
chunkRows.push([allRows[i], allRows[i + 1], allRows[i + 2]]);
}
인덱스 페이지 데이터의 복사본을 어딘가에 저장해야 합니다. 각 요청마다 페이지를 스크랩하는 것은 낭비적이고 느립니다. 웹을 통해 전달할 것이므로 JSON으로 저장하는 것이 가장 적합합니다. 페이지 스니펫에는 링크 속성과 텍스트 속성이 있어야 합니다. 여기서도 일부 템플릿을 처리하겠습니다.
// Map these chunked rows into a row object
const pageEntries = [];
chunkRows.forEach(row => {
const a = row[0].querySelector('a');
const page = {
link: `<a class="page-link "href="${a.href}">${a.innerText}</a>`,
text: `<div class="page-text">${row[1].querySelector('td').innerText}</div>`
}
pageEntries.push(page);
})
이를 사용자에게 어떻게 전달할 것인지 결정해야 했습니다. Chrome 확장 프로그램을 고려했지만 프로토타입을 더 빨리 만들고 싶었기 때문에 Glitch로 전환하여 Express 템플릿을 사용했습니다.
스크래핑 논리를 비동기 함수로 패키징하고 puppeteer을 사용하여 인덱스 페이지의 컨텍스트에서 이러한 명령을 실행했습니다. (Glitch에서는 보안 위험이 될 수 있는
--no-sandbox
를 사용해야 합니다.) 완료된 프로젝트에서 node getNewPages.js
를 사용하여 이 스크립트를 수동으로 호출하여 디스크의 항목을 업데이트할 수 있습니다. (이것은 크론 작업에 깔끔하게 맞을 것입니다!).Chrome DevTool 해커에서 좀 더 응집력 있는 것까지.
// getNewPages.js
const fs = require('fs');
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: ['--no-sandbox'] // Required for Glitch
});
const page = await browser.newPage();
await page.goto('https://developer.mozilla.org/en-US/docs/Web/JavaScript/Index');
// Scan index table, gather links and summaries
const pageEntries = await page.evaluate(() => {
// Index table
const indexTable = document.querySelector("#wikiArticle > table > tbody");
// There are three <tr>s to a row
const allRows = indexTable.querySelectorAll('tr');
const chunkRows = [];
for (var i = 0; i < allRows.length; i += 3) {
chunkRows.push([allRows[i], allRows[i + 1], allRows[i + 2]]);
}
// Map these chunked rows into a row object
const pageEntries = [];
chunkRows.forEach(row => {
const a = row[0].querySelector('a');
const page = {
link: `<a class="page-link "href="${a.href}">${a.innerText}</a>`,
text: `<div class="page-text">${row[1].querySelector('td').innerText}</div>`
}
pageEntries.push(page);
})
return pageEntries;
});
// Save page objects to JSON on disk
const pageJSON = JSON.stringify(pageEntries);
fs.writeFile('./data/pages.json', pageJSON, function (err) {
if (err) {
return console.log(err);
}
console.log(`New pages saved! (JSON length: ${pageJSON.length})`);
});
await browser.close();
})();
더 빠른 액세스를 위해 모든 페이지 항목을 메모리에 유지하는
require('./data/pages.json')
를 사용하여 JSON 파일을 노드에 로드할 수 있습니다(이는 ~300kb의 고정된 작은 크기로 인해 가능함). 웹 앱의 나머지 부분은 임의 함수를 둘러싼 래퍼입니다.// server.js
// init project
const express = require('express');
const app = express();
app.use(express.static('public'));
const pages = require('./data/pages.json');
const rndPage = () => pages[Math.floor(Math.random() * pages.length)];
app.get('/', (req, res) => res.sendFile(__dirname + '/views/index.html'));
app.get('/rnd', (req, res) => res.send(rndPage()));
// listen for requests :)
const listener = app.listen(process.env.PORT, function() {
console.log('Your app is listening on port ' + listener.address().port);
});
우리에게 필요한 유일한 클라이언트 측 JavaScript는 페이지 링크 및 요약을 업데이트하기 위한
fetch
호출입니다. 뿐만 아니라 귀여운 흔들림 애니메이션이 있는 버튼으로 항목을 넘길 수 있습니다. 같은 스니펫이 두 번 나올 확률은 897분의 1입니다. 어떻게 해결하시겠습니까? 댓글로 알려주세요!여기에서 이동: 동일한 행 패턴을 따르는 MDN 문서(JavaScript 제외)의 다른 페이지가 있습니다. 즉, 스크립트에서 URL을 변경하여 간단하게 스크랩할 수 있습니다.
코드 사본을 사용하여 프로젝트를 재생하거나remix 리포지토리를 복제할 수 있습니다healeycodes/random-mdn-page.
프로그래밍 및 개인 성장에 대해 150명 이상의 사람들이 내newsletter에 가입했습니다!
기술에 대해 트윗합니다.
Reference
이 문제에 관하여(작은 프로젝트, 시작부터 배포까지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/healeycodes/a-tiny-project-from-inception-to-deployment-784텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)