next.js小结

Next.js

关于最近next.js开发总结javascript

1.初始化demo案例

nextjs.frontendx.cn/docs/#安装css

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

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

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

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 这是没问题的,可是背景图片引入的时候有时候会没法解析,但有时候又能够,另外就是在开发模式下,新路由页面不能及时加载样式文件渲染,再次刷新就能够了,固然在生产环境中,这个问题是没有的react

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.jswebpack

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文件也要作对应更改nginx

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

4.数据请求

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

  • 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,github

我主要讲为何要用 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中取值便可,web

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/…

相关文章
相关标签/搜索