Next.js是一个轻量级的 React 服务端渲染应用框架。还是头一回用这种服务端渲染的框架,之所以会做服务端渲染,是因为这个项目是一个纯展示性的品牌官网,所以需要为SEO考虑,由于SPA对搜索引擎并不友好,所以选择了Next.js来进行服务端多页渲染。使用了之后发现,其实从编码的思维来看,其实还是组件式的单页思想。
这里想拿出来说说的是在这个项目中,我们开启了css-module,但在后来的开发过程中需要引入其他组件,却发现样式无法加载出来,这里简单记录一下在解决这个问题的一个过程。
这里我们以Tab组件为例,我们使用的是rc-tabs,除了需要引入Tab组件之外,还需要引入其对应的样式,
引入css文件:
import 'rc-tabs/dist/rc-tabs.css';
这时发现引入的样式并没有生效,这是由于开启了css-module,webpack会为编译之后的class类名加上哈希值,也就意味着,组件对应样式的class类名发生了变化,但是组件DOM对应的class名并不会变化,这就是样式无法正常使用的原因。所以解决方案是,在过css-module编译时应该忽略组件自带的样式。找到了问题所在,解决之。
修改配置文件,next.config.js的配置如下:
const withCss = require('@zeit/next-css');
const withLess = require('@zeit/next-less');
const path = require('path');
const cssLoaderGetLocalIdent = require('css-loader/lib/getLocalIdent.js');
module.exports = withLess(
withCss({
exportPathMap() {
return {
'/': { page: '/' },
'/about': { page: '/about' },
'/article': { page: '/article' },
'/articleList': { page: '/articleList' },
'/business': { page: '/business' },
'/course': { page: '/course' },
};
},
cssModules: true,
cssLoaderOptions: {
localIdentName: '[local]___[hash:base64:5]',
getLocalIdent: (context, localIdentName, localName, options) => {
const hz = context.resourcePath.replace(context.rootContext, '');
console.log(hz);
if (/node_modules/.test(hz)) {
return localName;
}
return cssLoaderGetLocalIdent(context, localIdentName, localName, options);
},
},
distDir: './.next',
webpack: (config, options) => {
// Fixes npm packages that depend on `fs` module
config.node = {
fs: 'empty',
};
config.resolve.alias['@'] = path.join(__dirname);
return config;
},
}),
);
主要看这里:其实就是对CSSLoader配置了一下,在getLocalIdent中忽略了对node_modules下的样式的module化处理~