關於最近next.js開發總結javascript
跟據官網操做,基本上能實現一個hellow demo,第一步已經完成java
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配置
}
})
複製代碼
默認路由是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"
}
}
複製代碼
數據請求主要分爲兩部分,一部分是客戶端請求,一部分是服務端請求,頁面初始化數據都放服務端,表單提交內容放客戶端,列表分頁首次在服務端,其後放客戶端 服務端請求next.js主要是經過getInitialProps方法獲取api數據,其內置屬性:git
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
若是出現如下警告
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; #反向代理
}
複製代碼
因某些緣由業務代碼不能進行顯示,只能將大致架構進行顯示,此次用next,js開發前先後後也將近一個月,學習的挺多,尤爲是向node端延伸方面,如最新的next.js8.1版本,已經推出了與servesless結合,now等構建方案,learning...
github地址 github.com/tanzhiling/…