next.jsотличный легкий весreact
Изоморфная структура, которую можно использовать для быстрой разработки рендеринга на стороне сервера на основеreact
заявление. существуетnext.jsОфициальный сайт рекомендует использоватьnow
Для развертывания приложений, но для домашних пользователей или пользователей с особыми потребностями, развертывание на настраиваемых серверах может быть тем, чего хочет большинство людей. В связи с недавней ревизией официального сайта компании я хотел бы поделиться своим опытом от разработки до развертывания.
Я до сих пор смутно помню, как впервые использовал егоnext.jsбыл в прошлом году (2017), в то время с использованиемnext.js2.x версия,react
Еще версия 15, год спустя, сейчасreact
был разработан до версии 16, в то время какnext.jsОн разработан до версии 6.0, скорость итерации поражает, и в процессе использования новой версии есть много ям.
используемая технология
Поговорим о том, какие технологии используются на этот раз Ниже перечислены основные технологии или библиотеки инструментов, используемые в проекте.
Веб-фреймворк следующего поколения, разработанный оригинальной командой Express, используется для предоставления веб-сервисов.
Это высокопроизводительный HTTP и обратный прокси-сервер, а также сервер IMAP/POP3/SMTP (из энциклопедии Baidu), разработанный россиянами. Используется для предоставления статических файловых служб, сертификатов https и прокси-служб.
- react 16.3
библиотека пользовательского интерфейса javascript
- next.js 6.0.1
легкийreactИзоморфная структура приложения
Разработано Ant Financial
react的
Набор библиотек компонентов среднего и внутреннего продукта.
на основе
react
анимационные решения
Определить, находится ли компонент в текущей области просмотра
react
компоненты
Менеджер процессов для приложений Node с балансировкой нагрузки
Изоморфный API-интерфейс WHATWG Fetch
стадия развития
Сказав так много, давайте перейдем к этапу разработки, и первым шагом будет построение структуры проекта.Здесь мы делимся нашей структурой проекта:
📁.vscode
vscode
конфигурационный файл
📁component
reactкомпоненты
📁common
В общедоступную часть я помещаю информацию панели навигации, глобальные переменные и глобальные стили и т. д.
📁pages
Все страницы проекта, а такжеnext.js входной файл для каждой страницы
📁static
статические файлы
📁styles
таблица стилей для каждой страницы
🗄index.js
файл запуска узла
🗄.babelrc
babelконфигурационный файл
🗄.gitignore
конфигурационный файл git
🗄ecosystem.config.js
pm2конфигурационный файл
🗄next.config.js
next.js конфигурационный файл
🗄postcss.config.js
postcss конфигурационный файл
🗄nginx.conf
nginxконфигурационный файл
🗄package.json
конфигурационный файл нпм
После завершения настройки структуры проекта предполагается, что вы уже находитесь вpackage.json
Все нужные нам зависимости сохранены в, попробуем набратьyarn
для установки зависимостей. Предполагая, что установка прошла успешно, давайте продолжим наш путь разработки.
Первый вpages
Создайте новый под файломindex.js
, здесь я просто случайным образом извлекаю какой-то код из своего реального проекта в качестве учителя.
export default class HomePage extends React.Component {
static async getInitialProps({ req, pathname }) {
const data = await fetch(`${ctx}/api/projects/common/list`).then(res => res.json())
.then(dt => dt)
.catch(err => {
return {
success: false,
message: err.message
}
})
return { pathname,data };
}
render() {
const { pathname, data } = this.props;
return (
<div>
<Head>
<title>首页-易科捷(武汉)生态科技有限公司</title>
</Head>
<div>Welcome to next.js!</div>
{/*这里省略代码*/}
</div>
);
}
}
если вашpackage.json
не настроен вnext
Запустите скрипт, пожалуйста, посетитеsetupДля настройки ниже запускаем в консолиnpm run dev
, если все в порядке, откройте браузер, и вы увидитеWelcome to next.js!
существуетnext.js
опыт разработки иreact
почти никакой разницы, но вwebpack
Настройка этой части может занять немного работы. Некоторые часто используемые плагины, такие какsass
,css
Ждать,next.js
Все это предусмотрено для вас, и вы также можете использовать плагины сообщества с открытым исходным кодом, чтобы завершить свой путь разработки. Для получения подробной информации, пожалуйста, проверьтеофициальный сайт next.js.
развертывать
После прохождения ряда процессов, таких как этап разработки, тестирование и т. д., теперь, наконец, настал этап развертывания. существуетnext.js
На стадии производства упаковка должна запускаться толькоnpm run build
Вот и все, официальная рекомендация - не менять имя запакованной папки (оригинальное имя.next
), вот я лично рекомендую модифицировать егоbuild
илиdist
эти имена. После того, как упаковка будет завершена, вам нужно написатьnodejs
Запустите файл записи и вставьте приведенный ниже пример кода:
const Koa = require('koa')
const next = require('next')
const Router = require('koa-router')
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 = new Koa()
const router = new Router()
// 首页
router.get('/', async ctx => {
await app.render(ctx.req, ctx.res, '/', ctx.query)
ctx.respond = false
})
// 关于
router.get('/about', async ctx => {
await app.render(ctx.req, ctx.res, '/about', ctx.query)
ctx.respond = false
})
// 产品
router.get('/products/:id', async ctx => {
const {id} = ctx.params
await app.render(ctx.req, ctx.res, `/products/${id}`, ctx.query)
ctx.respond = false
})
// 案例
router.get('/case', async ctx => {
await app.render(ctx.req, ctx.res, '/case', ctx.query)
ctx.respond = false
})
// 联系我们
router.get('/contact', async ctx => {
await app.render(ctx.req, ctx.res, '/contact', ctx.query)
ctx.respond = false
})
// 详情
router.get('/view/:type/:id', async ctx => {
const {id, type} = ctx.params
await app.render(ctx.req, ctx.res, `/view`, {id, type})
ctx.respond = false
})
// 如果没有配置nginx做静态文件服务,下面代码请务必开启
/* router.get('*', async ctx => {
await handle(ctx.req, ctx.res)
ctx.respond = false
})*/
// 防止出现控制台报404错误
server.use(async (ctx, next) => {
ctx.res.statusCode = 200
await next()
})
server.use(router.routes())
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`)
})
})
Общие статические файлы, сжатие gzip не нужно передаватьnodejs
Чтобы сделать это, я всегда думал, что профессиональные вещи оставляются профессиональным людям. Здесь задача передаетсяnginx
, обратите особое внимание на часть кода, которую я прокомментировал в примере кода выше, если вы не используетеnginx
Чтобы использовать статическую файловую службу, обязательно откройте ее, в противном случаеnext.js
упакованныйjs
,css
, файлы изображений и т. д., будут сообщены404
.
существуетnext.js
Упаковано на стадии производственной упаковкиjs
Путь запроса файла имеет номер версии, но фактическая упакованная папка не имеет фактического соответствующего каталога, то есть здесь используется упакованный виртуальный каталог.nginx
нуждаются в особом внимании. к счастьюnext.js
Укажите элементы конфигурации для измененияbuild id
, вот мой реальный код:
// next.config.js
module.exports = {
generateBuildId: async () => {
// For example get the latest git commit hash here
return 'v1'
}
}
Упакованный таким образом виртуальный путь, вероятно,_next/v1/page/xxx.js
, если вы используетеcdn
префикс, здесь есть небольшая разница, но номер версии все же есть.
Еще одно отверстиеnext.js
В комплекте три папки:bundles
,dist
,static
, для тех, кто не знает исходный код, они не знают, в какой папке находится фактический файл запроса. Так что я вижуnext.js
Исходный код, я обнаружил, что на самом деле я искалbundle
под файломpage
, расположение исходного кода:L214
Итак, в конфигурацииnginx
Вам нужно использовать псевдоним. Ниже мой фрагментnginx
Реальный код конфигурации:
# 网站根目录文件
location ~ ^/(robots.txt|humans.txt|favicon.ico|sw.js|baidu_verify_7Kj6tQjI3v.html) {
root /home/website/eco_website_pc/static/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# static下的文件
location ^~ /static/ {
alias /home/website/eco_website_pc/static/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# next pages页面下的脚本
location ~ ^/(/_next/v1/) {
alias /home/website/eco_website_pc/build/bundles/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# next static下的静态文件
location ~ ^/(/_next/static/) {
root /home/website/eco_website_pc/build;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
После того, как статический файл настроен, его необходимо настроитьhttps
Сертификат в наличии, т.к. наш проект официальный сайт компании, сертификат получу бесплатно, вот пользуюсьfreesslСертификат целостности в Азии, представленный выше. После примененияssl
После сертификата нужно перейти к провайдеру доменного имени для настройкиTXT
Для справки, здесь я использую Alibaba Cloud.После завершения проверкиfreesslСертификат будет скачан, после получения сертификата необходимо его настроить.nginx
ssl
Сертификат, моя полная конфигурация размещена ниже:
server {
listen 80;
listen 443 ssl;
server_name wh-eco.com;
charset utf-8;
ssl_certificate /home/website/ssl/www/full_chain.pem;
ssl_certificate_key /home/website/ssl/www/private.key;
fastcgi_param HTTPS on;
fastcgi_param HTTP_SCHEME https;
if ($scheme = http ) {
return 301 https://$host$request_uri;
}
access_log /var/log/nginx/www.wh-eco.com.access.log;
error_log /var/log/nginx/www.wh-eco.com.error.log;
location / {
proxy_pass http://127.0.0.1:xxxx; #保密 0.0
proxy_set_header Host $host;
#proxy_redirect off;
proxy_set_header REMOTE-HOST $remote_addr;
# 网站可能后期会使用websocket 特次升级请求协议
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60;
proxy_read_timeout 600;
proxy_send_timeout 600;
}
# 网站根目录文件
location ~ ^/(robots.txt|humans.txt|favicon.ico|sw.js|baidu_verify_7Kj6tQjI3v.html) {
root /home/website/eco_website_pc/static/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# static下的文件
location ^~ /static/ {
alias /home/website/eco_website_pc/static/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# next pages页面下的脚本
location ~ ^/(/_next/v1/) {
alias /home/website/eco_website_pc/build/bundles/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# next static下的静态文件
location ~ ^/(/_next/static/) {
root /home/website/eco_website_pc/build;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
error_page 500 502 503 504 = /error.html;
error_page 404 = /notfound.html;
location = /error.html {
root /home;
}
location = /notfound.html{
root /home;
}
}
Что касаетсяgzip
Вы можете настроить его в соответствии с вашими требованиями, вставьте пример моей конфигурации:
gzip on;
gzip_comp_level 6;
gzip_vary on;
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
image/jpeg
image/gif
image/png
text/css
text/plain
text/x-component;
по окончанииnginx
Что нужно сделать после настройкиpm2
способ запуска всего приложения
pm2 start ecosystem.config.js
После выполнения вышеуказанной команды, если все пойдет хорошо, вы можете ввести доменное имя для доступа к вашему приложению (при условии, что вы завершили работу по разрешению доменного имени).
Суммировать
Как только вы входите в переднюю часть, она такая же глубокая, как море