Next.js项目实战踩坑指南(笔记)


Posted in Javascript onNovember 29, 2018

前言

github: https://github.com/code-coder/next-mobile-complete-app

已经用Next.js快两个月了,项目已经提测了,这里总结一下开发过程中,以及在部署的时候遇到一些棘手的问题。

疑难杂症

1. 移动端overflow:auto,ios滚动卡顿

解决方案: 主容器增加样式-webkit-overflow-scrolling: touch;

2. dev mode路由跳转后样式丢失

原因:dev下样式根据页面动态加载,浏览器缓存文件styles.chunk.css造成样式不更新。

解决方案: 利用版本号强制重载样式文件

示例1:

// 在Layout组件中
<Head>
  <title>{title}</title>
  {process.env.NODE_ENV !== 'production' && (<link rel="stylesheet" type="text/css" href={'/_next/static/css/styles.chunk.css?v=' + Router.route} />)}
</Head>

示例2:

// 在_app.js中
import Router from 'next/router';

Router.events.on('routeChangeComplete', () => {
 if (process.env.NODE_ENV !== 'production') {
  const els = document.querySelectorAll('link[href*="/_next/static/css/styles.chunk.css"]');
  const timestamp = new Date().valueOf();
  els[0].href = '/_next/static/css/styles.chunk.css?v=' + timestamp;
 }
});

3、Android 键盘弹起窗口会变小,有 flex 或者 position 是 absolute 或者 fixed 布局会变

这里直接把body.height设置为浏览器的窗口高度。

doc.body.style.height = docEl.clientHeight + 'px';

4、跨域及传递cookie的问题

第一步,登录成功后api服务器返回cookie。

跨域访问要接收cookie,解决办法也很简单只需要API服务器根据请求地址设置Access-Control-Allow-Origin的值为请求地址的ip就可以了(测试环境可以动态设置这个ip,生产可以设置指定的域名或者ip地址)。

第二步,浏览器自动缓存,再后续请求中携带此cookie。

fetch或axois请求都默认不带cookie,需要通过option配置打开。

- fetch要配置`{ credentials: 'include', mode: 'cors' }`

- axois要配置`axios.defaults.withCredentials=true;`

另外,还可以通过服务器代理走内网访问api。

以下为我们公司所采用的解决方案:

为了解决跨域以及部署不同服务器需要修改 api 地址的问题,我们使用 前端服务器代理 + dns 解析。整个流程如下图所示:

Next.js项目实战踩坑指南(笔记)

通过NODE_ENV环境变量来配置开发和生产的地址。

const isProd = process.env.NODE_ENV === 'production';
process.env.BACKEND_URL = isProd ? '/relative_url' : 'http://text.api.com';
process.env.BACKEND_URL_SERVER_SIDE = isProd ? 'http://bff.api.com' : 'https://prod.api.com';

module.exports = {
 'process.env.BACKEND_URL': process.env.BACKEND_URL, // 客户端渲染请求,是个相对地址,在前端服务器被代理到API服务器
 'process.env.BACKEND_URL_SERVER_SIDE': process.env.BACKEND_URL_SERVER_SIDE // 服务端渲染请求,是API服务器地址,仅供内网访问
};

5、服务端渲染时带 cookie 请求的问题

这里用到一个插件叫nookies。

在_app.js中全局解析cookies注入ctx:

static async getInitialProps({ Component, ctx }) {
  let pageProps = {};

  let cookies = {};
  if (ctx.isServer) {
   cookies = parseCookies(ctx);
  }
  if (Component.getInitialProps) {
   pageProps = await Component.getInitialProps({ ctx, cookies });
  }

  return { pageProps };
 }

然后就可以通过页面请求:

static async getInitialProps({ ctx }) {
  const { store, req, isServer, cookies } = ctx;
  store.dispatch(setNav({ navTitle: 'Home', isHome: true }));
  store.dispatch(getDataStart({ settings: { isServer, cookies } }));
 }

proxyFetch中就会根据isServer的值来分辨是服务端API请求还是客户端API请求。服务端请求会把cookies写入Fetch的header中。

const prefix = isServer ? process.env.BACKEND_URL_SERVER_SIDE : process.env.BACKEND_URL;
isServer && (this.headers['cookie'] = 'EGG_SESS=' + cookies['EGG_SESS'] + ';';)
// fetch核心
fetch(prefix + url, { headers: this.headers, ...this.init, ...options })

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
替代window.event.srcElement效果的可兼容性的函数
Dec 18 Javascript
jquery 查找新建元素代码
Jul 06 Javascript
Dom 结点创建 基础知识
Oct 01 Javascript
js Select下拉列表框进行多选、移除、交换内容的具体实现方法
Aug 13 Javascript
简单的jquery左侧导航栏和页面选中效果
Aug 21 Javascript
JS实现的用来对比两个用指定分隔符分割的字符串是否相同
Sep 19 Javascript
在Node.js中使用HTTP上传文件的方法
Jun 23 Javascript
JQuery Dialog对话框 不能通过Esc关闭的原因分析及解决办法
Jan 18 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
Jul 22 jQuery
vue 详情跳转至列表页实现列表页缓存
Mar 27 Javascript
Vue 引入AMap高德地图的实现代码
Apr 29 Javascript
JavaScript类的继承多种实现方法
May 30 Javascript
js canvas实现二维码和图片合成的海报
Nov 19 #Javascript
详解@angular/cli 改变默认启动端口两种方式
Nov 29 #Javascript
js实现每日签到功能
Nov 29 #Javascript
Vue.js的复用组件开发流程完整记录
Nov 29 #Javascript
javascript实现考勤日历功能
Nov 29 #Javascript
vsCode安装使用教程和插件安装方法
Aug 24 #Javascript
vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
Nov 29 #Javascript
You might like
PHP spl_autoload_register实现自动加载研究
2011/12/06 PHP
smarty半小时快速上手入门教程
2014/10/27 PHP
php从文件夹随机读取文件的方法
2015/06/01 PHP
PHP实现的CURL非阻塞调用类
2018/07/26 PHP
JS 自定义带默认值的函数
2011/07/21 Javascript
最佳的addEvent事件绑定是怎样诞生的
2011/10/24 Javascript
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
2014/06/19 Javascript
JavaScript实现继承的4种方法总结
2014/10/16 Javascript
Javascript中实现trim()函数的两种方法
2015/02/04 Javascript
jQuery实现的左右移动焦点图效果
2016/01/14 Javascript
基于javascript实现全屏漂浮广告
2016/03/31 Javascript
详解AngularJS中$filter过滤器使用(自定义过滤器)
2017/02/04 Javascript
jQuery倒计时代码(超简单)
2017/02/27 Javascript
nodejs个人博客开发第五步 分配数据
2017/04/12 NodeJs
vue使用swiper.js重叠轮播组建样式
2019/11/14 Javascript
基于小程序请求接口wx.request封装的类axios请求
2020/07/02 Javascript
js实现限定区域范围拖拉拽效果
2020/11/20 Javascript
[55:04]海涛DOTA2死魂复燃6.82版本介绍
2014/09/28 DOTA
Python中常用操作字符串的函数与方法总结
2016/02/04 Python
cmd运行python文件时对结果进行保存的方法
2018/05/16 Python
python一行sql太长折成多行并且有多个参数的方法
2018/07/19 Python
python实现代码统计程序
2019/09/19 Python
python实现图片转字符画的完整代码
2021/02/21 Python
Gerry Weber德国官网:优质女性时装,德国最大的时装公司之一
2019/11/02 全球购物
PPP协议组成及简述协议协商的基本过程
2015/05/28 面试题
个人职业生涯规划书1500字
2013/12/31 职场文书
兴趣小组活动总结
2014/05/05 职场文书
工程承包协议书范本
2014/09/29 职场文书
介绍长城的导游词
2015/01/30 职场文书
班主任班级管理心得体会
2016/01/07 职场文书
女人创业励志语录,句句蕴含能量,激发你的潜能
2019/08/20 职场文书
2019幼儿园感恩节活动策划书
2019/11/28 职场文书
PHP控制循环操作的时间
2021/04/01 PHP
简单且有用的Python数据分析和机器学习代码
2021/07/02 Python
Python使用PyYAML库读写yaml文件的方法
2022/04/06 Python