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作准备~

相关文章
相关标签/搜索