我正在创建一个 NextJS 应用程序,我只想将生产文件复制到我的服务器并部署该应用程序。当我不使用 Express 时,这工作得很好,但是当我使用 Express 时,应用程序不再在服务器上运行,因为它说它找不到“页面”目录。
项目结构
|- .next
|- client
|- polyfills.js
|- components
|- CompA.js
|- CompB.js
|- etc
|- node-modules
|- ...
|- pages
|- index.js
|- page1.js
|- page2.js
|- etc
|- public
|- appIcon.png
|- scripts
|- utils.js
|- stylesheets
|- main.css
|- next.config.js
|- package-lock.json
|- package.json
我的脚步
我在本地开发应用程序并测试我正在运行的“npm run dev”。当应用程序准备好部署到服务器时,我只将生产文件复制到服务器并部署应用程序。我的理解是构建的应用程序全部包含在“.next”目录中,因此这是我复制到服务器的唯一目录。
这是我在服务器上获取应用程序的完整步骤
- 在本地开发应用程序
- 使用“npm run dev”在本地测试
- 使用“npm run build”然后“npm run start”在本地进行测试
- 应用程序运行良好
- 将文件移动到服务器位置并部署
- cp .next ~/myTestFolder
- cp package.json ~/myTestFolder
- cp package-lock.json ~/myTestFolder
- cp next.config.js ~/myTestFolder
- cd ~/myTestFolder
- 安装
- npm 运行构建
- npm 运行开始
- 应用程序运行良好
当我使用 Express 时该过程失败
一旦我使用 Express,这个过程就不再有效。我需要使用 express 和 dotenv 以便我可以为我的应用程序提供一个可自定义的 basePath,它在我将应用程序部署到的不同服务器上可能有所不同(请参阅我的其他堆栈溢出问题: NextJS 部署到特定 URL 路径)
我做了以下事情:
安装新的依赖
npm install --save express dotenv
创建一个“.env”文件
BASE_PATH=/my-test-application/path-for-my-app
更新“next.config.js”以从“.env”读取变量并传递给WebPack,以便它可以在“.js”文件中使用
// support getting variables from the server environment
const { parsed: localEnv } = require('dotenv').config()
const webpack = require('webpack')
module.exports = {
// Stop being being able to access pages without using proper URL
useFileSystemPublicRoutes: false,
webpack: function(cfg) {
// pass the environment variables to webpack so JS files can access them
cfg.plugins.push(new webpack.EnvironmentPlugin(localEnv))
....
}
....
}
更新“package.json”中的脚本
"scripts": {
"dev": "node ssr-server.js",
"build": "next build",
"start": "node ssr-server.js"
},
创建一个“ssr-server.js”文件来做路由
const express = require('express')
const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.get('/my-test-application/path-for-my-app', (req, res) => {
return app.render(req, res, '/index', req.query)
})
server.get('/my-test-application/path-for-my-app/page1', (req, res) => {
return app.render(req, res, '/page1', req.query)
})
server.get('/posts/:id', (req, res) => {
return app.render(req, res, '/posts', { id: req.params.id })
})
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
更新任何“链接”以使用此路径
render(){
let basePath = process.env.BASE_PATH? process.env.BASE_PATH: "";
...
<Link href={`${basePath}/page1`}>
...
我可以使用“npm run dev”和“npm run build”/“npm run start”在本地运行应用程序。
但是,当我将文件复制到我的服务器位置时,它现在失败了。我复制了与上面相同的所有文件,并添加了 2 个新文件
- cp ssr-server.js ~/myTestFolder
- cp .env ~/myTestFolder
我运行“npm build”OK,但是当我运行“npm run start”时它失败并显示以下内容
$ npm run start
> React_SSR@1.0.0 start /home/myTestFolder
> node ssr-server.js
/home/myTestFolder/node_modules/next/dist/lib/find-pages-dir.js:3
if(existsSync(_path.default.join(dir,'..','pages'))){throw new Error('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?');}throw new Error("> Couldn't find a `pages` directory. Please create one under the project root");}
^
Error: > Couldn't find a `pages` directory. Please create one under the project root
at findPagesDir (/home/myTestFolder/node_modules/next/dist/lib/find-pages-dir.js:3:170)
at new DevServer (/home/myTestFolder/node_modules/next/dist/server/next-dev-server.js:1:3830)
at createServer (/home/myTestFolder/node_modules/next/dist/server/next.js:2:105)
at Object.<anonymous> (/home/myTestFolder/ssr-server.js:5:13)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! React_SSR@1.0.0 start: `node ssr-server.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the React_SSR@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/myTestFolder/.npm/_logs/2020-03-06T10_24_04_105Z-debug.log
知道我错过了什么/做错了什么吗?