从 SCSS 中提取 CSS 并在 React 应用程序中延迟延迟加载



我有几个SCSS主题文件,我想提取到CSS文件中,然后将它们加载到页面中。我希望能够使用contenthash进行长期缓存。

由于我使用的是 Webpack 4,所以我也使用 mini-css-extract-plugin。我开始在我的 webpack 配置中创建 splitChunks。

// webpack.config.js
module.exports = {
  plugins: [
      new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: "[name].[contenthash].css",
      chunkFilename: "[id].[contenthash].css"
    })
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        'vendor': {
            // custom commons chunk for js
        },
        'theme-a': {
            test: /theme-a.scss/,
        },
        'theme-b': {
            test: /theme-b.scss/,
        },
        // more themes
      }
    }
  }
  module: {
    rules: [
      {
        test: /.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          "sass-loader"
        ]
      }
    ]
  }
}

然后,我尝试在我的应用程序中动态导入css:

// app.js
class App extends React.Component {
  // constructor
  login(themeName) {
    import(/* webpackChunkName: "`${themeName}`" */ `./path/to/${themeName}.scss`).then(theme => {
      // do something with `theme`
    }
  }
  // other stuff
}

我需要能够在login()中动态加载该 css 文件,我只是不确定当它有生成的[contenthash]时如何引用它。

TLDR:有没有一种好方法可以提取 css 并将引用的 CSS 包导入到延迟加载中?我与mini-css-extract-plugin无关.

编辑:在此处创建了一个mini-css-extract-plugin问题。

我的解决方案最终使用了extract-text-webpack-plugin.我的配置现在看起来像这样:

// webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ExtractThemeA = new ExtractTextPlugin({ filename: 'themeA.[hash].css', allChunks: true});
module.exports = {
  plugins: [
      ExtractThemeA,
      // more plugins for other css files
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        // Note: No changes to splitChunks
        'vendor': {
            // custom commons chunk for js
        }
    }
  }
  module: {
    rules: [
      {
        test: /theme-a.scss$/,
        use: ExtractThemeA.extract([ 'css-loader', 'sass-loader' ])
      },
      // more module rules for each css file needed
    ]
  }
}

然后,这些块在我的HtmlWebpackPlugin中按文件名可用:

<!-- HtmlWebpackPlugin Template -->
<script>
// provides me with an array of file name strings
var themesManifest = <%= htmlWebpackPlugin.files.css %>
</script>

对不起,我的理解失误,

您可能只制作两个不同的 scss-文件并根据需要导入它们。 theme.scss admin.scss或类似

这就是我现在在 React 中做 scss 的方式

在应用程序中.js

import styles from '../../stylesheet/main.scss'
// could be as well
import styles1 from '../../stylesheet/theme.scss' // some file
import styles2 from '../../stylesheet/admin.scss' // some other file
const App = () => {
  <div className={styles.action_feed} >{ content }</div>
} 

在main.scss中

.action_feed {
  position: fixed;
  width: 350px;
  height: auto;
  max-height: 100%;
  max-width: 100%;
  top: 0;
  left: 0;
  z-index: 9999;
}

我想你也可以这样做

const themeName = 'main'
import(`./stylesheet/${themeName}.scss`, (css) => {
  // meaby set this to state? not quite sure how should properly handle
  // dynamically imported css
  this.setState({ css: css.action_feed })
  // or possible this way. I have done some non-React dom manipulation
  // this way before
  document.querySelector('body').classList.add(css.action_feed)
})
<div className={this.state.css}>{ content }</div>

您可能还应该查看 React 的新 Refs API。它可能会给你一些很好的灵活性,为所需的元素提供className-attr。

设置为splitChunks.chunks all工作,尽管我认为在这种情况下无论如何

最新更新