1. 建立项目
安装 create-next-app 脚手架
npm i -g create-next-app
用脚手架简历next项目
create-next-app nextjs_react
创建完成后项目目录
├─ /.next <-- 用于SSR运行的工程,执行yarn dev或yarn build后才会出现
├─ /node_modules
├─ /pages <-- Next.js指定的页面目录
| ├─ /api <-- Next.js指定的API服务目录,可以删除
| | └─ hello.js <-- API服务的hello接口
| ├─ _app.js <-- Next.js指定的项目入口文件
| └─ index.js <-- 项目首页
├─ /public <-- 静态目录,放在这里的文件可通过"/"直接访问(没有public这一层级)
| ├─ favicon.ico
| └─ vercel.svg
├─ /styles <-- 项目全局样式
| ├─ globals.css
| └─ Home.module.css <-- Home组件样式
├─ .eslintrc.json
├─ .gitignore
├─ next.config.js <-- Next.js配置文件
├─ package.json
├─ README.md
└─ yarn.lock
2. 更改项目目录结构
- 根目录下新增 src 目录
- 把 pages 目录放到 src 目录里
- 在 src 目录下新建 common 目录
- 将 styles 目录放到 common 目录下
最终初始目录结构如下:
/src
├─ /common <-- 公用目录
| ├─ /images <-- 公用图片目录
| └─ /styles <-- 公用样式目录
├─ /components <-- 公用组件目录
└─ /pages <-- Next.js指定的页面目录
├─ /api <-- Next.js指定的API服务目录(不会生成api页面目录)
├─ _app.js <-- Next.js指定的项目入口文件(不会生成_app.html)
└─ index.js <-- index页面(会生成index.html)
3. 配置项目
在tsconfig.json
文件中添加如下配置:
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
}
}
在src/pages/_app.js
修改页面title:
import '@/common/styles/globals.scss'
import type { AppProps } from 'next/app'
import Head from 'next/head'
export default function App ({ Component, pageProps }: AppProps) {
return (
<>
<Head>
<title>nextjs_react</title>
</Head>
<Component {...pageProps} />
</>
)
}
4. 集成Sass/Scss
安装sass
npm i sass --save
nextjs有内置sass,在配置next.config,js里面打开
const path = require('path')
module.exports = {
sassOptions: {
includePaths: [path.join(__dirname, 'styles')],
},
}
5. 配置axios
安装axios:
npm i axios --save
在src目录下新建utils/axios.ts
:
import axios from 'axios'
import qs from "qs"
axios.defaults.timeout = 30000
axios.defaults.withCredentials = true // 跨域设置
axios.defaults.baseURL = ''
const cancelArr: Array<any> = [];
export { cancelArr }
// 请求拦截器
axios.interceptors.request.use(
(config: any) => {
// 一些请求拦截操作
return config;
},
(error: any) => {
return Promise.reject(error);
}
)
// 响应拦截器
axios.interceptors.response.use(
(response: any) => {
return response
},
(error: any) => {
return Promise.reject(error)
}
)
export default axios
/**
* post 请求方法
* @param url
* @param data
* @returns {Promise}
*/
export function post (url: string, data = {}, responseType: any) {
return new Promise((resolve, reject) => {
axios.post(url, data, {
responseType,
cancelToken: new axios.CancelToken(function executor (cancel) {
cancelArr.push({
cancel
})
})
}).then(
response => {
if (response) {
resolve(response.data);
} else {
console.log("取消了")
}
},
err => {
reject(err);
}
);
});
}
/**
* get 请求方法
* @param url
* @param data
* @returns {Promise}
*/
export function get (url: string, data = {}) {
return new Promise((resolve, reject) => {
axios.get(url, data).then(
response => {
resolve(response.data);
},
err => {
reject(err);
}
);
});
}
解决跨域问题:
-
安装插件:
npm i express http-proxy-middleware
-
在项目根目录中新建
server.js
const express = require('express')
const next = require('next')
const { createProxyMiddleware } = require('http-proxy-middleware')
// 配置代理
const devProxy = {
'/api': {
target: 'http://192.168.xx.xx:8000', // 端口自己配置合适的
pathRewrite: {
'^/api': '/api'
},
changeOrigin: true
}
}
// 运行端口
const port = parseInt(process.env.PORT, 10) || 3000
// 判断是否为开发环境
const dev = process.env.NODE_ENV !== 'production'
// 初始化app
const app = next({
dev
})
const handle = app.getRequestHandler()
app.prepare()
.then(() => {
const server = express()
// 开发环境下使用代理接口
if (dev && devProxy) {
Object.keys(devProxy).forEach(function (context) {
server.use(createProxyMiddleware(context, devProxy[context]))
})
}
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, err => {
if (err) {
throw err
}
console.log(`> Ready on http://localhost:${port}`)
})
})
.catch(err => {
console.log(err, 'error')
})
- 修改
package.json
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js",
"lint": "next lint"
},