Next.js踩坑入門系列(二)— 添加Antd && CSS

Next.js踩坑入門系列

我的對於腳手架的UI有一種執念,若是搭建出來就是一個首頁+a標籤跳轉,實在不是我這個處女座的風格,所以第二步我就想引用UI框架 —— ant-design,相信不少使用react的開發者用的也都是這個UI框架吧。由於之前本身在配製的時候也常常採坑,因此仍是在這裏記錄一下~css

安裝依賴

既然是安裝ant-design,那麼這兩個東西確定是不能少的,一個是antd另外一個就是antd官方的按需加載babel插件babel-plugin-import。html

// 安裝依賴
yarn add antd babel-plugin-import 
複製代碼

由於如今開發環境大部分過渡到ES6/ES7語法了,所以還須要安裝一個babel的裝飾器轉化插件babel-plugin-transform-decorators-legacy,說實話這個插件具體是幹啥的我還真沒太仔細看,不過裝上它在babel裏配置就可使用antd了。node

固然還有其餘方法,我這裏只是使用了這一種方法~react

// 根目錄新建.babelrc文件
{
  "presets": ["next/babel"],
  "plugins": [
    "transform-decorators-legacy",
    [
      "import",
      {
        "libraryName": "antd",
        "style": "css"
      }
    ]
  ]
}
複製代碼

配置好了,咱們來試一試,yarn dev啓動項目,額,一大堆報錯,爲啥呢?好像是服務端渲染的時候node端的問題吧,具體的我也不太清楚由於是入門有大神指導具體的能夠留言教教小弟一下,不勝感激。反正查唄,由於本來在其餘腳手架配置的時候須要在webpack裏配置一些東西嘛,這個怎麼可能沒有配置文件呢?
固然有了,只不過更名了,叫作next.config.js了,上網查了一下,官方的解決方案就是引入一下next-css這個包,而後require.extensions['.css'],仍是那句話,我不理解,之後再深刻研究一下,目前目的是可用~可是配置方案查到了就在這裏寫一下。webpack

// 安裝依賴
yarn add @zeit/next-css

// 根目錄下建立next.config.js,內容以下

/* eslint-disable */
const withCss = require('@zeit/next-css');

// fix: prevents error when .css files are required by node
if (typeof require !== 'undefined') {
  require.extensions['.css'] = (file) => {}
}

module.exports = withCss();
複製代碼

好了,如今咱們在啓動,就沒有報錯了,畢竟是官方解決方案,仍是好使~把首頁的a標籤換成antd的button試試效果,效果是下面這樣:git

額,果真沒這麼簡單,這又咋的了,也沒有任何報錯,也沒有任何提示,顯而易見就是樣式沒加載進來吧。。。繼續查,OK,明白了,其實antd的樣式已經有了,只不過在頁面上沒被引進來。爲何這麼說呢?看下面兩幅圖:

能夠看出來,第一個就是渲染出來的頁面head標籤裏沒有任何的CSS樣式,第二個就是antd的樣式文件已經被打包放進.next文件夾的static文件夾裏面了。
緣由找到了,接下來就是解決問題了

Next.js Head組件

解決問題就是咱們須要把那個style.css放到頁面裏,可是我翻遍了整個工程目錄,都沒有找到正常React SPA的那個index.html,尷尬了,有問題仍是得找官方文檔啊,查完事後發現了這個東西,Head,想看具體的能夠點進去看官網,寫的挺詳細的~,就是咱們可使用這個head組件來爲咱們的頁面添加head信息。github

// /pages/index.js
import React, { Fragment } from 'react';
import { Button } from 'antd';
import Link from 'next/link';
import Head from 'next/head';
const Home = () => (
  <Fragment>
    <Head>
      <meta name='viewport' content='width=device-width, initial-scale=1' />
      <meta charSet='utf-8' />
      <title>Next-Antd-Scafflod</title>
      <link rel='stylesheet' href='/_next/static/style.css' />
    </Head>
    <Fragment>
      <h1>我是Next的首頁</h1>
      <Link href='/userList'>
        <Button type='primary'>用戶列表頁</Button>
      </Link>
    </Fragment>
  </Fragment>
);
export default Home;
複製代碼

OK,到如今而言是否是有點NB了,O(∩_∩)O哈哈~,真的是採坑系列啊,配置一個UI組件就這麼麻煩。估計接下來有坑可踩啦!

抽離Head爲Layout

通常的應用都會有個菜單Menu導航條之類的嘛,因此頁面就作頁面的事情,head放裏面感受怪怪的,仍是按照習慣把Head抽離出來當成一個高級父組件吧。我的習慣,就新建了一個components文件夾,裏面新建Layout.js。web

// /components/Layout.js
import Head from 'next/head';
export default ({ children }) => (
  <div>
    <Head>
      <meta name='viewport' content='width=device-width, initial-scale=1' />
      <meta charSet='utf-8' />
      <title>Next-Antd-Scafflod</title>
      <link rel='stylesheet' href='/_next/static/style.css' />
    </Head>
    <style jsx global>{`
      body {
      }
    `}</style>
    {children}
  </div>
);
複製代碼
// /pages/index.js
import React, { Fragment } from 'react';
import { Button } from 'antd';
import Link from 'next/link';
import Layout from '../components/Layout';
const Home = () => (
  <Layout>
    <Fragment>
      <h1>Hello Next.js</h1>
      <Link href='/userList'>
        <Button type='primary'>用戶列表頁</Button>
      </Link>
    </Fragment>
  </Layout>
);
export default Home;
複製代碼

講到這裏,整個Antd的配置基本就完成了吧,哈哈,沒想到講個antd配置能寫這麼多,真實厲害了~既然UI框架嘛,順便我就把CSS也寫了吧。看Next官網能夠很明確瞭解到它推崇的是css-in-js,具體連接你們請點這裏Next Css-in-Js,說白了,能夠把它理解成用類Vue的形式寫React,組件內部使用下面這種形式來修改樣式redux

<style jsx>{`
      p {
        color: blue;
      }
      div {
        background: red;
      }
      @media (max-width: 600px) {
        div {
          background: blue;
        }
      }
    `}</style>
    <style global jsx>{`
      body {
        background: black;
      }
    `}</style>
複製代碼

這裏須要注意的是,組件內部的css並非子組件繼承父組件,就是組件內部使用,若是想要子組件繼承父組件樣式,須要將style jsx改爲style global jsx這種形式,說實話,越看越像Vue,^_^ 除了上面那種官方推薦的方法之外,還有其餘不少種Css-in-Js的樣例,其中我的仍是比較推薦styled-components的,你們感興趣能夠去看官方文檔,寫的真的很不錯。bash

留坑

之前我在用antd的時候,都會根據重置一下自帶配色以及一些其餘的默認屬性,這裏我才用了之前的方式結果出錯了,之前的方式是依賴babel-plugin-import,在babelrc文件裏將"style": "css"改爲"style": true,這樣,babel-plugin-import會加載.less文件,而後在webpack裏面配置less-loader的modifyVars變量進行覆蓋:

config.module.rules.push({
        test: /\.less$/,
        use: [
          {
            loader: "style-loader"
          }, {
              loader: "css-loader"
          }, {
              loader: "less-loader",
              options: {
                sourceMap: true,
                modifyVars: AntdTheme
              }
          }
        ]
    })
複製代碼

可是在next框架裏若是使用less方式引入服務端渲染會過不去,這算是一個坑?仍是有解決辦法我沒查到,總之暫時這樣吧,改的話其實也能夠改,用下面這種方式就行了,無關痛癢~

<style jsx global>{`
      .ant-btn-primary {
        background-color: #ec6a00
      }
    `}</style>
複製代碼

你看,也能夠改,不過我的以爲antd的配色仍是挺不錯的,哈哈,就別改了。我認爲官方後續會加強的吧!

可能官方早就有解決方案了吧,只不過我仍是不太會用?由於我看除了next-css包之外還提供了next-less包,這個包應該就是用來加載less文件的吧我看了一下這個包還支持css-modules,不過我配置了一下仍是不太對,而且我對目前這種寫法還以爲挺舒服的,就很少浪費時間了,你們感興趣的能夠攻克一下,解決了能夠留言個地址給我,萬分感謝~

總結

第二篇寫完了,本來寫以前覺得很簡單的兩下就完事了,沒想到中間踩了這麼多坑,由於我是一邊搭項目一邊寫的,因此我的認爲仍是比較詳細的,很是適合新手。像我這麼良心的寫手是否是不多了,哈哈。
代碼地址 下一篇:準備好好講講路由而後簡單的整理一下項目骨架爲了接下來的redux作準備~

相關文章
相關標籤/搜索