一、简介
二、创建项目
- 创建
$ 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.json
、node_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.json
、node_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
文件夹中即可,Link
或Image
访问时路径直接/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
打包一下,这时打包控制台会报出警告或报错,解决掉所有抛出的问题即可。 - 后续在补充…