çŸåšãAPIã«ãŒããŸãã¯ããŒãžãããã¡ã€ã«ãèªã¿åãããšã¯ã§ããŸããã
__dirname
ãã¹ã䜿çšããŠfs.readFile
ãåŒã³åºãããæ£åžžã«æ©èœãããããã«ãããã
ããã¯ãéçºã¢ãŒããšæ¬çªã¢ãŒãã§æ©èœããã¯ãã§ãã
ããã¯ãããçšåºŠã®å®¹éã§@zeit/webpack-asset-relocator-loader
ãšçµ±åããå¿
èŠãããå ŽåããããŸãã ãã®ãã©ã°ã€ã³ã¯ããããã®ã¿ã€ãã®èŠä»¶ãåŠçããŸãã
ãã ããããã¯å¿
é ã§ã¯ãããŸããã __dirname
ãš__filename
ã§_only_ãæ©èœãããã®ã§åé¡ãããŸããïŒçžå¯Ÿãã¹ãŸãã¯cwdããŒã¹ã®ãã¹ã¯ãããŸããïŒã
äŸïŒ
// pages/api/test.js
import fs from 'fs'
import path from 'path'
export default (req, res) => {
const fileContent = fs.readFileSync(
path.join(__dirname, '..', '..', 'package.json'),
'utf8'
)
// ...
}
泚ïŒäžèšã®äŸâïžã
require
ã§ããŸããããšãã§ããããšã¯ç¥ã£ãŠããŸãããããã¯éèŠã§ã¯ãããŸããã ð
APIã«ãŒãã䜿çšããŠãã¡ã€ã«ã®ã¢ããããŒããå®è£ ããããšããŠãããã2çªç®ã«ãããã£ãã ãã§ãã ãã¡ã€ã«ãã¢ããããŒãããããšã¯ã§ããŸãããS3ãã±ããã«ã¢ããããŒãããã«ã¯ãã¡ã€ã«ã«å床ã¢ã¯ã»ã¹ã§ããå¿ èŠããããŸãã
ç§ã¯ããã2çªç®ã«ïŒ ãŸããããŒã ã¡ã³ããŒãããã°æçš¿ãªã©ã®ããŒã¿ãã³ã³ãã³ããã£ã¬ã¯ããªã«ä¿æããããããã£ã¬ã¯ããªå ã®ãã¹ãŠã®ãã¡ã€ã«ãèŠæ±ããæ¹æ³ãæ¢ããŠããããããã£ã¬ã¯ããªãèªã¿åãããšãã§ããããšã¯ãç§ã®äŒç€Ÿã®äœ¿çšæ³ã«ãšã£ãŠéåžžã«éèŠã§ãã
äžèšã®PRã¯ãããä¿®æ£ããŸãïŒ âïžð
fs.writeFile
ã¯ã©ãã§ããïŒ ããšãã°ã /api/route
ã«æçš¿ãããWebhookã«åºã¥ããŠJSONãã¡ã€ã«ãäœæããŠä¿åããŸã
ãã@marlonmarcello ãããã¯å¯èœã«ãªãã§ãããã ãã°ãããåŸ ã¡ãã ããð
ããã¯ãã§ã«è§£æ±ºãããŠããŸããïŒ
ãŸã ãïŒ8334ã賌èªã§ããŸã
@ huv1kã©ããããããšãïŒ
ãããããè¿ éã«é²ããã®ã«åœ¹ç«ã€æ¹æ³ã¯ãããŸããïŒ
泚ç®ã«å€ããïŒããªãã¯æŽ»åäœã䜿çšããŠããå Žåãããªãã¯ãã§ã«çŽæ¥ã¢ãžã¥ãŒã«ãšããŠJSONãã¡ã€ã«ãã€ã³ããŒãããããšãã§ããŸãïŒç¢ºèªããŠãã ããresolveJsonModule
ã§true
ã§tsconfig.json
ïŒã äŸãã°ïŒ
import myJson from '../../../some/path/my.json';
JSONãªããžã§ã¯ãã®åœ¢ç¶ããã®åãšããŠèªåçã«äœ¿çšãããããããªãŒãã³ã³ããªãŒãã¯éåžžã«åªããŠããŸãã
ç§ã䜿çšããŠããåé¿çïŒ
# next.config.js
module.exports = {
serverRuntimeConfig: {
PROJECT_ROOT: __dirname
}
}
ãããŠããªãããã¹ãå¿ èŠãšããå Žæã§
import fs from 'fs'
import path from 'path'
import getConfig from 'next/config'
const { serverRuntimeConfig } = getConfig()
fs.readFile(path.join(serverRuntimeConfig.PROJECT_ROOT, './path/to/file.json'))
ããã§ã¯ãçŸåšã®ãã¡ã€ã«ããã®çžå¯Ÿãã¹ã§ãã¡ã€ã«ãåç
§ããå¿
èŠããªãããšã¯ããã£ãŠããŸãããéåžžã«é¢é£ãããŠãŒã¹ã±ãŒã¹ïŒ /public/images
ãã©ã«ããŒããç»åãã¡ã€ã«ãèªã¿åãïŒã¯è§£æ±ºããŸãã
PRã§ãããå°ãå€ãã£ãã®ãèŠãŸãã-çŸåšã®èšç»ãäœã§ãããïŒãŸãã¯ããã§ãªããïŒã«é¢ããæŽæ°ã¯ãããŸããïŒ è¿œæ±ããããªãæŠç¥ãããã€ãããããã«æãããŸããããããããªã¹ãããããšãå¿ãããŠãã ãã+ãªãè²¢ç®è ããããè©ŠããŠã¿ãããšãã§ããã®ã§ããïŒ
ããã«ããã Next.jsã§ã®ãã¯ãµã¹ã®äœ¿çšã
ç§ã䜿çšããŠããåé¿çïŒ
# next.config.js module.exports = { serverRuntimeConfig: { PROJECT_ROOT: __dirname } }
ãããŠããªãããã¹ãå¿ èŠãšããå Žæã§
import fs from 'fs' import path from 'path' import getConfig from 'next/config' const { serverRuntimeConfig } = getConfig() fs.readFile(path.join(serverRuntimeConfig.PROJECT_ROOT, './path/to/file.json'))
ããã§ã¯ãçŸåšã®ãã¡ã€ã«ããã®çžå¯Ÿãã¹ã§ãã¡ã€ã«ãåç §ããå¿ èŠããªãããšã¯ããã£ãŠããŸãããéåžžã«é¢é£ãããŠãŒã¹ã±ãŒã¹ïŒ
/public/images
ãã©ã«ããŒããç»åãã¡ã€ã«ãèªã¿åãïŒã¯è§£æ±ºããŸãã
çŽ æŽãããç·ã ç§ã®ããã«åããã
ç§ã¯ããã«æ°ããgetStaticProps
ã¡ãœããã䜿çšããŠããŸãïŒïŒ9524ïŒã ãã®ã¡ãœããã¯çŸåšäžå®å®ã§ãããšããŒã¯ãããŠããŸãããæ£åŒã«åºè·ããããšã«é¢ããŠNext.jsããŒã ããã®è¯ããµããŒããããããã§ãã
äŸãã°ïŒ
export async function unstable_getStaticProps() {
const siteData = await import("../data/pages/siteData.json");
const home = await import("../data/pages/home.json");
return {
props: { siteData, home }
};
}
@ ScottSmith95ããã䜿çšããŠãããããªãã¯ãœãŒã¹ãããžã§ã¯ãã¯ãããŸããïŒ ãããã©ã®ããã«èŠãããã«ã€ããŠèå³ããããŸãã
ãã®ãããžã§ã¯ãã¯ãŸã ãªãŒãã³ãœãŒã¹ã§ã¯ãããŸããããããã«è³ªåãããã°ãç§ã®èšå®ããã£ãšå ±æã§ããŠããããã§ãã
@ ScottSmith95ç§ã¯
src
å€åŽ/å
åŽïŒïŒ@Svishãããžã§ã¯ãå ã®/ dataã«ããŒã¿ãã¡ã€ã«ãä¿åããŸãã ïŒããŒãžã¯/ src / pragesã§ã¯ãªã/ pagesã«ãããŸããïŒãã®ããŒãžã³ã³ããŒãã³ãã¯æ¬¡ã®ããã«ãªããŸãïŒå°éå ·ã¯ããã©ã«ãã®ãšã¯ã¹ããŒãã§ããHomeã³ã³ããŒãã³ãã«éä¿¡ãããŸãïŒïŒ
// /pages/index.js
const Home = ({ siteData, home }) => {
return (
<>
<Head>
<meta name="description" content={siteData.siteDescription} />
<meta name="og:description" content={siteData.siteDescription} />
<meta
name="og:image"
content={getAbsoluteUrl(siteData.siteImage, constants.siteMeta.url)}
/>
</Head>
<section className={`container--fluid ${styles.hero}`}>
<SectionHeader section={home.hero} heading="1">
<div className="col-xs-12">
<PrimaryLink
href={home.hero.action.path}
className={styles.heroAction}
>
{home.hero.action.text}
</PrimaryLink>
</div>
</SectionHeader>
<div className={styles.imageGradientOverlay}>
<img src={home.hero.image.src} alt={home.hero.image.alt} />
</div>
</section>
</>
);
};
ããé«åºŠãªããŒãžãã€ãŸãåçã«ãŒããæã€ããŒãžã®å Žåã次ã®ããã«ãã®ããŒã¿ãååŸããŸãã
// /pages/studio/[member.js]
export async function unstable_getStaticProps({ params }) {
const siteData = await import("../../data/pages/siteData.json");
const member = await import(`../../data/team/${params.member}.json`);
return {
props: { siteData, member }
};
}
å±éã¯éåžžã«ã¹ã ãŒãºã«é²ã¿ãåçã«ãŒãã§ã¯getStaticPaths()
ãå¿
èŠã«ãªããŸãã ãã®ããã¥ã¡ã³ãã«ã€ããŠã¯RFCã確èªããããšããå§ãããŸãããããŒã ã¡ã³ããŒã®ããŒã¿ããã¹ãŠåéããŠNext.jsã«æž¡ãããšã§
// /pages/studio/[member.js]
export async function unstable_getStaticPaths() {
const getSingleFileJson = async path => await import(`../../${path}`);
// These utility functions come from `@asmallstudio/tinyutil` https://github.com/asmallstudio/tinyutil
const directoryData = await getDirectory(
"./data/team",
".json",
getSingleFileJson,
createSlugFromTitle
);
const directoryPaths = directoryData.reduce((pathsAccumulator, page) => {
pathsAccumulator.push({
params: {
member: page.slug
}
});
return pathsAccumulator;
}, []);
return directoryPaths;
}
@ ScottSmith95ææã«èŠããŸãïŒ æéãããã°ãããã€ãã®ãã©ããŒã¢ããã®è³ªåïŒ
next export
ã䜿çšããå ŽågetStaticPaths
ããã¹ãã©ã¡ãŒã¿ã®ãªã¹ããè¿ãããããïŒæ¬¡ã«ïŒã¬ã³ããªã³ã°ããšã«getStaticProps
ã«1ã€ãã€ãã£ãŒããããããšãæ£ããç解ããŸãããïŒgetStaticProps
ãªãgetStaticPaths
ãã©ã¡ãŒã¿ãæå®ããã«ããŒãžã®äŸããïŒ_app
getStaticProps
ã䜿çšã§ããŸããïŒ ããšãã°ãããŒãããããµã€ãå
šäœã®èšå®ãªã©ãããå Žåã¯ã©ãã§ãããããAPIã¯ã©ãã§ããïŒ ãããã®ããã¯ã¯ããŒãžçšã§ãããAPIã¯ã©ãã§ããïŒ
ããããããŸããã 次ã®èšå®ã§_dirnameãenvå€æ°ãšããŠèšå®ããããšãã§ããŸããã ãããã£ãŠãAPIãããã¡ã€ã«ã·ã¹ãã ã«ã¢ã¯ã»ã¹ã§ããŸããããããŒã«ã«ã§ããæ©èœããŸããã§ããã ä»ãŸã§å±éãããšããããšã©ãŒãçºçããŸããã å±éåŸã«æ©èœããªãçç±ã¯ãããŸããïŒ
@ josias-räž»ãªåé¡ã¯éåžžãèªã¿åããããã¡ã€ã«ããããã€ã¡ã³ãã«å«ãŸããŠããªãããšã§ããããã¡ã€ã«ãå«ããæ¹æ³ãšãã¡ã€ã«ã®çš®é¡ïŒ js
/ json
ã«ãã£ãŠç°ãªããŸããéåžžã¯åé¡ãããŸãããã .jade
ãããªä»ã®ãã¡ã€ã«ã¿ã€ãã§ã¯ããããã®ãã¡ã€ã«ã®èªã¿åã/åŠçã«åå¥ã®@now/node
ã©ã ã/ãããã€ã¡ã³ãã䜿çšãããªã©ã圌ãåŠçããå¥ã®æ¹æ³ãå¿
èŠã«ãªããŸãã
ãšã©ãŒã«ã€ããŠãã£ãšèª¬æã§ããã°ã誰ããããªããå©ããŠããããããããŸããã
@BrunoBernardinoå®éã«ã¯srcãã©ã«ããŒå
ã®JSONãã¡ã€ã«ãåç
§ããŠããŸããã ããããå®éã«ã¯ããã§ã«å±éã«å€±æããŠããã®ã¯fs.readdirSync(my_dirname_env_var)
ã¡ãœããã§ãããããŸãã ãã®ããããããã€ã¡ã³ãåŸã«dirã¯ãŸã£ããååšããªãããã«èŠããŸãã APIã䜿çšããŠjsonãžã®ãã«ãã¹ã«ã¢ã¯ã»ã¹ããããšãããšã次ã®ããã«ãªããŸãã
ERROR Error: ENOENT: no such file or directory, open '/zeit/3fc37db3/src/content/somejsonfilethatexists.json'
ãããŠãç§ãè¿°ã¹ãããã«ãããã¯ã npm start
ããã«ãããŠå®è¡ãããšãããŒã«ã«ã§æ©èœããŸãã
@ josias-rããããšãïŒ ä»£ããã«ïŒãããã€ã¡ã³ãããããã°ããããã«ïŒçžå¯Ÿãã¹ïŒå€æ°ãªãïŒã䜿çšããŠfs.readdirSync
ãå®è¡ããããšããŸãããïŒ ç§ã¯éåžžã¯æ©èœããããšãçºèŠããŸããããããããªããåæåããã»ã¹ïŒ getInitialProps
ãªã©ïŒã®ã©ããã«ãã®ã³ãŒããæžãããšãã§ããŸãïŒãã¡ã€ã«ãèªã¿åãã ãã§ãã©ãã«ãä¿åããŸããïŒããããã€ã¡ã³ãããã»ã¹ã¯ããã®ãã¡ã€ã«ãå¿
èŠã§ããããšãèªèããå®éã®ã³ãŒã/ããžãã¯ã®å€æ°ã䜿çšããŠãããèªã¿åãç¶ããŸãã ãã¡ããšãããã®ã§ã¯ãããŸããããããããµããŒãããããŸã§æ©èœããŸãã __dirname
ã䜿çšã§ããå ŽåããããšæããŸãã
@BrunoBernardinoã«ãŒãçžå¯Ÿãã¹./
ããå§ãŸããã¡ã€ã«ããªãŒãæ§ç¯ããããšãã§ããŸããã ç§ãåŸãã®ã¯æ¬¡ã®JSONã§ããïŒããŒãã¢ãžã¥ãŒã«ã¯ãªã¹ããããŠããŸããïŒïŒ
{
"path": "./",
"name": ".",
"type": "folder",
"children": [
{
"path": ".//.next",
"name": ".next",
"type": "folder",
"children": [
{
"path": ".//.next/serverless",
"name": "serverless",
"type": "folder",
"children": [
{
"path": ".//.next/serverless/pages",
"name": "pages",
"type": "folder",
"children": [
{
"path": ".//.next/serverless/pages/api",
"name": "api",
"type": "folder",
"children": [
{
"path": ".//.next/serverless/pages/api/posts",
"name": "posts",
"type": "folder",
"children": [
{
"path": ".//.next/serverless/pages/api/posts/[...id].js",
"name": "[...id].js",
"type": "file"
}
]
}
]
}
]
}
]
}
]
},
{
"path": ".//node_modules",
"name": "node_modules",
"type": "folder",
"children": ["alot of children here ofc"]
},
{ "path": ".//now__bridge.js", "name": "now__bridge.js", "type": "file" },
{
"path": ".//now__launcher.js",
"name": "now__launcher.js",
"type": "file"
}
]
}
JSONãã¡ã€ã«ãããã«ãªãããã§ãããäžèšã§ææ¡ãããããªã³ãŒããä»ããŠãããå«ããããšããŸãããïŒ äž»ãªåé¡ã¯ããããã€ã¡ã³ããå®è¡ããæé©åãåžžã«åçãã¹ãååŸãããšã¯éããªãããšã§ãããã®ãããéçãã¹ã匷å¶ããããšã¯ãéå»ã«ç§ã«ãšã£ãŠã¯ããŸããããŸããïŒå¿ ãããå®éã«å®è¡ãããŠããã³ãŒãã§ã¯ãªããé¢é£ãããã¡ã€ã«ã確èªããããã§ãïŒãå«ãŸããŠããŸãïŒã ããã¯çã«ããªã£ãŠããŸããïŒ
@BrunoBernardinoéAPIãœãªã¥ãŒã·ã§ã³ã«åãæ¿ããŸããã ãã©ã«ããŒãããã¡ã€ã«ãåçã«èŠæ±ãããã®ã§ããããã®ãã¡ã€ã«ã®ã³ã³ãã³ãã®ã¿ãå¿
èŠãªã®ã§ã import()
ã¡ãœããã䜿çšã§ããŸãã ããããŒã«èŠããã®ã§ãç§ã¯ãã®æ¹æ³ã§ããããããããããŸããã§ããããããã¯åºæ¬çã«ç§ã®APIãšã³ããã€ã³ããè¡ã£ãã®ãšåãããšãè¡ã£ãŠããŸãã
...ãã¡ã€ã«ãéçãã©ã«ããŒã«å
¥ããããšããŸãããããããæ©èœããŸããã§ããã ããããå°æ¥çã«ã¯ãã¡ã€ã«ã·ã¹ãã ãžã®ã¢ã¯ã»ã¹ãå¯èœã«ãªãããšãé¡ã£ãŠããŸãã
ç§ãããããŒãªãœãªã¥ãŒã·ã§ã³ã«é ŒããããåŸãŸããã§ãããããããããã«å®çŸãããããã®ãŠãŒã¹ã±ãŒã¹ããæåŸ ã©ãããã«ãµããŒããããããã«ãªããšãããå€ãã®äººã ãNextãæ¬çªç°å¢ã«å¯Ÿå¿ããŠãããšèŠãªãå§ããããšãé¡ã£ãŠããŸãã
ç§ã䜿çšããŠããåé¿çïŒ
# next.config.js module.exports = { serverRuntimeConfig: { PROJECT_ROOT: __dirname } }
ãããŠããªãããã¹ãå¿ èŠãšããå Žæã§
import fs from 'fs' import path from 'path' import getConfig from 'next/config' const { serverRuntimeConfig } = getConfig() fs.readFile(path.join(serverRuntimeConfig.PROJECT_ROOT, './path/to/file.json'))
ããã§ã¯ãçŸåšã®ãã¡ã€ã«ããã®çžå¯Ÿãã¹ã§ãã¡ã€ã«ãåç §ããå¿ èŠããªãããšã¯ããã£ãŠããŸãããéåžžã«é¢é£ãããŠãŒã¹ã±ãŒã¹ïŒ
/public/images
ãã©ã«ããŒããç»åãã¡ã€ã«ãèªã¿åãïŒã¯è§£æ±ºããŸããçŽ æŽãããç·ã ç§ã®ããã«åããã
now
ã«ãããã€ãããšæ©èœããªãããã§ãããããŒã«ã«éçºã§ã¯å®å
šã«æ©èœããŸãã
ENOENT: no such file or directory, open '/zeit/41c233e5/public/images/my-image.png'
at Object.openSync (fs.js:440:3)
at Object.readFileSync (fs.js:342:35)
at getEmailImage (/var/task/.next/serverless/pages/api/contact/demo.js:123:52)
at module.exports.7gUS.__webpack_exports__.default (/var/task/.next/serverless/pages/api/contact/demo.js:419:87)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async apiResolver (/var/task/node_modules/next/dist/next-server/server/api-utils.js:42:9) {
errno: -2,
syscall: 'open',
code: 'ENOENT',
path: '/zeit/41c233e5/public/images/my-image.png'
}
ãããªãã¯ãã©ã«ããŒãã«ãŒãã«ç§»åãããããšãç解ããŠããã®ã§ãæ¬çªç°å¢ã§ããŒã¹ãã©ã«ããŒã匷å¶çã«æ€çŽ¢ããããšããŸããããããã§ãåãçµæãåŸãããŸããã
ENOENT: no such file or directory, open '/zeit/5fed13e9/images/my-image.png'
at Object.openSync (fs.js:440:3)
at Object.readFileSync (fs.js:342:35)
at getEmailImage (/var/task/.next/serverless/pages/api/contact/demo.js:124:52)
at module.exports.7gUS.__webpack_exports__.default (/var/task/.next/serverless/pages/api/contact/demo.js:331:87)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async apiResolver (/var/task/node_modules/next/dist/next-server/server/api-utils.js:42:9) {
errno: -2,
syscall: 'open',
code: 'ENOENT',
path: '/zeit/5fed13e9/images/my-image.png'
}
@PaulPCIOã§çºçããŠããåé¡ã¯ã .json
ã .js
ããŸãã¯.ts
ãã¡ã€ã«ã§ã¯ãªãããã§ãã /public
äžã®ãã¡ã€ã«ã¯CDNã«ããããã€ããããŸãããã©ã ãïŒAFAIKïŒã«ã¯ããããã€ããããªãããããã®å Žåã¯ã includeFiles
䜿çšããå°çšã®ã©ã ãïŒ @now/node
ïŒãããã€ã¡ã³ããå¿
èŠã§ãã includeFiles
ããŸãã¯ããã®åäžã®ãã¡ã€ã«ã®ã¿ãå¿
èŠãªå Žåã¯ããããbase64
ã«å€æãããããå€æ°ãšããŠäœ¿çšããŸãïŒå°çšãã¡ã€ã«å
ãã©ããã«é¢ä¿ãªãïŒã
æåŸ
ããŠãã@BrunoBernardinoã«æè¬ããŸãã base64
ã¡ãœããã䜿çšããŸã
ãããã€ãããç°å¢ã§ã®__dirnameã«å¯Ÿãã解決çã¯ãããŸããïŒ
@NicolasHz詳ãã説æããŠããã ããŸããïŒ ç§ã¯ããªãã®è³ªåãå®å šã«ã¯ç解ããŠããŸããã§ããã
@BrunoBernardinoç§ã®ãã®ãå«ãæåŸã®ã³ã¡ã³ããèŠããšãã次ã®æ§æã®ããã_dirname
ãããã¯ã¯ãããã€ã¡ã³ãã§ã¯æ©èœããªããšç¢ºä¿¡ããŠããŸãã jsãã¡ã€ã«ãJSONãã¡ã€ã«ããããŸãã å°ãªããšãnow
ãããã€ã¡ã³ãã®å Žåãããããã«ã¹ã¿ã ãããã€ã¡ã³ãã«ã¯ã«ãŠã³ããããŸããã
@BrunoBernardinoãããã€ãããç°å¢ã®ããŒã«ã«ãã¹ã«ãã€ã³ãã£ã³ã°ããããã€ãã®å€æ°ã䜿çšã§ããŸããã __dirnameãããã€ãããšæªå®çŸ©ã«ãªããAPIã¹ã¯ãªãããããã¡ã€ã«ãèªã¿åãããšãã§ããŸããã
@NicolasHzãæã«
確èªããã ãã§ãconfig.jsã¯ãããã€ã¡ã³ãã§æ©èœããŠããŸããã
ç§ã䜿çšããŠããåé¿çïŒ
# next.config.js
module.exports = {
env: {
PROJECT_DIRNAME: __dirname,
},
}
ãã¹ãå¿ èŠãªAPIå®çŸ©ïŒallPostsãã©ã«ããŒã«ã¯ããŒã¯ããŠã³åœ¢åŒã®ãã¹ãŠã®ããã°ãå«ãŸãããããžã§ã¯ãã«ãŒãã«ãããŸãïŒ
import fs from 'fs'
import { join } from 'path'
const postsDirectory = join(process.env.PROJECT_DIRNAME, 'allPosts')
ããã¯å°å
ã®éçºã«å®å
šã«åãçµãã§ããŸãã
ããããçŸåšzeitã«ãããã€ãããšããã®ãšã©ãŒãçºçããŸãã
[POST] /api/postsApi
11:00:13:67
Status:
500
Duration:
8.1ms
Memory Used:
76 MB
ID:
kxq8t-1585546213659-5c3393750f30
User Agent:
axios/0.19.2
{
fields: [ 'title', 'date', 'slug', 'author', 'coverImage', 'excerpt' ],
page: 1
}
2020-03-30T05:30:13.688Z 572075eb-4a7a-47de-be16-072a9f7005f7 ERROR Error: ENOENT: no such file or directory, scandir '/zeit/1cc63678/allPosts'
at Object.readdirSync (fs.js:871:3)
at getPostSlugs (/var/task/.next/serverless/pages/api/postsApi.js:306:52)
at module.exports.fZHd.__webpack_exports__.default (/var/task/.next/serverless/pages/api/postsApi.js:253:86)
at apiResolver (/var/task/node_modules/next/dist/next-server/server/api-utils.js:48:15)
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
errno: -2,
syscall: 'scandir',
code: 'ENOENT',
path: '/zeit/1cc63678/allPosts'
}
@BrunoQuaresmaã®ãããª@sjcodebookã«ãããšããã®åé¿çã¯ããŒã«ã«ã§ã®ã¿æ©èœããŸãã ã©ã ãããã¡ã€ã«ã·ã¹ãã ã«ã¢ã¯ã»ã¹ããã¢ããªèªäœããã®ãªã¯ãšã¹ããä»ããŠãã®ãã¡ã€ã«ãåŒã³åºãããã«ããŸã å¥ã®@now/node
ãããã€ã¡ã³ãã䜿çšããŠããŸãïŒãŸãã¯ãããã€ããåã«å¿
èŠãªéççµæãçæããŸãïŒã ã¡ãã£ãšæ£æ°ãããªããã©ãããŸãããã
ããã«ã¡ã¯@BrunoBernardino ...ã«ã¹ã¿ã ããŒããµãŒããŒãåããå¥ã®ãããžã§ã¯ããæå³ããŸããïŒ
ãã ããã includeFiles ãèšå®ãããã®ã«ã¢ã¯ã»ã¹ã§ããªãã®ã«ããªããããã«ã¢ã¯ã»ã¹ã§ããªãã®ãããããŸããð€
@valseåããããžã§ã¯ãã«now.json
ã¹ããããã§ãïŒ
{
"builds": [
{
"src": "next.config.js",
"use": "@now/next"
},
{
"src": "lambdas/**/*.ts",
"use": "@now/node",
"config": {
"includeFiles": ["email-templates/**"]
}
}
],
"routes": [
{
"src": "/lambdas/(.+)",
"dest": "/lambdas/$1.ts"
}
]
}
ããããã°ã次ã®ãããªæ¹æ³ã§ããããåŒã³åºãããšãã§ããŸãã
await ky.post(`${hostUrl}/lambdas/email?token=${someToken}`);
次ã®APIããŒãžå
ãããã¡ãŒã«ã®éä¿¡ãšpug
ãªã©ã®ãã³ãã¬ãŒããã¡ã€ã«ããã®èªã¿åããåŠçããlambdas/email.ts
ãã¡ã€ã«ããããšä»®å®ããŸãã
ã圹ã«ç«ãŠã°å¹žãã§ãã
ãŸãããincludeFilesãã¯@now/node
ã®ã¿æ©èœããŸãïŒããããä»ã®äººã§ããã @now/next
ã§ã¯æ©èœããŸããïŒ
@BrunoBernardinoã¯ã node
é¢æ°ã䜿çšããŠããå ŽåãESMãèªã¿åããªãããã«èŠããŸãã
ããã¯ãmdxããŒãžã®ãªã¹ããã€ã³ããŒãããããšãããšã©ããªããŸããã
ã³ãŒã
import { NextApiRequest, NextApiResponse } from 'next'
import { promises as fs } from 'fs'
import { join } from 'path'
const { readdir } = fs
export default async (req: NextApiRequest, res: NextApiResponse) => {
const postFiles = await readdir(join(process.cwd(), 'pages', 'blog'))
const postNames: string[] = postFiles.filter((page: string) => page !== 'index.tsx')
const posts = []
for (const post of postNames) {
const mod = await import(`../pages/blog/${post}`)
posts.push({ ...mod, link: post.slice(0, post.indexOf('.')) })
}
res.status(200).json([])
}
ç§ãåŸããšã©ãŒïŒ
export const title = 'My new website!'
^^^^^^
SyntaxError: Unexpected token 'export'
@talentlessguyç§ã¯Zeit / VercelããŒã ã«æå±ããŠãããããã 幞ããªé¡§å®¢ã§ãã ãã®ã¹ããããããããã€ãã®æœåšçãªåé¡ãèŠãããã®ã§ããã®ãããªãã®ã¯åœŒãã®ã«ã¹ã¿ããŒãµããŒãã«ããé©ããŠããããã§ãïŒ
process.cwd()
代ããã«ãäœã䜿çšããªããã __dirname
ã䜿çšããããšããå§ãããŸãã ç§ã¯åŸè
ãã©ã ãã§äœ¿çšããŠããŸããããä»ã®ãã®ã䜿çšããŠããã®ã§ããããåé¡ã§ãããã©ããã¯ããããŸããNextApiRequest
ãšNextApiResponse
ãã¿ã€ããšããŠã€ã³ããŒãããŠããŸãããããã¯@now/node"
ããå®è¡ããå¿
èŠããããŸãã ãããã£ãŠãã¿ã€ãã¯æ¬¡ã®ããã«ã€ã³ããŒãããå¿
èŠããããŸããimport { NowRequest, NowResponse } from '@now/node';
pages/...
ããã€ã³ããŒã/èªã¿åããè¡ã£ãŠããŸããã includeFiles
ä»ããŠããããå«ããŠããŸããïŒ ããªãã®now.json
ã©ã®ããã«èŠããŸããïŒ@BrunoBernardino
__dirname
ã¯åžžã«/
ã§ããããã䜿çšã§ããŸããã代ããã«process.cwd()
ãå®éã®ãã¹ã瀺ããŸãã
ç§ã¯urã®ä¿®æ£ãåãå ¥ããããã¯æ©èœããŸããïŒ
lambdas / posts.ts
import { NowResponse, NowRequest } from '@now/node'
import { promises as fs } from 'fs'
import { join } from 'path'
const { readdir } = fs
export default async (req: NowRequest, res: NowResponse) => {
const postFiles = await readdir(join(process.cwd(), 'pages', 'blog'))
const postNames: string[] = postFiles.filter((page: string) => page !== 'index.tsx')
const posts = []
for (const post of postNames) {
const mod = await import(`../pages/blog/${post}`)
posts.push({ ...mod, link: post.slice(0, post.indexOf('.')) })
}
res.status(200).json([])
}
now.json
{
"builds": [
{
"src": "next.config.js",
"use": "@now/next"
},
{
"src": "lambdas/**/*.ts",
"use": "@now/node",
"config": {
"includeFiles": ["pages/blog/*.mdx"]
}
}
],
"routes": [
{
"src": "/lambdas/(.+)",
"dest": "/lambdas/$1.ts"
}
]
}
ç§ãåŸããšã©ãŒïŒ
import Meta from '../../components/Article/Meta.tsx'
^^^^^^
SyntaxError: Cannot use import statement outside a module
typescriptããŒãé¢æ°ã¯.mdx
ãã¢ãžã¥ãŒã«ãšããŠæ±ãããšãã§ããªãããã§ã:(
äºè§£ããŸãããåé¡ãèŠã€ãã£ãããã§ãã çŽæ¥ã€ã³ããŒãããã®ã§ã¯ãªãããã¡ã€ã«ã®å 容ãèªã¿åã£ãŠè§£æããŠã¿ãŠãã ããã ç§ã¯ãã®ãããªã€ã³ããŒããèŠãããšããããŸããããããŠããã¯ããã€ãã®ããã«ã®éæ³ã§ã®ã¿æ©èœãããã®ã®ããã§ããããã¯ããªããæ®éã®TSã®ä»£ããã«äœ¿ãããšãæè¿ããŸãã
@BrunoBernardinoããªãã¯æ£ããã§ãããããã¯æçœãªtsã§ã¯ãããŸãã...ç§ã¯esnextã«ã¿ãŒã²ãããèšå®ããesnextã«ãã¢ãžã¥ãŒã«ãèšå®ããŠããŸããããã¯ãã¹ãŠãã€ã³ããŒãã§ããã¯ãã§ã...ãããã©ããããããããã¯ããŸãã
ãšã«ããããã¯åé¡ãšã¯é¢ä¿ãããŸãããã©ããã§ã°ã°ãã€ããã§ã
å¿é
ãªãã ããã€ãã®ãã³ããhttps://mdxjs.com/advanced/typescriptãšhttps://mdxjs.com/getting-started/webpackã«ããå¯èœæ§ãããããã @now/node
ãããã€ã¡ã³ãã埮調æŽããå¿
èŠããããŸããããã䜿ã£ãŠã ãšã«ããã圌ãã®ãµããŒãã¯å©ãã«ãªãã¯ãã§ãã
ããã«é¢ããåãã¯ãããŸããïŒ APIã«ãŒãã§äœ¿çšããããã®htmlã¡ãŒã«ãã³ãã¬ãŒããå«ããããšãã§ããã°çŽ æŽããããšæããŸãã çŸåšãç§ã¯ããããJSãã¡ã€ã«ã«å«ããŠããŸãããç§ã¯ãã®ããã¯ã®ç¹å®ã®ãã¡ã³ã§ã¯ãããŸããã
ãã1ã€ã®ããã¯ã¯ãwebpackraw-loaderã䜿çšããŠããããjsã«åã蟌ãããšã§ãã
yarn add --dev raw-loader
const templates = {
verify: require("raw-loader!../template/email/verify.hbs").default,
};
次ã«ã templates.verify
ãæååãšããŠäœ¿çšããŸãã
next-i18nextã§çºçããŠããåé¡ããããããã«é¢é£ããŠããããã§ãïŒ vercel / vercelïŒ4271 ïŒã åºæ¬çã«now
å
¥ããŠããŸãã.json
å
ã«ãããã¡ã€ã«/public/static/locales/
ãµãŒããŒã¬ã¹æ©èœã«ã ããã§èª¬æããæ©èœã次ã«è¿œå ããããŸã§ã誰ããåé¿çãæäŸã§ããŸããïŒ
@borispoehlandäžããã€ã³ããŒã/å¿ èŠãªåé¿çãè©ŠããŸãããïŒ ããã¯ããŸãããã¯ãã§ãã
@borispoehlandäžããã€ã³ããŒã/å¿ èŠãªåé¿çãè©ŠããŸãããïŒ ããã¯ããŸãããã¯ãã§ãã
@BrunoBernardinoæ£ç¢ºãªã³ã¡ã³ãã®æå³ãããããŸããã
public/static/locales
å
ã®ãã¹ãŠã®.json
ãã¡ã€ã«ããµãŒããŒã¬ã¹é¢æ°ã«ã€ã³ããŒãããäŸãæããŠãã ããã ãããŠãããã
ç§ã¯æ¬¡ã«äœ¿çšããŠããŸãïŒåã«è¿°ã¹ãããã«ã includeFiles
ã¯@now/next
ãšäºææ§ããããŸããããããç§ã®åé¡ã«åœ±é¿ãäžããå Žåã¯idkïŒã
ããã«ã next-i18next
ã¯ç§ã«ãšã£ãŠäžçš®ã®ãã©ãã¯ããã¯ã¹ã§ããããïŒãããã£ãŠããããããã¡ã€ã«ãã€ã³ããŒãããããªãïŒã next-i18next
ãçŽæ¥ã€ã³ããŒãã§ããããã«ãã¡ã€ã«ãå®å
šã«ã€ã³ããŒãããæ¹æ³ãæ¢ããŠããŸããã¢ã¯ã»ã¹ããŠïŒäžèšã®ä»ã®ã³ã¡ã³ãã§ãæã«ã¯å¯äžã®PROJECT_DIRNAME
å
éšã§å®çŸ©ãããnext.config.json
ãšã€ã³ããŒããæåã§è¡ããªããã°ãªããªãã£ããããã¯ç§ãå°éããããšãããã®ã§ã¯ãããŸããïŒã vercel / vercelïŒ4271ã®ããã«ã now
.json
ãã¡ã€ã«ããµãŒããŒã¬ã¹é¢æ°ã«åã蟌ãå¿
èŠããããŸãã
pages/api
å
ã®_any_ãã¡ã€ã«å
ã®httpsïŒ //github.com/vercel/next.js/issues/8251#issuecomment-544008976ã®ããã«å®è¡ã
ã€ã³ããŒãã§ã¯äœãããå¿ èŠã¯ãããŸããã éèŠãªã®ã¯ãwebpack vercelãå®è¡ãããšããããã®ãã¡ã€ã«ãå«ããå¿ èŠãããããšãããããæ©èœããã¯ãã§ãã
ãããçã«ããªã£ãŠããããšãé¡ã£ãŠããŸãã
pages/api
å ã®_any_ãã¡ã€ã«å ã®ïŒ8251ïŒã³ã¡ã³ãïŒã®ãããªããšãè¡ããŸãã€ã³ããŒãã§ã¯äœãããå¿ èŠã¯ãããŸããã éèŠãªã®ã¯ãwebpack vercelãå®è¡ãããšããããã®ãã¡ã€ã«ãå«ããå¿ èŠãããããšãããããæ©èœããã¯ãã§ãã
ãããçã«ããªã£ãŠããããšãé¡ã£ãŠããŸãã
@BrunoBernardinoãã®ã¢ãããŒãã®åé¡ã¯ãjsonãã¡ã€ã«ãããããããããšã§ãã ãã¹ãŠã®ãã¡ã€ã«ã«å¯ŸããŠæåã§ã€ã³ããŒããè¡ãã®ã¯ãã¡ãã£ãšé¢åã§ãã now
ãäŒããç°¡åãªæ¹æ³ã¯ãããŸããïŒãããããã®ãã£ã¬ã¯ããªå
ã®ãã¹ãŠã®jsonãã¡ã€ã«ãååž°çã«ååŸããŠãã ãããïŒ åãã£ãŠæè¬ããŸã
ç·šéïŒ json
ãã¡ã€ã«ãæåã§ã€ã³ããŒãããŠãã以åãšåããšã©ãŒãçºçããŸãã ç§ã¯ããã®ããã«æ°ããåé¡ãéãã€ããã§ããç§ã¯æšæž¬ããŸã
誰ããè°è«ã«åå ããããšã«èå³ãããå Žåã«åããŠãç§ã¯èªåã®åé¡ã«ã€ããŠæ°ããåé¡ã@ BrunoBernardino ïŒ
__dirname
ãéåžžã®åäœãšåãããã«äœ¿çšã§ããããã«ããããã®å¥ã®ãªãã·ã§ã³/åé¿çã¯ãwebpackæ§æã調æŽããããšã§ãã
ããã©ã«ãã§ã¯ãwebpackã¯ã次ã®ããã«æ瀺ããªãéããããŸããŸãªããŒãã°ããŒãã«ãããªãã£ã«ã§ãšã€ãªã¢ã¹ããŸãã
https://webpack.js.org/configuration/node/
ãŸããwebpackã®ããã©ã«ãèšå®ã§ã¯ã __dirname
ãš__filename
ã¯ãã®ãŸãŸã«ããŠãããŸããã€ãŸããããããããªãã£ã«ãããããŒãã«éåžžã©ããåŠçãããŸãã
ãã ããNext.js webpackæ§æã¯ãwebpackã®ããã©ã«ãã䜿çš/åæ ããŸããhttps://github.com/vercel/next.js/blob/bb6ae2648ddfb65a810edf6ff90a86201d52320c/packages/next/build/webpack-config.ts#L661 -L663
ããã¯èšã£ãŠããç§ã¯ä»¥äžã®ã«ã¹ã¿ã Nextconfigãã©ã°ã€ã³ã䜿çšããŠwebpackæ§æã調æŽããŸããã
éèŠïŒããã¯ç§ã®ãŠãŒã¹ã±ãŒã¹ã§æ©èœããŸãã å¹ åºãç°å¢/æ§æã§ãã¹ããããŠããããNext.jsãŠããã/çµ±åãã¹ãã®ãã¹ãŠã«å¯ŸããŠãã¹ããããŠããŸããã ããã䜿çšãããšãç°å¢ã«æå³ããªãå¯äœçšãçºçããå¯èœæ§ããããŸãã
ãŸããNextã«ã¯ã__dirname
ãš__filename
ã®webpackã®ããã©ã«ãèšå®ã䜿çšããªãç¹å®ã®çç±ãããå ŽåããããŸãã ç¹°ãè¿ãã«ãªããŸããã以äžã®ã³ãŒãã«ã¯æå³ããªãå¯äœçšãããå¯èœæ§ãããããã泚æããŠäœ¿çšããå¿ èŠããããŸãã
ãŸãã以äžã®ãã©ã°ã€ã³ã¯next-compose-plugins
ããã±ãŒãžã§äœ¿çšããããã«èšèšãããŠããŸãïŒ https ïŒ
ãã ããéåžžã®ãã©ã°ã€ã³ãšããŠãæ©èœããã¯ãã§ãïŒ https ïŒ
const withCustomWebpack = (nextCfg) => {
return Object.assign({}, nextCfg, {
webpack(webpackConfig, options) {
// We only want to change the `server` webpack config.
if (options.isServer) {
// set `__dirname: false` and/or `__filename: false` here to align with webpack defaults:
// https://webpack.js.org/configuration/node/
Object.assign(webpackConfig.node, { __dirname: false });
}
if (typeof nextCfg.webpack === 'function') {
return nextCfg.webpack(webpackConfig, options);
}
return webpackConfig;
},
});
};
@jkjustjoshingã«ãã£ãŠãœãªã¥ãŒã·ã§ã³ãå®è£ ããŸãããããŒã«ã«ã§ã¯ããŸãæ©èœããŸãããã¢ããªãVercelã«ãããã€ãããšæ©èœããŸããã
次ã®ãšã©ãŒãçºçããŸãã
Error: GraphQL error: ENOENT: no such file or directory, open '/vercel/37166432/public/ts-data.csv'
ç§ã®ã³ãŒãïŒ
const content = await fs.readFile(
path.join(serverRuntimeConfig.PROJECT_ROOT, "./public/ts-data.csv")
);
ãã¡ã€ã«ãžã®ãªã³ã¯ã¯æ¬¡ã®ãšããã§ãïŒ https ïŒ
@bengrunfeldã¯ãããœãªã¥ãŒã·ã§ã³ã¯ããŒã«ã«ã§ã®ã¿æ©èœããŸãã
æè¿åæ§ã®åé¡ãçºçãïŒAPIã«ãŒãã§ãã¡ã€ã«ãèªã¿åãããïŒã解決çã¯äºæ³ãããç°¡åã§ããã
path.resolve('./public/ts-data.csv')
è©Šããã ãã
@borispoehlandã©ããããããšãããããŸããïŒ ããªãã®ãœãªã¥ãŒã·ã§ã³ã¯çŸããæ©èœããŸããïŒ
@bengrunfeldåé¡ãããŸãããå¶ç¶ã«ããããèŠã€ããŸããïŒ @BrunoBernardino ;ïŒïŒã ããã§ã®ã¿ããªã®åé¡ã®è§£æ±ºçã ãšæããŸãã
next.config.js
ãèšå®ããå¿
èŠãããããšã«æ³šæããŠãã ããã @borispoehlandã®ãœãªã¥ãŒã·ã§ã³ãæ©èœããããšã
次ã«ããããäžèšã®@jkjustjoshingã®ãœãªã¥ãŒã·ã§ã³ã«ãªã»ãããã
# next.config.js
module.exports = {
serverRuntimeConfig: {
PROJECT_ROOT: __dirname
}
}
next.config.js
ãèšå®ããå¿ èŠãããããšã«æ³šæããŠãã ããã @borispoehlandã®ãœãªã¥ãŒã·ã§ã³ãæ©èœããããšãäžèšã®@jkjustjoshingã®ãœãªã¥ãŒã·ã§ã³ã«ãªã»ãããã
# next.config.js module.exports = { serverRuntimeConfig: { PROJECT_ROOT: __dirname } }
@bengrunfeldæ¬åœã«ïŒ ç§ã®ãããžã§ã¯ãã§ã¯PROJECT_ROOT
ã¢ãããŒãããªããŠãæ©èœãããããã³ãŒãã®å¥ã®ãã€ã³ãã§ãŸã
Vercelã«ãããã€ããå ŽåãSSGã¢ãŒããšSSR /ãã¬ãã¥ãŒã¢ãŒãã®äž¡æ¹ã§æ©èœããããŒãžã«readFile
ãæžã蟌ãã«ã¯ã©ãããã°ããã§ããïŒ
ãããæ©èœããªãå Žæã®ãã¢ãªããžããªïŒ https ïŒ
@mathdroidã¯ã readFile
ãšreaddir
ãããããgetStaticProps
getStaticPaths
é¢æ°ãš
ãã ãã fs
ã€ã³ããŒã
ãããã©ã®ããã«æ©èœããããæããŠãã ããã
@borispoehlandçŽ æŽããã解決çãããããšãã path.resolve()
ãã/public
ãããŒã«ã«ãšVercelã®äž¡æ¹ã§æ©èœãããšã¯äºæ³ããŠããŸããã§ããïŒeyesïŒïŒ ããªãã¯ãã®æ¥ã®ç§ã®æäžäž»ã§ãã ïŒ+1ïŒ
@borispoehlandãµãŒããŒã¬ã¹é¢æ°å
ã§ãœãªã¥ãŒã·ã§ã³ãè©ŠããŸããããããã§ã次ã®ããã«ãªããŸãã
ENOENTïŒãã®ãããªãã¡ã€ã«ããã£ã¬ã¯ããªã¯ãããŸãããã/ var / task / public /posts.jsonããéããŠãã ããã
const postsFile = resolve('./public/posts.json');
const updateCache = async (posts: IPost[]): Promise<IPost[]> => {
postCache = posts;
fs.writeFileSync(postsFile, JSON.stringify(postCache)); // <====
return postCache;
}
next.config.jsãªãã§è©ŠããŠã¿ãŸãã
module.exports = {
serverRuntimeConfig: {
PROJECT_ROOT: __dirname
}
}
ãã¶ãããªãã®ãœãªã¥ãŒã·ã§ã³ã¯ãµãŒããŒã¬ã¹æ©èœã§ã¯æ©èœããŸãããïŒ
@borispoehlandãµãŒããŒã¬ã¹é¢æ°å ã§ãœãªã¥ãŒã·ã§ã³ãè©ŠããŸããããããã§ã次ã®ããã«ãªããŸãã
ENOENTïŒãã®ãããªãã¡ã€ã«ããã£ã¬ã¯ããªã¯ãããŸãããã/ var / task / public /posts.jsonããéããŠãã ãããconst postsFile = resolve('./public/posts.json'); const updateCache = async (posts: IPost[]): Promise<IPost[]> => { postCache = posts; fs.writeFileSync(postsFile, JSON.stringify(postCache)); // <==== return postCache; }
next.config.jsãªãã§è©ŠããŠã¿ãŸãã
module.exports = { serverRuntimeConfig: { PROJECT_ROOT: __dirname } }
ãã¶ãããªãã®ãœãªã¥ãŒã·ã§ã³ã¯ãµãŒããŒã¬ã¹æ©èœã§ã¯æ©èœããŸãããïŒ
ãªããããããªãã®åŽã§æ©èœããªãã®ãåãããŸãã...ããããªãã
ããããŸããã@ bengrunfeldã³ãŒãã䜿çšããŠèªã¿åãçšã«æ©èœãããŸããããæ®å¿µãªãã次ã®ããã«æžã蟌ãããšã¯ã§ããŸããã
[ãšã©ãŒïŒEROFSïŒèªã¿åãå°çšãã¡ã€ã«ã·ã¹ãã ã '/ var / task / public / posts.json'ãéããŸã]
ãããã£ãŠãããŒã¿ããŒã¹åŒã³åºããå€ãããã®ãé¿ããããã«ãã£ãã·ã¥ãæŽæ°ããæ¹æ³ã¯ãããŸãã:(
@neckarosã¯ãç§ã®ã¢ãããŒãã䜿çšããŠ.json
以å€ã®ãã¡ã€ã«ãããšãã°.jpg
ãã¡ã€ã«ãèªã¿åãããšããŸãããïŒ
ããããŸããã@ bengrunfeldã³ãŒãã䜿çšããŠèªã¿åãçšã«æ©èœãããŸããããæ®å¿µãªãã次ã®ããã«æžã蟌ãããšã¯ã§ããŸããã
[ãšã©ãŒïŒEROFSïŒèªã¿åãå°çšãã¡ã€ã«ã·ã¹ãã ã '/ var / task / public / posts.json'ãéããŸã]
ãããã£ãŠãããŒã¿ããŒã¹åŒã³åºããå€ãããã®ãé¿ããããã«ãã£ãã·ã¥ãæŽæ°ããæ¹æ³ã¯ãããŸãã:(
@neckarosã¯ãS3ïŒãŸãã¯ä»ã®å€éšãã¡ã€ã«ã·ã¹ãã ïŒããã®æžã蟌ã¿ãšèªã¿åããã§ããã¯ãã§ãããç§ã¯éåžžãæ®çºæ§ã®å¯èœæ§ãããè¿ éãªãã£ãã·ã¥ããããã®ã«redisã䜿çšããŸãã https://redislabs.comã¯ãããããµãŒããŒã¬ã¹ãã«ä¿ã¡ãŸããå¿ èŠã«å¿ããŠã httpsïŒ//nextjs-boilerplates.brn.shã«æ¬çªçšã®ã³ãŒãäŸããã
@borispoehlandãµãŒãã¬ã¹é¢æ°ããã®èªã¿åãã¯ã§ããŸããããæžã蟌ã¿ã¯ã§ããŸããã§ããã ããããæ°ããã³ã³ãã³ããè¿œå ããã®ã§ã¯ãªããã€ã³ã¯ãªã¡ã³ã¿ã«ãã«ãïŒåæ€èšŒïŒã§ãã£ãã·ã¥ãæŽæ°ããããšã§æ©èœããããã«ãªããŸããã ããã¯æªããã¿ãŒã³ã§ã¯ãªããšæããŸãã ãååããã ãããããšãããããŸãïŒ
@BrunoBernardinoããããšãç§ã¯èŠãŠ
æ°äººã®ãŠãŒã¶ãŒãããã°å£ããªããå®å šã«ç¡æã®è¶£å³ã®ãœãªã¥ãŒã·ã§ã³ãæ¬åœã«æ¢ããŠããŸã:)
äºè§£ã RedisLabsãšVercelãç§ã®ããã«ãããããŠãããŸããã ð¯
å°ãæãäžããåŸãæ¡åŒµOSããã±ãŒãžã§åäœãããã¡ã€ã«ãäœæããŸãã...
import { tmpdir } from "os";
const doc = new PDFDocument()
const pdfPath = path.join(tmpdir(), `${store.id}${moment().format('YYYYMMDD')}.pdf`)
const writeStream = doc.pipe(fs.createWriteStream(pdfPath)
ãã¡ã€ã«ã®èªã¿åãã¯@subwaymatchãœãªã¥ãŒã·ã§ã³ã§const logoPath = path.resolve('./public/logo.png')
å°ãæãäžããåŸãæ¡åŒµOSããã±ãŒãžã§åäœãããã¡ã€ã«ãäœæããŸãã...
import { tmpdir } from "os"; const doc = new PDFDocument() const pdfPath = path.join(tmpdir(), `${store.id}${moment().format('YYYYMMDD')}.pdf`) const writeStream = doc.pipe(fs.createWriteStream(pdfPath)
ãã¡ã€ã«ã®èªã¿åãã¯@subwaymatchãœãªã¥ãŒã·ã§ã³ã§
const logoPath = path.resolve('./public/logo.png')
ããã§ããããã®ãã¡ã€ã«ã®å 容ãèªã¿è¿ãããšãã§ããŸããïŒ ãã£ã¬ã¯ããªã¯ã¢ã¯ã»ã¹å¯èœã§æ°žç¶çã§ããïŒ
@marklundin tmpdir
ãšããååã®é¢æ°ã§ã¯ããããæ°žç¶çã§ãããšã¯æããŸãããããããæ©èœããå Žåã¯ãå®éã«tmpdir
ãã©ãã»ã©äžæçã§ããããç¥ã£ãŠãããšããã§ããã...ð€
ããã«é¢ããæŽæ°ã¯ãããŸããïŒ ãªãgetInitialPropsã§æ©èœããã®ã«ãAPIã«ãŒãã§ã¯æ©èœããªãã®ãçåã«æã£ãŠããŸãð€·ââïž
ç§ã®çŸåšã®åé¿ç
const data = await import(`../../../../data/de/my-nice-file.json`);
res.json(data.default);
çŸåšãAPIã«ãŒãã§ããã®åé¡ãçºçããŠããŸã
çŸåšãAPIã«ãŒãã§ããã®åé¡ãçºçããŠããŸã
ããã«ã¯ããã€ãã®å®çšçãªè§£æ±ºçããããŸãããå ·äœçã«ã¯ã©ã®ãããªåé¡ããããŸããïŒ
ãã®ã¹ã¬ããããã®ææ¡ããã£ãŠãããããæ©èœãããã®ã«èŠåŽããŠããŸãã ç§ã®ãŠãŒã¹ã±ãŒã¹ã¯ãã¬ã€ããäœæããŠããŠãã³ã³ããŒãã³ãèªäœãšäžç·ã«ã³ã³ããŒãã³ãã®ãœãŒã¹ã³ãŒãã衚瀺ãããå Žåã§ãã ãããè¡ãããã®ç§ã®æ¹æ³ã¯ãfsã䜿çšããŠgetServerSidePropså ã«ã³ã³ããŒãã³ãã®jsxãã¡ã€ã«ãããŒããããã¡ã€ã«ã®å 容ã®æååå€ãå°éå ·ãšããŠæž¡ãããšã§ãã
ç§ã¯ãããããŒã«ã«ã§æ©èœããããšã«ã€ããŠæãè¶ããŠæããŠããŸããããããããããç§ããããå±éããããã«è¡ã£ããšããåã³ã¯å»ããŸãã:(
åç §ããŠãã ããïŒ https ïŒ
@ElGoorfã®åé¡ã¯ã public
ãã¡ã€ã«ããšããžã«ãããé¢æ°ãã©ã ãã«ããããšã§ãã çŸåšã @vercel/next
ãŸã includeFiles
èš±å¯ãããŠããªãããã lambda
é¢æ°ã䜿çšããã®ãæãç°¡åãªæ¹æ³ã§ãã
ããã«ä»ã®äººãå©ããããã€ãã®ãµã³ãã«ã³ãŒãããããŸãïŒ https ïŒ
ããããšã@BrunoBernardino ãxåã®é ãã¢ã€ãã ããã£ãšèªã¿èŸŒãŸãã...ããèŠéããããšã«æ°ã¥ãããã¹ã¬ãããæå³ã倱ã£ãŠå€¢äžã«ãªã£ãŠãããšæããŸããïŒ
æ®å¿µãªãããEdge / Lambdaã«ã€ããŠèããã®ã¯åããŠãªã®ã§ããœãªã¥ãŒã·ã§ã³ã«èŠåŽããŸãããã @ balthildã®ãœãªã¥ãŒã·ã§ã³ã¯ãnode.fsã¡ãœãããè©Šãåã®åœåã®ãœãªã¥ãŒã·ã§ã³ã«è¿ãããšãããããŸããïŒ httpsïŒ/ /github.com/vercel/next.js/issues/8251#issuecomment -634829189
çŽ æŽãããïŒ åäœããŸãããïŒ ãããšããŸã åé¡ããããŸããïŒ
Vercelããã®çšèªã䜿çšããŠãããã©ããã¯ããããŸããããEdgeãšã¯ãéçãã¡ã€ã«ãæäŸãããCDNãæå³ããlambdaãšã¯ãAWSLambdaé¢æ°ã®ããã«åé¢ãããAPIã«ãŒãããåŒã³åºããããããã¯ãšã³ããé¢æ°ãæå³ããŸãã ã
ããã
vercelã§next.jsã䜿çšããŠãã¡ã€ã«ã«æžã蟌ãéã®æŽæ°ã¯ãããŸããïŒ åé¡ãªãèªããŸãã const logoPath = path.resolve('./public/logo.png')
ã䜿çšãã
public / sitemap.xmlãã¡ã€ã«ãäžæžãããããšããŠããŸãïŒvercelã®ãµã€ãºå¶éã®ããïŒããããªãã¯ãã©ã«ããŒå ã®éçãã¡ã€ã«ãšããŠãšã©ãŒãªãã§ã®ã¿è¿ãããšãã§ããŸãã 以åã«zlibã䜿çšããŠãµã€ãããããå®è£ ããå¿çãã¹ããªãŒãã³ã°ããŸããããã¹ããªãŒã ãçµäºãããŸã§åŸ ã£ãŠããè¿ãããã§ãã ããã¯ãµã€ãºå¶éãšã©ãŒã«ã¯ãªããŸããããæ®å¿µãªããéåžžã«äœéã§ãã ç§ã¯äººã ãæã£ãŠãããããããªãã©ããªææ¡ã«ããªãŒãã³ã§ãã ãµã€ããããã¯ãå¥ã®ããã¯ãšã³ããžã®APIåŒã³åºãããæ§ç¯ãããŠãããå®æçã«æŽæ°ããå¿ èŠããããŸãã
ç§ãè©Šã¿ãããšïŒ
ãã@emomooney ããµãŒããŒã¬ã¹ã®äž»ãªãå©ç¹ãã¯ã¹ããŒãã¬ã¹ã§ããããããã¹ããŒããè¿œå ããã®ã§ãVercelãé¢æ°ã«ãã¡ã€ã«ãæžã蟌ãããšãïŒãã£ãã·ã³ã°ã®å Žåã§ãïŒèš±å¯ããããšã¯ãªããšæããŸãããã®ããã«edge / cdnã䜿çšããå¿ èŠããããŸãã
以åã«zlibã䜿çšããŠãµã€ãããããå®è£ ããå¿çãã¹ããªãŒãã³ã°ããŸããããã¹ããªãŒã ãçµäºãããŸã§åŸ ã£ãŠããè¿ãããã§ãã
ã³ãŒã«ãã¹ã¿ãŒãã§ãåŸç¶ã®åŒã³åºãã§ãã®é床äœäžãçºçããã®ãããããšãæåã®åŒã³åºãã§çºçããã®ããèå³ããããŸããïŒ ããã¯ãnext.js apié¢æ°ãŸãã¯å°çšã®ã©ã ããä»ããVercelãžã®APIåŒã³åºãã§ãããããã§è¡ã£ãŠããããšãšäŒŒãŠãããšæããŸãã
ããã§ãé
ãããå ŽåãVercelã®å€éšã«ãããåå¥ã®ããã¯ãšã³ããã¯ãããŸããïŒ ãããããªããããªãã¯æœåšçã«ããã䜿ã£ãŠsitemap.xml
ãã¡ã€ã«ãšvercel --prod
ãã¡ã€ã³ã«æ§ç¯ããåºæ¬çã«ãã¡ã€ã«ãèªã¿åãå¯èœã§ã¢ã¯ã»ã¹å¯èœã«ããããã«ããã£ãã·ã¥ãããããšãã§ããŸãããããŠããªãã¯ãã æŽæ°ããå¿
èŠãããã§ãããrobots.txt
ã¯ããµã€ãããããå¥ã®ãã¡ã€ã³/ãµããã¡ã€ã³ã«ãªã³ã¯ããŸãã
æãåèã«ãªãã³ã¡ã³ã
ç§ã䜿çšããŠããåé¿çïŒ
ãããŠããªãããã¹ãå¿ èŠãšããå Žæã§
ããã§ã¯ãçŸåšã®ãã¡ã€ã«ããã®çžå¯Ÿãã¹ã§ãã¡ã€ã«ãåç §ããå¿ èŠããªãããšã¯ããã£ãŠããŸãããéåžžã«é¢é£ãããŠãŒã¹ã±ãŒã¹ïŒ
/public/images
ãã©ã«ããŒããç»åãã¡ã€ã«ãèªã¿åãïŒã¯è§£æ±ºããŸãã