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

从SCS中提取CSS并在React应用程序中延迟延迟加载,css,reactjs,webpack,lazy-loading,Css,Reactjs,Webpack,Lazy Loading,我有几个SCSS主题文件,我想提取到CSS文件,然后加载到页面中。我希望能够使用contenthash进行长期缓存 因为我在使用Webpack4,所以我也在使用。我开始在我的网页配置中创建一个分割块 // webpack.config.js module.exports = { plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.o

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

因为我在使用Webpack4,所以我也在使用。我开始在我的网页配置中创建一个分割块

// 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包导入延迟加载?我不喜欢
迷你css提取插件

编辑:创建了一个
迷你css提取插件
问题。

很抱歉我没有理解

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

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

在App.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>
} 
我想你也可以这样做

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>
const themeName='main'
导入(`./stylesheet/${themeName}.scss`,(css)=>{
//meaby将此设置为状态?不太确定应如何正确处理
//动态导入的css
this.setState({css:css.action_feed})
//或者可能是这样。我做了一些非反应dom操作
//以前是这样吗
document.querySelector('body').classList.add(css.action\u提要)
})
{content}
您可能还应该查看React的新Refs API。它可能会为您提供一些很好的灵活性,以便将
className
-attr指定给所需的元素


设置为
splitChunks.chunks
to
all
可以工作,尽管我认为在这种情况下,我的解决方案最终使用了。我的配置现在如下所示:

// 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
    ]
  }
}
然后,这些块在my
HtmlWebpackPlugin
中按文件名提供:

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

//为我提供一个文件名字符串数组
变量themesManifest=

我并不担心我的JS不会被分块,而是担心这些单独的主题css文件。我需要将这些文件解压缩并加载到
login()
我很感谢您的回复,但同样,这不是我想要的。我需要提取css(用于http缓存目的)并动态注入
login()
上的页面。
<!-- HtmlWebpackPlugin Template -->
<script>
// provides me with an array of file name strings
var themesManifest = <%= htmlWebpackPlugin.files.css %>
</script>