从 SCSS 中提取 CSS 并在 React 应用程序中延迟延迟加载
Extract CSS from SCSS and deferred lazy load in React app
我有几个 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"
]
}
]
}
}
然后我在我的应用程序中尝试了 dynamically importing 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]
.[= 时如何引用它21=]
TLDR:有没有一种好的方法既可以提取 css 又可以稍后将引用的 CSS 包导入延迟加载?我不受 mini-css-extract-plugin
.
的束缚
编辑:创建了一个 mini-css-extract-plugin
问题 here。
对不起我的理解,
您可能只制作两个不同的 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>
}
在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
是可行的,尽管我认为无论如何在这种情况下都是如此
我的解决方案最终使用了 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 主题文件,我想将其提取到 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"
]
}
]
}
}
然后我在我的应用程序中尝试了 dynamically importing 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]
.[= 时如何引用它21=]
TLDR:有没有一种好的方法既可以提取 css 又可以稍后将引用的 CSS 包导入延迟加载?我不受 mini-css-extract-plugin
.
的束缚
编辑:创建了一个 mini-css-extract-plugin
问题 here。
对不起我的理解,
您可能只制作两个不同的 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>
}
在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
是可行的,尽管我认为无论如何在这种情况下都是如此
我的解决方案最终使用了 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>