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

Next.js踩坑入门系列

个人对于脚手架的UI有一种执念,如果搭建出来就是一个首页+a标签跳转,实在不是我这个处女座的风格,因此第二步我就想引用UI框架 —— ant-design,相信很多使用react的开发者用的也都是这个UI框架吧。因为以前自己在配制的时候也经常采坑,所以还是在这里记录一下~

安装依赖

既然是安装ant-design,那么这两个东西肯定是不能少的,一个是antd另一个就是antd官方的按需加载babel插件babel-plugin-import。

// 安装依赖
yarn add antd babel-plugin-import 
复制代码

因为现在开发环境大部分过渡到ES6/ES7语法了,因此还需要安装一个babel的装饰器转化插件babel-plugin-transform-decorators-legacy,说实话这个插件具体是干啥的我还真没太仔细看,不过装上它在babel里配置就可以使用antd了。

当然还有其他方法,我这里只是使用了这一种方法~

// 根目录新建.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'],还是那句话,我不理解,以后再深入研究一下,目前目的是可用~但是配置方案查到了就在这里写一下。

// 安装依赖
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试试效果,效果是下面这样:

额,果然没这么简单,这又咋的了,也没有任何报错,也没有任何提示,显而易见就是样式没加载进来吧。。。继续查,OK,明白了,其实antd的样式已经有了,只不过在页面上没被引进来。为什么这么说呢?看下面两幅图:

可以看出来,第一个就是渲染出来的页面head标签里没有任何的CSS样式,第二个就是antd的样式文件已经被打包放进.next文件夹的static文件夹里面了。
原因找到了,接下来就是解决问题了

Next.js Head组件

解决问题就是我们需要把那个style.css放到页面里,但是我翻遍了整个工程目录,都没有找到正常React SPA的那个index.html,尴尬了,有问题还是得找官方文档啊,查完过后发现了这个东西,Head,想看具体的可以点进去看官网,写的挺详细的~,就是我们可以使用这个head组件来为我们的页面添加head信息。

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

// /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,组件内部使用下面这种形式来修改样式

 <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的,大家感兴趣可以去看官方文档,写的真的很不错。

留坑

以前我在用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做准备~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值