Nextjs 外部 css 不更新客户端页面转换

Nextjs external css not updating on client side page transitions

我还是 nextjs 的新手,所以我不知道这是一个错误还是我错误地实现了它。

我使用本指南成功提取了所有 scss 文件: https://github.com/zeit/next-plugins/tree/master/packages/next-sass

使用服务器端渲染时一切正常。外部 css 文件得到正确更新和应用,但一旦我进行客户端页面转换,新的 scss 导入不会注入外部 css 文件。我也不想在初始页面加载时预取每个 scss 文件,它应该在服务器端路由和客户端路由上动态获取和更新外部文件。

我的next.config.js

const getRoutes = require('./routes');
const path = require('path');
const withSass = require('@zeit/next-sass');

module.exports = withSass({
  exportPathMap: getRoutes,
  // useFileSystemPublicRoutes: false,
  cssModules: true,
  cssLoaderOptions: {
    importLoaders: 1,
    localIdentName: "[local]___[hash:base64:5]",
  },
})

示例组件

import { Fragment } from 'react';
import Main from '../components/main';
import style from '../styles/pages/parkett.scss';

const Parkett = () => 
  <Fragment>
    <section className={`section ${style.sec_two_parkett}`}>
      <div className={`sec_text ${style.sec_two_text}`}>
        <h2 className="didonesque_headline">Detailiert</h2>
        <p className="normal_text">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
      </div>
    </section>
    <section className={`section ${style.sec_three_parkett}`}>
      <div className={`sec_text ${style.sec_three_text}`}>
        <h2 className="didonesque_headline">Erstaunlich</h2>
        <p className="normal_text">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.</p>
      </div>
    </section>
  </Fragment> 

export default () => 
  <Main 
    title="parkett" 
    component={<Parkett />} 
    links={['Treppe', 'Moebel', 'Innenausbau']}
    />

您好,我建议使用 styled-jsx-css-loader for loading css into jsx it work fine for me and sass loader 将 sass 转换为 css,您可以像这样在 next.config.js 文件中链接它们:

config.module.rules.push({
      test: /\.scss$/,
      use: [
        {
          loader: 'emit-file-loader',
          options: {
            name: 'dist/[path][name].[ext].js',
          },
        },
        {
          loader: 'babel-loader',
          options: {
            babelrc: false,
            extends: path.resolve(__dirname, './.babelrc'),
          },
        },
        'styled-jsx-css-loader',
        // optional if you wanna purify css if you are using bootstrap or a huge css lib
        // {
        //   loader: 'css-purify-webpack-loader',
        //   options: {
        //     includes: [
        //       './pages/*.js',
        //       './components/**/*.js',
        //       './containers/**/*.js',
        //     ],
        //   },
        // },
        {
          loader: 'sass-loader',
          options: {
            sourceMap: dev,
          },
        },
      ],
    });

然后像这样导入 sass:

import commonStyle from '../styles/common/index.scss';
<style jsx global>
 {commonStyle}
</style>

将以下内容添加到我的 _app.js 的顶部解决了我的问题:

// This is a bit of a hack to ensure styles reload on client side route changes.
// See: https://github.com/zeit/next-plugins/issues/282#issuecomment-480740246
if (process.env.NODE_ENV !== 'production') {
  Router.events.on('routeChangeComplete', () => {
    const path = '/_next/static/css/styles.chunk.css'
    const chunksSelector = `link[href*="${path}"]`
    const chunksNodes = document.querySelectorAll(chunksSelector)
    const timestamp = new Date().valueOf()
    chunksNodes[0].href = `${path}?${timestamp}`
  })
}

请参阅 next-plugins 存储库中的以下问题了解一些背景信息: