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 相关文章推荐
javascript 进度条 实现代码
Jul 30 Javascript
分享XmlHttpRequest调用Webservice的一点心得
Jul 20 Javascript
dwz 如何去掉ajaxloading具体代码
May 22 Javascript
CSS+jQuery实现的一个放大缩小动画效果
Sep 24 Javascript
jQuery选择器querySelector的使用指南
Jan 23 Javascript
PhotoShop给图片自动添加边框及EXIF信息的JS脚本
Feb 15 Javascript
javascript结合canvas实现图片旋转效果
May 03 Javascript
详解JavaScript ES6中的Generator
Jul 28 Javascript
JS实现AES加密并与PHP互通的方法分析
Apr 19 Javascript
WebSocket的简单介绍及应用
May 23 Javascript
微信小程序实现蒙版弹出窗功能
Sep 17 Javascript
使用vue判断当前环境是安卓还是IOS
Apr 12 Vue.js
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 启动时报错的简单解决方法
2014/01/27 PHP
如何使用PHP Embed SAPI实现Opcodes查看器
2015/11/10 PHP
Joomla实现组件中弹出一个模式(modal)窗口的方法
2016/05/04 PHP
PHP引用返回用法示例
2016/05/28 PHP
php封装的smartyBC类完整实例
2016/10/19 PHP
javascript offsetX与layerX区别
2010/03/12 Javascript
基于jQuery的为attr添加id title等效果的实现代码
2011/04/20 Javascript
利用JQuery制作符合Web标准的QQ弹出消息
2014/01/14 Javascript
JS实现距离上次刷新已过多少秒示例
2014/05/23 Javascript
jQuery+PHP实现微信转盘抽奖功能的方法
2016/05/25 Javascript
多种jQuery绑定事件的实现方式
2016/06/13 Javascript
AngularJS中transclude用法详解
2016/11/03 Javascript
Angular.js中ng-if、ng-show和ng-hide的区别介绍
2017/01/20 Javascript
关于laydate.js加载laydate.css路径错误问题解决
2017/12/27 Javascript
vuex实现的简单购物车功能示例
2019/02/13 Javascript
在vue中封装方法以及多处引用该方法详解
2020/08/14 Javascript
vue项目中openlayers绘制行政区划
2020/12/24 Vue.js
python中 chr unichr ord函数的实例详解
2017/08/06 Python
Python面向对象class类属性及子类用法分析
2018/02/02 Python
python钉钉机器人运维脚本监控实例
2019/02/20 Python
Python实现定时执行任务的三种方式简单示例
2019/03/30 Python
用Python中的turtle模块画图两只小羊方法
2019/04/09 Python
python使用递归的方式建立二叉树
2019/07/03 Python
python把ipynb文件转换成pdf文件过程详解
2019/07/09 Python
Django单元测试工具test client使用详解
2019/08/02 Python
Python实现滑动平均(Moving Average)的例子
2019/08/24 Python
Python实现直播推流效果
2019/11/26 Python
python全局变量引用与修改过程解析
2020/01/07 Python
使用Python判断一个文件是否被占用的方法教程
2020/12/16 Python
HTML5 canvas绘制的玫瑰花效果
2014/05/29 HTML / CSS
英国家喻户晓的家居商店:The Range
2019/03/25 全球购物
自主招生自荐信
2013/12/08 职场文书
2014年学生会部门工作总结
2014/11/07 职场文书
导师工作推荐信
2015/03/27 职场文书
运动会200米广播稿
2015/08/19 职场文书
党风廉洁教育心得体会
2016/01/20 职场文书