next.js小结

Next.js

关于最近next.js开发总结

1.初始化demo案例

nextjs.frontendx.cn/docs/#安装

跟据官网操作,基本上能实现一个hellow demo,第一步已经完成

2.antd引入及less(主题配置)&&静态资源服务

yarn add antd @zeit/next-less less less-loader less-vars-to-js

antd 阿里系提供的UI Framework,这个就不说了.@zeit/next-less 由next.js官方推荐样式解决方案,也有scss,css,stylus的,这个可自行去官网查看,less-vars-to-js这个用来配置主题,在next.config.js中进行配置,next.config.js是next.js官方为开发者提供个性化配置文件。 静态资源服务有点小坑,img引入url直接链接static 这是没问题的,但是背景图片引入的时候有时候会无法解析,但有时候又可以,另外就是在开发模式下,新路由页面不能及时加载样式文件渲染,再次刷新就可以了,当然在生产环境中,这个问题是没有的

const withLess = require("@zeit/next-less");
const lessToJS = require("less-vars-to-js");
//主题配置 通过不同环境可以调用不同的主题方案
const themeVariables = lessToJS(
  fs.readFileSync(path.resolve(__dirname, "./assets/antd-custom.less"), "utf8")
);
// fix: prevents error when .less files are required by node
if (typeof require !== "undefined") {
  require.extensions[".less"] = file => {};
}
module.exports = withLess({
  lessLoaderOptions: {
    javascriptEnabled: true,
    modifyVars: themeVariables,
    localIdentName: "[local]___[hash:base64:5]"
  },
  webpack(config,options){
      return config //自定义webpack配置
  }
})
复制代码
3.定制路由

默认路由是pages文件下的名称,比如pages下a.js,b.js,那么路由名称就是/a,/b.随着项目开发越来越大,名称不好取,通常在服务端控制路由,全局目录下新建server.js

const express = require("express"); //express作为server启动方案,也可取koa以及其他方案
const next = require("next");
const compression = require("compression");  //压缩插件 若配nginx,这个可不需要
const devProxy = {
  "/front": {
    target: "http://10.37.0.***:84",
    pathRewrite: { "^/front": "/front" },
    changeOrigin: true
  }
}; //代理配置
const port = parseInt(process.env.PORT, 10) || 3000;
const env = process.env.NODE_ENV;
const dev = env !== "production";
const app = next({
  dir: ".", // base directory where everything is, could move to src later
  dev
});

const handle = app.getRequestHandler();
let server;
app
  .prepare()
  .then(() => {
    server = express();
    // Set up the proxy.
    if (dev && devProxy) {
      const proxyMiddleware = require("http-proxy-middleware");
      Object.keys(devProxy).forEach(function(context) {
        server.use(proxyMiddleware(context, devProxy[context]));
      });
    }
    if (!dev) {
      server.use(compression()); //gzip
    }
    server.get("/login", (req, res) => {
      app.render(req, res, "/login");
    });
    // 首页重定义
    server.get("/", (req, res) => {
      app.render(req, res, "/home");
    });
    server.all("*", (req, res) => handle(req, res));
    server.listen(port, err => {
      if (err) {
        throw err;
      }
      console.log(`> Ready on port ${port} [${env}]`);
    });
  })
  .catch(err => {
    console.log("An error occurred, unable to start the server");
    console.log(err);
  });
复制代码

配置完成后,package.json文件也要做对应更改

{
  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  }
}
复制代码
4.数据请求

数据请求主要分为两部分,一部分是客户端请求,一部分是服务端请求,页面初始化数据都放服务端,表单提交内容放客户端,列表分页首次在服务端,其后放客户端 服务端请求next.js主要是通过getInitialProps方法获取api数据,其内置属性:

  • pathname - URL 的 path 部分
  • query - URL 的 query 部分,并被解析成对象
  • asPath - 显示在浏览器中的实际路径(包含查询部分),为String类型
  • req - HTTP 请求对象 (只有服务器端有)
  • res - HTTP 返回对象 (只有服务器端有)
  • jsonPageRes - 获取数据响应对象 (只有客户端有)
  • err - 渲染过程中的任何错误
Page.getInitialProps = async ({ req }) => {
  const res = await fetch('https://api.github.com/repos/zeit/next.js')
  const json = await res.json()
  return { stars: json.stargazers_count }
}
复制代码

这里讲个很重要的数据请求插件 isomorphic-unfetch,官方介绍,既可以在浏览器端使用,也可以在node端使用,在next.js中再适合不过了 客户端请求,就是普通的fecth就行,主要是讲数据传递及存储,还是那群老朋友,redux,react-redux,redux-saga,redux-persist,

我主要讲为什么要用 redux-persist,如果只是用csr,构建redux项目的时候,我基本上是不会用redux-pesrist,因为我们可以通过localStroge,sessionStorage做持久化或会话级存储,但是在next.js,我开发的时候就遇到这问题,一些公共组件的数据无法存储,但每个页面都去调用又没必要,暂用资源,在next.js中经常会出现window,localStorage is not defined 等字眼 比如home页面 三大块 header homeContainer footer,a页面也是三大块 header aContainer footer,然而header,footer都是需要读取后台数据的,在访问home页面的时候可以放在home. getInitialProps中将数据请求到,然后通过_app.js中的pageProps传到header,footer等公共组件中,在此过程中可以发起一次action,将数据传递到reducer层,以后其他页面这些公共数据直接进reducer中取值即可,

5.开发中的小问题

如果出现以下警告

  chunk styles [mini-css-extract-plugin]
  Conflicting order between:
复制代码

安装webpack-filter-warnings-plugin进行webpack 配置,可以忽视掉

  webpack(config, options) {
    config.plugins.push(new FilterWarningsPlugin({ exclude: /mini-css-extract-plugin[^]*Conflicting order between:/, }))
    return config;
  },
复制代码

打包优化问题 先用@zeit/next-bundle-analyzer 分析一下 页面的包体结构 然后再进行对应的拆分 该挂cdn的挂cdn 这只是对项目的优化,一些页面性能优化 根据具体的performance分析报告 做具体代码修改

  webpack(config, options) {
    config.externals = {
      "antd": "antd",
      'react': 'React',
      'moment': 'moment',
      'react-dom': 'ReactDOM',
    }
    return config;
  },
复制代码

部署问题 next.js 打包出来的文件需放到服务器上,因为是服务端启动 需要在服务器上安装node 装个pm2 进行进程守护,生成日志,后面容易排查一些问题 具体操作步骤 node 服务器启动的端口3000 nginx 在做一层代理 对外暴露的真实端口是8080 映射到对应的域名 用户就可以进行愉快的访问了

  upstream nextjs {
      server 127.0.0.1:3000;
      keepalive 64;
  }
  server {
      listen      8080;
      server_name 10.37.0.113;
      location / {
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Nginx-Proxy true;
      proxy_cache_bypass $http_upgrade;
      proxy_pass http://nextjs; #反向代理
  }
复制代码

6.结语

因某些原因业务代码不能进行显示,只能将大体架构进行显示,这次用next,js开发前前后后也将近一个月,学习的挺多,尤其是向node端延伸方面,如最新的next.js8.1版本,已经推出了与servesless结合,now等构建方案,learning...

github地址 github.com/tanzhiling/…

转载于:https://juejin.im/post/5cc00862f265da038f77443e

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值