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

简介: 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
> test@0.1.0 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: 'next@13.5.4',
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: 'ts-api-utils@1.0.3',
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 区分好正测试地址即可。
  • 客户端组件渲染,因为调用接口在浏览器前台,跟正常网页开发一样,则需要配置下代理,推荐直接使用本地 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 打包一下,这时打包控制台会报出警告或报错,解决掉所有抛出的问题即可。
  • 后续在补充…
相关文章
|
3天前
|
存储 JavaScript 索引
js开发:请解释什么是ES6的Map和Set,以及它们与普通对象和数组的区别。
ES6引入了Map和Set数据结构。Map的键可以是任意类型且有序,与对象的字符串或符号键不同;Set存储唯一值,无重复。两者皆可迭代,支持for...of循环。Map有get、set、has、delete等方法,Set有add、delete、has方法。示例展示了Map和Set的基本操作。
17 3
|
4天前
|
JavaScript 前端开发
js开发:请解释事件冒泡和事件捕获。
JavaScript中的事件处理有冒泡和捕获两种方式。事件冒泡是从子元素向上级元素传递,而事件捕获则从外层元素向内层传递。`addEventListener`的第三个参数可设定事件模式,`false`或不设为冒泡,`true`为捕获。示例代码展示了如何设置。
19 2
|
2天前
|
前端开发 JavaScript
js开发中的异步处理
JavaScript中的异步处理包括回调函数、Promise和async/await。回调函数是早期方法,将函数作为参数传递给异步操作并在完成后执行。Promise提供链式处理,通过resolve和reject管理异步操作的成功或失败。async/await基于Promise,允许写更简洁的同步风格代码,通过try-catch处理错误。Promise和async/await是现代推荐的异步处理方式。
|
3天前
|
域名解析 网络协议 安全
服务器部署访问出错的原因和解决办法
部署到服务器后无法访问可能是由于配置错误、权限问题或网络设置不当。解决办法包括检查服务器配置文件、确保文件路径正确、调整权限设置以及检查防火墙和端口设置。
13 4
|
3天前
|
JavaScript 前端开发
js开发:请解释什么是ES6的Generator函数,以及它的用途。
ES6的Generator函数是暂停/恢复功能的特殊函数,利用yield返回多个值,适用于异步编程和流处理,解决了回调地狱问题。例如,一个简单的Generator函数可以这样表示: ```javascript function* generator() { yield &#39;Hello&#39;; yield &#39;World&#39;; } ``` 创建实例后,通过`.next()`逐次输出&quot;Hello&quot;和&quot;World&quot;,展示其暂停和恢复的特性。
14 0
|
3天前
|
缓存 JavaScript 前端开发
js开发:请解释什么是Webpack,以及它在项目中的作用。
Webpack是开源的JavaScript模块打包器,用于前端项目构建,整合并优化JavaScript、CSS、图片等资源。它实现模块打包、代码分割以提升加载速度,同时进行资源优化和缓存。Webpack的插件机制可扩展功能,支持热更新以加速开发流程。
13 2
|
4天前
|
JavaScript 前端开发
js开发:请解释this关键字在JavaScript中的用法。
【4月更文挑战第23天】JavaScript的this关键字根据执行环境指向不同对象:全局中指向全局对象(如window),普通函数中默认指向全局对象,作为方法调用时指向调用对象;构造函数中指向新实例,箭头函数继承所在上下文的this。可通过call、apply、bind方法显式改变this指向。
7 1
|
4天前
|
JavaScript 前端开发
js开发:请解释同步和异步编程的区别。
同步编程按顺序执行,易阻塞;异步编程不阻塞,提高效率。同步适合简单操作,异步适合并发场景。示例展示了JavaScript中同步和异步函数的使用。
14 0
|
9天前
|
Java 应用服务中间件 Linux
在阿里云服务器上部署Tomcat详细图文详解
本文介绍了在阿里云服务器上安装和配置JDK和Tomcat的步骤。首先,需要注册阿里云账号并进行实名认证,然后购买并设置服务器。接着,通过File Zilla连接服务器,创建Java和Tomcat的安装目录,并将JDK和Tomcat的tar.gz文件上传到服务器,解压并重命名。之后,配置JDK的环境变量,将catalina.sh复制到/etc/init.d/目录下,并修改相关配置。最后,启动Tomcat并配置安全组规则,确保可以通过公网访问。
|
9天前
|
弹性计算 Java Linux
阿里云服务器搭建部署宝塔详细流程
该内容是一个阿里云服务器和域名的配置指南。首先,需注册阿里云账号并进行企业实名认证。接着,选购服务器如2核2G1兆的Linux系统,并购买域名。完成域名备案后,进行域名解析和ICP备案。然后,通过远程连接登录服务器,重置密码,安装宝塔面板。在安全组中开启宝塔面板随机生成的端口。最后,登录宝塔面板安装LNMP环境,配置数据库如MySQL和Redis,部署JDK、Tomcat,上传前端和后端项目以实现上线。