webpack mini-css-extract-plugin =>在单个条目上输出多个css文件

sirbozc5  于 2022-12-04  发布在  Webpack
关注(0)|答案(3)|浏览(249)

我如何为我的 gutenberg 块设置webpack来提取多个css文件,并根据样式表的名称捆绑这些文件。
Zack Gordon在Webpack 3中使用了Extract Text Plugin,这很好用。但是在Webpack 4中我不得不切换到mini-css-extract-plugin,在这个插件中我不能再让这个插件工作了。
请看下面我的当前设置,这样你就可以看到我正在尝试做什么。
这是我的项目文件夹:

Plugin folder
|-- [src]
|   |-- [block1]
|   |   |-- block1.js
|   |   |-- style.scss
|   |   `-- editor.scss
|   |-- [block2]
|   |   |-- block2.js
|   |   |-- style.scss
|   |   `-- editor.scss
|   `-- index.js
`-- [build]
    |-- index.js
    |-- style.build.css
    `-- editor.build.css

在block1.js/block2.js中:

import './style.scss'
import './editor.scss'

在index.js中:

import './block1'
import './block2'

在webpack.config.js中:

const defaultConfig = require("./node_modules/@wordpress/scripts/config/webpack.config");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    ...defaultConfig,
    optimization: {
        ...defaultConfig.optimization,
        splitChunks: {
            cacheGroups: {
                style: {
                    name: 'style',
                    test: /style\.s?css$/,
                    chunks: 'all',
                    enforce: true,
                },
                editor: {
                    name: 'editor',
                    test: /editor\.s?css$/,
                    chunks: 'all',
                    enforce: true,
                },
            },
        },
    },
    plugins: [
        ...defaultConfig.plugins,
        new MiniCssExtractPlugin({
            filename: 'blocks.[name].build.css'
            }),
    ],
    module: {
        ...defaultConfig.module,
        rules: [
            ...defaultConfig.module.rules,
            {
                test: /\.s?css$/,
                exclude: /node_modules/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'sass-loader'
                ],
            },

        ]
    },
};

预期输出:

[build]
|-- blocks.editor.build.css
|-- index.js
|-- blocks.style.build.css

电流输出:

[build]
|-- blocks.editor.build.css
|-- editor.js
|-- index.js
|-- blocks.style.build.css
|-- style.js
`-- (...and indentical map files)

当前的设置会产生两个我不需要的额外的js文件(style.js/editor.js),但最大的问题是,它也会导致块无法在WordPress中加载。当我不使用splitChunks时,它会加载,但所有的css都捆绑在一个文件中...我需要两个。
正在比较:没有splitChunks的index.js:

/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = "./src/index.js");
/******/ })

具有分割区块的index.js:

/******/    // add entry module to deferred list
/******/    deferredModules.push(["./src/index.js","editor","style"]);
/******/    // run deferred modules when ready
/******/    return checkDeferredModules();
/******/ })
wz1wpwve

wz1wpwve1#

看到我的评论,改变了我的设置,现在它的工作:(好吧,它不再是一个单一的条目,但嘿:-)
项目文件夹:

Plugin folder
|-- [src]
|   |-- [block1]
|   |   |-- block1.js
|   |   |-- style.scss
|   |   `-- editor.scss
|   |-- [block2]
|   |   |-- block2.js
|   |   |-- style.scss
|   |   `-- editor.scss
|   `-- index.js
|   `-- css.js
`-- [build]
    |-- index.js
    |-- style.build.css
    `-- editor.build.css

在css.js中:

import './block1/style.scss'
import './block1/editor.scss'
import './block2/style.scss'
import './block2/editor.scss'

在webpack.config.js中:

const defaultConfig = require("./node_modules/@wordpress/scripts/config/webpack.config");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    ...defaultConfig,
    entry: {
        index: path.resolve( process.cwd(), 'src', 'index.js' ),
        css: path.resolve( process.cwd(), 'src', 'css.js' ),
    },
    optimization: {
        ...defaultConfig.optimization,
        splitChunks: {
            cacheGroups: {
                style: {
                    name: 'style',
                    test: /style\.s?css$/,
                    chunks: 'all',
                    enforce: true,
                },
                editor: {
                    name: 'editor',
                    test: /editor\.s?css$/,
                    chunks: 'all',
                    enforce: true,
                },
            },
        },
    },
    plugins: [
        ...defaultConfig.plugins,
        new MiniCssExtractPlugin({
            filename: 'blocks.[name].build.css'
            }),
    ],
    module: {
        ...defaultConfig.module,
        rules: [
            ...defaultConfig.module.rules,
            {
                test: /\.s?css$/,
                exclude: /node_modules/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'sass-loader'
                ],
            },

        ]
    },
};

输出生成文件夹:

[build]
|-- blocks.editor.build.css
|-- index.js
|-- blocks.style.build.css
|-- style.js (ignore)
|-- editor.js (ignore)
|-- css.js (ignore)
`-- (...and indentical map files)
bttbmeg0

bttbmeg02#

实际上,您不需要多个条目。使用当前解决方案中的配置,您只缺少一个选项来使其按您希望的方式工作。filename选项必须在块名称的基础上动态设置。

plugins: [
    new MiniCssExtractPlugin({
      filename: ({ chunk }) => `${chunk.name.replace('/js/', '/css/')}.css`,
    })
],

这将为每个块创建一个.css文件。由于您已经有了styleeditor块,它将创建style.css和“editor.css”,每个块都有相应的css或scss导入到js文件中。
检查文件
它看起来像这样,唯一的增加是filenameMiniCssExtractPlugin选项的更改,以及css条目的删除。

module.exports = {
    ...defaultConfig,
    entry: {
        index: path.resolve( process.cwd(), 'src', 'index.js' ),
    },
    optimization: {
        ...defaultConfig.optimization,
        splitChunks: {
            cacheGroups: {
                style: {
                    name: 'style',
                    test: /style\.s?css$/,
                    chunks: 'all',
                    enforce: true,
                },
                editor: {
                    name: 'editor',
                    test: /editor\.s?css$/,
                    chunks: 'all',
                    enforce: true,
                },
            },
        },
    },
    plugins: [
        ...defaultConfig.plugins,
        new MiniCssExtractPlugin({
          filename: ({ chunk }) => `${chunk.name.replace('/js/', '/css/')}.css`,
          // chunkFilename: "[name].css"
        })
    ],
    module: {
        ...defaultConfig.module,
        rules: [
            ...defaultConfig.module.rules,
            {
                test: /\.s?css$/,
                exclude: /node_modules/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'sass-loader'
                ],
            },

        ]
    },
};
vfh0ocws

vfh0ocws3#

应用发布的答案,我设计了一个配置,允许包scss文件共享相同的名称,并将它们分组在<name>.css中,其余的分组在styles.css中。
我在配置文件的开头定义了一个数组,其中包含所有CSS块名称组。

const chucksCSS = ['style', 'editor'];

BornieRaba帖子中,我定义了一个新条目,允许使用名称“main”作为块名。

module.exports = {
...defaultConfig,
  entry: {
    index: './src/index.jsx',
  },
...defaultConfig,
}

每个CSS群组的属性都会在cacheGroups设定中解构。

...
optimization: {
    splitChunks: {
      cacheGroups: {
        ...chucksCSS.map((name) => ({
          name,
          test: new RegExp(`${name}\\.s?css$`),
          chunks: 'all',
          enforce: true,
        })).reduce((acc, current) => {
          acc[current.name] = current;
          return acc;
        }, {}),
      },
    },
  },
...

要完成添加插件MiniCssExtractPlugin和配置filename以分配块名称,并将默认块名称重命名为style,例如以指定的名称生成文件。

plugins: [
    ...
    new MiniCssExtractPlugin({
      // Chunk name 'index' is set by entry point where is not recognized by any cacheGroup
      filename: ({ chunk }) => `${chunk.name === 'index' ? 'styles' : chunk.name}.css`,
    }),
    ...
],

它看起来像这样

const chucksCSS = ['style', 'editor'];

module.exports = {
    ...defaultConfig,
    entry: {
        index: './src/index.jsx',
    },
    optimization: {
        ...defaultConfig.optimization,
        splitChunks: {
            cacheGroups: {
                ...chucksCSS.map((name) => ({
                     name,
                    test: new RegExp(`${name}\\.s?css$`),
                    chunks: 'all',
                    enforce: true,
                })).reduce((acc, current) => {
                  acc[current.name] = current;
                  return acc;
                }, {}),
            },
        },
    },
    plugins: [
        ...defaultConfig.plugins,
        new MiniCssExtractPlugin({
          // Chunk name 'index' is set by entry point where is not recognized by any cacheGroup
          filename: ({ chunk }) => `${chunk.name === 'index' ? 'styles' : chunk.name}.css`,
        })
    ],
    module: {
        ...defaultConfig.module,
        rules: [
            ...defaultConfig.module.rules,
            {
                test: /\.s?css$/,
                exclude: /node_modules/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'sass-loader'
                ],
            },

        ]
    },
};

相关问题