NextJS with Express : copying files to server and running “npm run start” fails

核能气质少年 提交于 2020-03-25 13:00:27

问题


I am creating a NextJS application and I want to copy ONLY the production files to my server and deploy the application. This works perfectly fine when I do NOT use Express, however when i do use Express the app no longer runs on the server as it says it can not find the "pages" directory.

Project structure

|- .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

My steps

I develop the application locally and test it my running "npm run dev". When the app is ready to deploy to a server I copy JUST the production files to the server and deploy the application. It is my understanding that the built application is ALL contained in the ".next" directory, therefore this is the only directory I copy to my server.

Here are my full steps in order to get the application on the server

  1. Develop the application locally
  2. Test locally using "npm run dev"
  3. Test locally using "npm run build" and then "npm run start"
  4. Application runs perfectly fine
  5. Move the files to the server location and deploy
    1. cp .next ~/myTestFolder
    2. cp package.json ~/myTestFolder
    3. cp package-lock.json ~/myTestFolder
    4. cp next.config.js ~/myTestFolder
    5. cd ~/myTestFolder
    6. npm install
    7. npm run build
    8. npm run start
    9. Application runs perfectly fine

The process fails when i use Express

As soon as I use Express, this process no longer works. I need to use express and dotenv so I can have a customizable basePath for my application which can differ on the different servers I deploy my application to (see my other stack overflow question : NextJS deploy to a specific URL path)

I did the following:

Install the new dependencies

npm install --save express dotenv

Create a ".env" file

BASE_PATH=/my-test-application/path-for-my-app

Update "next.config.js" to read the variables from ".env" and pass to WebPack so it can be used in ".js" files

// 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))    
        ....
    }
    ....
 }

Update the scripts in "package.json"

"scripts": {
    "dev": "node ssr-server.js",
    "build": "next build",
    "start": "node ssr-server.js"
},

Create a "ssr-server.js" file to do the routing

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}`)
  })
})

Update any "Link"s to use this path

render(){
    let basePath = process.env.BASE_PATH? process.env.BASE_PATH: "";
    ...
    <Link href={`${basePath}/page1`}> 
    ...

I can run the application locally using "npm run dev" and "npm run build"/"npm run start".

However when I copy files to my server location it now fails. I copy all the same files as above with the addition of the 2 new files

  • cp ssr-server.js ~/myTestFolder
  • cp .env ~/myTestFolder

I run "npm build" OK, but when I run "npm run start" it fails with the following

$ 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

Any idea what I am missing/doing wrong?


回答1:


The error clearly says:

Error: > Couldn't find apagesdirectory..

you have to cp pages ~/myTestFolder as well.



来源:https://stackoverflow.com/questions/60564471/nextjs-with-express-copying-files-to-server-and-running-npm-run-start-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!