停止 extract-css-chunks-webpack-plugin 组合所有 CSS

Stop extract-css-chunks-webpack-plugin from combining all CSS

我正在使用 Webpack 4 构建一个带有快速后端的简单网站。现在我正在实现一个自定义元素,我遇到了一个关于阴影 DOM 的问题。

问题如下:我所有的 SCSS 都被合并到一个 CSS 输出文件中。我需要它保持独立,以便在连接元素时可以将自定义元素的样式动态添加到阴影 DOM。

我正在使用 extract-css-chunks-webpack-plugin(我认为问题在于)、css-loaderpostcss-preset-envsass-loader 来处理所有 SCSS app/site。

到目前为止,我所有的搜索只是把我带到了与我需要的完全相反的地方(人们试图结合他们的 SCSS)。

我知道我可以单独构建自定义元素,然后在构建后将其导入项目,但这意味着管理两个构建环境,然后必须对两者进行版本控制——这似乎是一个很大的开销.

项目的文件夹结构如下:

root
--src/
----assets/
------js/
--------main.js
------scss/
--------main.scss
------web-components/
--------contact-modal.js
--------scss/
----------modal.scss

我目前的webpack开发配置如下:

    **omitted**

    module: {
        rules: [{
                test: /\.(scss)$/,
                use: [{
                        loader: ExtractCssChunksPlugin.loader,
                        options: {
                            hot: true,
                        }
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true,
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            indent: 'postcss',
                            plugins: () => postcssEnv(),
                            sourceMap: 'inline',
                        },

                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: true
                        }
                    }
                ]
            },

    **omitted**

    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            template: 'src/views/pages/index.ejs',
            filename: 'index.html',
        }),
        new ExtractCssChunksPlugin({
            filename: 'assets/css/[name].css',
            chunkFilename: 'assets/css/[id].css',
        })
    ]

如果有更好的方法来使用我忽略的自定义元素,我将不胜感激任何反馈。

提前谢谢你。

编辑:

如果说明我在 contact-modal.js 文件中导入了 modal.scss 文件,那将是有益的。

我假设 modal.scss 正在导入 main.scss?如果是这样,那么您的问题出在 Sass 编译器本身,而不是 webpack。根据 modal.scss 中的内容,您可能需要使用 @use 而不是

编辑 1:

如果你在影子 DOM 中添加你编译的 css 比方说 <style> 标签,你可以用 to-string-loader 之类的东西替换 ExtractCSSChunks 加载器.在您的 js 中,import style from "modal.scss"; 将在您可以使用的字符串中包含编译输出。

为了在仍然使用 SCSS 的同时解决我的问题(允许我使用来自 postcss-loader 的供应商前缀),我最终用 .modal 标志为我的模态 scss 添加了前缀,所以 modal.scss 变成了 main.modal.scss.

然后我编辑了我的 webpack 配置,为 scss 文件设置了两个规则:一个只影响 .scss 个文件,一个影响 .modal.scss 个文件。

然后,在我的模式中,我导入了带有普通 import style from './main.modal.scss'; 的 scss,然后将其附加到 <style></style> 元素中的阴影 DOM。

代码如下:

新 SCSS 规则

                test: /(\.modal\.scss)$/,
                use: [
                    'css-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: () => [ postcssPresetEnv() ],
                            sourceMap: 'inline'
                        }
                    },
                    'sass-loader'
                ]

修改旧 SCSS 规则

                test: /(?<!\.modal)\.scss$/,
                use: [{
                        loader: ExtractCSSChunksPlugin.loader,
                        options: {
                            hot: true,
                        }
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true,
                            importLoaders: 3
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            ident: 'postcss',
                            plugins: () => [
                                postcssPresetEnv()
                            ],
                            sourceMap: 'inline'
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: true,
                        }
                    }
                ]

在我的联系方式-modal.js文件

import CSS from './scss/main.modal.scss';

    // ... omitted ...

    connectedCallback() {

    // ... omitted ...

    const style = document.createElement('style');
    style.innerHTML = CSS.toString();
    this.shadow.appendChild(style);

    // ... omitted ...
}