Next.js 创建项目到服务器部署(目录结构介绍、项目结构Demo、开发细节注意)

一、简介

二、创建项目

  • 创建

    $ npx create-next-app@latest
    
    What is your project named? test                                // 项目名
    Would you like to use TypeScript? No / Yes                      // 是否使用 TypeScript,选 Yes。
    Would you like to use ESLint? No / Yes                          // 是否使用 ESLint,选 Yes。
    Would you like to use Tailwind CSS? No / Yes                    // 是否使用 Tailwind CSS,选 Yes。
    Would you like to use `src/` directory? No / Yes                // 是否使用 src 作为根目录,选 Yes。
    Would you like to use App Router? (recommended) No / Yes        // 是否使用 路由,选 Yes。
    Would you like to customize the default import alias? No / Yes  // 是否需要 自定义默认导入别名;如果需要给项目根目录设置个别名,方便等项目目录层级深的时候引入,可以选择 Yes,我选了 Yes。
    What import alias would you like configured? @/*                // 配置什么导入别名,就用它的默认推荐 @/*,后续可以根据自己喜好去 tsconfig.json 中修改设置多个
    
  • 运行项目

    # 进入项目
    $ cd test
    
    # 启动测试环境
    $ npm run dev
    

    但是报错:

    $ npm run dev
    
    > [email protected] dev
    > next dev
    
    node:internal/modules/cjs/loader:940
      const err = new Error(message);
                  ^
    
    Error: Cannot find module 'stream/web'
    Require stack:
    - /Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/compiled/@edge-runtime/primitives/load.js
    - /Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/compiled/@edge-runtime/primitives/index.js
    - /Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/compiled/@edge-runtime/ponyfill/index.js
    - /Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/telemetry/storage.js
    - /Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/cli/next-dev.js
    - /Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/lib/commands.js
    - /Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/bin/next
        at Function.Module._resolveFilename (node:internal/modules/cjs/loader:940:15)
        at /Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/server/require-hook.js:54:36
        at Function.Module._load (node:internal/modules/cjs/loader:773:27)
        at Module.require (node:internal/modules/cjs/loader:1012:19)
        at Module.mod.require (/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/server/require-hook.js:64:28)
        at require (node:internal/modules/cjs/helpers:93:18)
        at Object.<anonymous> (/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/compiled/@edge-runtime/primitives/load.js:39:18)
        at Module._compile (node:internal/modules/cjs/loader:1108:14)
        at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
        at Module.load (node:internal/modules/cjs/loader:988:32) {
          
          
      code: 'MODULE_NOT_FOUND',
      requireStack: [
        '/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/compiled/@edge-runtime/primitives/load.js',
        '/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/compiled/@edge-runtime/primitives/index.js',
        '/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/compiled/@edge-runtime/ponyfill/index.js',
        '/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/telemetry/storage.js',
        '/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/cli/next-dev.js',
        '/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/lib/commands.js',
        '/Users/dengzemiao/Desktop/Project/react/nextjs/test/node_modules/next/dist/bin/next'
      ]
    }
    

    于是删除 package-lock.jsonnode_modules 重新安装一遍:

    $ npm i
    
    npm WARN EBADENGINE Unsupported engine {
          
          
    npm WARN EBADENGINE   package: '[email protected]',
    npm WARN EBADENGINE   required: {
          
           node: '>=16.14.0' },
    npm WARN EBADENGINE   current: {
          
           node: 'v16.0.0', npm: '7.10.0' }
    npm WARN EBADENGINE }
    npm WARN EBADENGINE Unsupported engine {
          
          
    npm WARN EBADENGINE   package: '[email protected]',
    npm WARN EBADENGINE   required: {
          
           node: '>=16.13.0' },
    npm WARN EBADENGINE   current: {
          
           node: 'v16.0.0', npm: '7.10.0' }
    npm WARN EBADENGINE }
    
    added 329 packages in 14s
    

    看到有部分包使用 engine 指定了版本,就重新装了个 node v16.14.0,然后再次删除 package-lock.jsonnode_modules 重新安装一遍,并运行项目,启动成功。

  • 启动成功后,以前的版本主要开发目录在 pages(Pages Router) 文件夹中,但是新版本增加了 app(APP Router) 目录,推荐使用 APP Router 完成开发,只是 pages 的一些回调函数无法在 app 目录中使用。

    Pages Router 目录结构:

    └── pages
        ├── about.js
        ├── index.js
        └── user.js
    

    APP Router 目录结构:

    src
    └── app
        ├── about
        │   └── page.js
        │   └── layout.js   // about 页面在全局 layout 基础上,再单独嵌套的 layout,这个里面才展示 page.js 的渲染内容
        ├── login
        │   └── page.js
        ├── team
        │   └── route.js
        ├── globals.css
        ├── layout.js       // 全局 layout
        ├── page.js 
        └── ...
    

三、接口调用,框架随意,都一样(例如 axios

  • 服务器组件渲染调研的接口可以直接全链接访问即可,在服务器渲染,不存在跨域。使用 .env 区分好正测试地址即可。

    扫描二维码关注公众号,回复: 17168541 查看本文章
  • 客户端组件渲染,因为调用接口在浏览器前台,跟正常网页开发一样,则需要配置下代理,推荐直接使用本地 nginx 配置,nginx server 配置文件:

    server {
          
          
            listen      8088;
            # server_name     next-nginx.com;
    
            location /api/ {
          
          
                    # 接口代理地址
                    proxy_pass https://test-api.xxx.com/api/;
            }
    
            location /_next/webpack-hmr {
          
          
                    proxy_pass http://localhost:3000/_next/webpack-hmr;
                    proxy_http_version 1.1;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection "upgrade";
            }
    
            location / {
          
          
                    # 访问 8088 时,转发到 nextjs 起的 3000 端口
                    proxy_pass http://localhost:3000;
            }
    }
    

    配置好后,重启 nginx 访问 http://localhost:8088/ 即可,服务器渲染部分的接口通过全链接直接加载好数据,客户端组件则通过代理加载好数据。

四、发包部署服务器

  • 安装 pm2,使用它挂起服务即可

    # 发布测试环境
    $ pm2 start npm --name <servername> -- run dev
    
    # 发布正式环境
    $ npm run build
    $ pm2 start npm --name <servername> -- run satrt
    
    # 重启
    $ pm2 restart <servername>
    
    # 查看所有服务
    $ pm2 ls
    
    # 删除服务
    $ pm2 delete <id>
    $ pm2 delete all
    
  • build 打包时如果报错 Error occurred prerendering page “/“. ...,意思就是 "/" 页面在服务器渲染时遇到报错崩溃了,需要排查下是哪里写错了,导致崩溃。解决方案

五、开发小细节

  • 如果需要实现网页加载完成,点击加载更多数据,则需要客户端组件配合完成。 Next.js 自用基础框架与功能案例

  • 图片不要使用 img 进行加载,需要使用自带的 Image 组件加载,Image 组件加载的图片,需要在 next.config.js 中配置好每个图片的域名,作为白名单,要不然会加载图片失败。

  • 预处理器推荐使用 sass,配置默认支持,安装一下即可使用,直接使用 CSS Modules 也成。

    $ npm i sass
    
  • 服务器组件不支持点击事件,客户端组件才可以使用点击事件、hooks 相关函数。

  • 素材或者原生静态网页需要导入到 nextjs 中时,直接丢到 public 文件夹中即可,LinkImage 访问时路径直接 /logo.svg/html/index.html 即可,最前面不需要 ./ 直接 /,不然访问静态页面会报错。

  • 启动之后控制器有个 app-index.js:31 Warning: Extra attributes from the server: data-darkreader-mode,data-darkreader-scheme 警告,能解决就解决,不能解决后面开发完成后发现没了,就算没解决好像也没什么影响,不要慌。

  • 想看自己代码写的是否有无问题,不是 run dev 起来就行,这样无法看到隐藏的问题,可以通过 $ npm run build 打包一下,这时打包控制台会报出警告或报错,解决掉所有抛出的问题即可。

  • 后续在补充…

猜你喜欢

转载自blog.csdn.net/zz00008888/article/details/134079382
今日推荐