zp1112 / blog

地址
http://issue.suzper.com/
36 stars 3 forks source link

nextjs+react+antd踩坑之旅 #22

Open zp1112 opened 6 years ago

zp1112 commented 6 years ago

Nextjs

继折腾了一宿没折腾好react-ssr,被react16和react-router4折磨半死后,毅然决定选择尝试Nextjs。 关于nextjs的大多教程,在这里

less和cssModule

next中使用less,需要配置next.config.js使用相应的plugin,否则会报错。教程中说使用next-less

const withLess = require('@zeit/next-less')
module.exports = withLess()

如你所愿,报错了,

.bezierEasingMixin();Inline JavaScript is not enabled. Is it set in your options?

这是less3的一个bug,需要配置option,修改next.config.js

const withLess = require('@zeit/next-less')
module.exports = withLess({
  cssModules: true, // 在项目中使用cssModule
  lessLoaderOptions: {
    javascriptEnabled: true // 
  },
})

nextjs把css都打包到一个文件下,会存在命名冲突,而使用css module可以实现scope效果 此时,可以正常使用less和css module了。

引入antd.less

pages/_app.js引入antd的样式 import "antd/dist/antd.less";,如你所愿,报错了,因为antd没有使用css module,我们在spa项目中配置webpack的时候通常是配置两种less-loader,一种是include src,一种是exclude node_module

然而查看next-less的源码,发现并没有做这种处理,因此需要手动修改next-less,将下面这部分复制,添加到

// 省略....
// 将此处的cssModules删除,添加一个参数antdLessLoaderOptions, 传参时将cssModules放到antdLessLoaderOptions和lessLoaderOptions里面
const {
        cssLoaderOptions,
        lessLoaderOptions = {},
        antdLessLoaderOptions = {}
      } = nextConfig
// 省略.....
options.defaultLoaders.less = cssLoaderConfig(config, extractCSSPlugin, {
        cssModules: lessLoaderOptions.cssModules,
        cssLoaderOptions,
        dev,
        isServer,
        loaders: [
          {
            loader: 'less-loader',
            options: lessLoaderOptions
          }
        ]
      })

      config.module.rules.push({
        test: /\.less$/,
        exclude: [/node_modules/], // 处理非antd的less
        use: options.defaultLoaders.less
      })
// 添加一个less-loader
      options.defaultLoaders.less = cssLoaderConfig(config, extractCSSPlugin, {
        cssModules: antdLessLoaderOptions.cssModules,
        cssLoaderOptions,
        dev,
        isServer,
        loaders: [
          {
            loader: 'less-loader',
            options: antdLessLoaderOptions
          }
        ]
      })

      config.module.rules.push({
        test: /\.less$/,
        include: [/node_module/], // 专门处理antd的less和node_module其他的库的less
        use: options.defaultLoaders.less
      })

修改next.config.js

const withLess = require('@zeit/next-less')
module.exports = withLess({
  cssLoaderOptions: {
    localIdentName: '[local]_[hash:base64:5]', // 此处是为了可以使生成的css module可辨识
  },
  lessLoaderOptions: {
    cssModules: true,
    javascriptEnabled: true
  },
  antdLessLoaderOptions: {
    javascriptEnabled: true
  }
})

。。。。。。。。。。。。。。分界线。。。。。。。。。。。。。。

开发过程中发现了一个问题,就是cssmodule里面定义的css属性,会被antd的样式覆盖,原因很简单,由于在_app.js引入antd.less的时候在引入RootContainer之后,因此会覆盖,解决方法自然是将antd.less放在container组件之前引入。放在import最顶部即可

import "antd/dist/antd.less";
import RootContainer from '../components/RootContainer';

boom!!!大功告成。

dreamHeroK commented 5 years ago

next官方example使用antd

ycjcl868 commented 5 years ago

不建议这样改,还是会全量打入 style 和组件 js