Javascript 希望webpack输出到单独的.css文件,而不是合并成一个

Javascript 希望webpack输出到单独的.css文件,而不是合并成一个,javascript,reactjs,webpack,Javascript,Reactjs,Webpack,我正在使用MiniCssExtractPlugin,并且还指定了用于优化的块: splitChunks: { cacheGroups: { styles: { name: 'styles', test: /\.css$/, chunks: 'all', enforce: true,

我正在使用
MiniCssExtractPlugin
,并且还指定了用于优化的块:

splitChunks: {
            cacheGroups: {
                styles: {
                    name: 'styles',
                    test: /\.css$/,
                    chunks: 'all',
                    enforce: true,
                },
            },
        },
我相信这些块会导致我的两个ink CSS组合成一个样式。[hash].CSS文件在开发或产品构建之后:

import '../../ext/ink-3.1.10/css/ink.min.css';
import '../../ext/ink-3.1.10/css/ink-flex.min.css';
index.tsx

import { render } from 'react-dom';
import React from 'react';
import { Provider } from 'react-redux';
import App from './App';
import '../../ext/ink-3.1.10/css/ink.min.css';
import '../../ext/ink-3.1.10/css/ink-flex.min.css';
import './less/master.less';
import store from './store';
import { BrowserRouter as Router } from 'react-router-dom';

const globalAny: any = global;
globalAny.__base = `${__dirname}/`;


render(
    <Provider store={store}>
        <Router>
            <App />
        </Router>
    </Provider>,

    document.getElementById('app')
);
更新:

现在唯一的问题是:

  • 还有,墨水css文件是否位于
    lib/css
    root
    中?由于某种原因,它似乎正在将其放入我的
    \uuu dirname
    和ext中,而不是放在我的
    main
    css旁边的
    lib\css

  • 看起来我正在用css创建的墨水复制?它在和中,在脚本中看起来像是作为路径的一部分附加到应用程序包中?似乎很奇怪

  • 我需要有2个墨水文件生成并包含在
    index.html
    中。它将这两个ink css文件(
    ink
    和ink flex)组合成一个inkcss文件。这给我带来了麻烦。看起来分块逻辑还没有为我包含在
    index.tsx
    中的文件创建单独的文件

  • webpack.config.js

    const path = require('path');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const TerserJSPlugin = require('terser-webpack-plugin');
    const HtmlWebPackPlugin = require('html-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    const CopyPlugin = require('copy-webpack-plugin');
    
    const isProduction = process.env.NODE_ENV === 'production';
    
    const html = () =>
        new HtmlWebPackPlugin({
            template: path.resolve(__dirname, 'src/client', 'index.html'),
            filename: 'index.html',
            hash: true,
        });
    
    const copyAllOtherDistFiles = () =>
        new CopyPlugin({
            patterns: [
                { from: 'src/client/assets', to: 'lib/assets' },
                { from: 'package.json', to: './' },
                { from: 'ext/ink-3.1.10/js/ink-all.min.js', to: 'lib/js' },
                { from: 'ext/ink-3.1.10/js/autoload.min.js', to: 'lib/js' },
                { from: 'ext/js/jquery-2.2.3.min.js', to: 'lib/js' },
                { from: 'feed.xml', to: './' },
            ],
        });
    
    module.exports = {
        entry: './src/client/index.tsx',
        output: {
            filename: 'scripts/app.[hash].bundle.js',
            publicPath: '/',
            path: path.resolve(__dirname, 'dist'),
        },
        resolve: {
            extensions: ['.ts', '.tsx', '.js'],
        },
        devtool: 'source-map',
        devServer: {
            open: true,
            writeToDisk: false,
            publicPath: '/',
            compress: true,
            historyApiFallback: {
                index: '/',
            },
            stats: 'errors-only',
            proxy: {
                '/api': {
                    target: 'http://localhost:3000',
                    secure: false,
                    changeOrigin: true,
                    logLevel: 'debug',
                },
            },
        },
        optimization: {
            minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
            splitChunks: {
                cacheGroups: {
                    styles: {
                        name: 'styles',
                        test: /\.css$/,
                        chunks: 'all',
                        enforce: true,
                    },
                },
            },
        },
        module: {
            rules: [
                {
                    test: /\.(js)$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                    },
                },
                {
                    test: /\.(tsx|ts)?$/,
                    use: 'ts-loader',
                    exclude: /node_modules/,
                },
                {
                    test: /\.html$/,
                    use: [
                        {
                            loader: 'html-loader',
                        },
                    ],
                },
                {
                    test: /\.less$/,
                    use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],
                },
                {
                    test: /\.css$/,
                    use: [
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                                publicPath: '../../',
                            },
                        },
                        'css-loader',
                    ],
                },
                {
                    test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: 'url-loader?limit=10000&mimetype=application/font-woff',
                },
                {
                    test: /\.(png|svg|jpg|gif)$/,
                    use: ['url-loader'],
                },
            ],
        },
        plugins: isProduction
            ? [
                    new CleanWebpackPlugin(),
                    copyAllOtherDistFiles(),
                    new MiniCssExtractPlugin({
                        filename: 'lib/css/[name].[hash].css',
                    }),
                    html(),
              ]
            : [
                    copyAllOtherDistFiles(),
                    new MiniCssExtractPlugin({
                        filename: 'lib/css/[name].[hash].css',
                    }),
                    html(),
              ],
    };
    
    const path = require('path');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const TerserJSPlugin = require('terser-webpack-plugin');
    const HtmlWebPackPlugin = require('html-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    const CopyPlugin = require('copy-webpack-plugin');
    
    const isProduction = process.env.NODE_ENV === 'production';
    
    const html = () =>
        new HtmlWebPackPlugin({
            template: path.resolve(__dirname, 'src/client', 'index.html'),
            filename: 'index.html',
            hash: true,
        });
    
    const copyAllOtherDistFiles = () =>
        new CopyPlugin({
            patterns: [
                { from: 'src/client/assets', to: 'lib/assets' },
                { from: 'package.json', to: './' },
                { from: 'ext/ink-3.1.10/js/ink-all.min.js', to: 'lib/js' },
                { from: 'ext/ink-3.1.10/js/autoload.min.js', to: 'lib/js' },
                { from: 'ext/js/jquery-2.2.3.min.js', to: 'lib/js' },
                { from: 'feed.xml', to: './' },
            ],
        });
    
    module.exports = {
        entry: './src/client/index.tsx',
        output: {
            filename: 'scripts/app.[hash].bundle.js',
            publicPath: '/',
            path: path.resolve(__dirname, 'dist'),
        },
        resolve: {
            extensions: ['.ts', '.tsx', '.js'],
        },
        devtool: 'source-map',
        devServer: {
            open: true,
            writeToDisk: false,
            publicPath: '/',
            compress: true,
            historyApiFallback: {
                index: '/',
            },
            stats: 'errors-only',
            proxy: {
                '/api': {
                    target: 'http://localhost:3000',
                    secure: false,
                    changeOrigin: true,
                    logLevel: 'debug',
                },
            },
        },
        optimization: {
            minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
            splitChunks: {
                cacheGroups: {
                    styles: {
                        name(module) {
                            const match = module.context.match(/[\\/](.*).css/);
    
                            if (!match) {
                                return false;
                            }
    
                            const moduleName = match[1];
    
                            return moduleName;
                        },
                        test: /\.css$/,
                        chunks: 'all',
                        enforce: true,
                    },
                },
            },
        },
        module: {
            rules: [
                {
                    test: /\.(js)$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                    },
                },
                {
                    test: /\.(tsx|ts)?$/,
                    use: 'ts-loader',
                    exclude: /node_modules/,
                },
                {
                    test: /\.html$/,
                    use: [
                        {
                            loader: 'html-loader',
                        },
                    ],
                },
                {
                    test: /\.less$/,
                    use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],
                },
                {
                    test: /\.css$/,
                    use: [
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                                publicPath: '../../',
                            },
                        },
                        'css-loader',
                    ],
                },
                {
                    test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: 'url-loader?limit=10000&mimetype=application/font-woff',
                },
                {
                    test: /\.(png|svg|jpg|gif)$/,
                    use: ['url-loader'],
                },
            ],
        },
        plugins: isProduction
            ? [
                    new CleanWebpackPlugin(),
                    copyAllOtherDistFiles(),
                    new MiniCssExtractPlugin({
                        filename: 'lib/css/[name].[hash].css',
                    }),
                    html(),
              ]
            : [
                    copyAllOtherDistFiles(),
                    new MiniCssExtractPlugin({
                        filename: 'lib/css/[name].[hash].css',
                    }),
                    html(),
              ],
    };
    

    I控制台。在此处注销匹配项以尝试排除故障:

    [
      '/Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10/css',
      'Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10',
      index: 0,
      input: '/Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10/css',
      groups: undefined
    ]
    match[1]: /Users/xxxxx/code/other/projects/xxxxx/src/client/ext/ink-3.1.10
    
    [
      '/Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10/css',
      'Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10',
      index: 0,
      input: '/Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10/css',
      groups: undefined
    ]
    match[1]: /Users/xxxxx/code/other/projects/xxxxx/src/client/ext/ink-3.1.10
    
    [
      '/Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10/css',
      'Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10',
      index: 0,
      input: '/Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10/css',
      groups: undefined
    ]
    match[1]: /Users/xxxxx/code/other/projects/xxxxx/src/client/ext/ink-3.1.10
    
    [
      '/Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10/css',
      'Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10',
      index: 0,
      input: '/Users/xxxxx/code/other/projects/xxxxx/ext/ink-3.1.10/css',
      groups: undefined
    ]
    match[1]: /Users/xxxxx/code/other/projects/xxxxx/src/client/ext/ink-3.1.10
    
    
    请尝试更改您的配置:

    splitChunks: {
       cacheGroups: {
          styles: {
              name(module) {
                 const match = module.context.match(/[\\/](.*).css/);
    
                 if (!match) {
                    return false;
                 }
    
                 const moduleName = match[1];
    
                 return moduleName;
              },
              test: /\.css$/,
              chunks: 'all',
              enforce: true,
           },
       },
    },
    
    通过定义
    名称:'styles'
    您告诉webpack,导入并匹配
    /\.css$/
    regex的每个模块都应该封装在一个名为“styles”的块中

    cacheGroup的name属性也可以是函数。 此函数获取模块(包含给定文件中大量数据的对象),并执行以下操作:

  • 如果返回false:-不将此模块(文件)添加到此块组
  • 如果返回字符串-将此模块(文件)推送到具有此名称的块中

  • 因此,根据每个文件返回的内容,您可以从一个缓存组生成多个块。

    非常感谢您的帮助和详细回答。我没有意识到我必须把这么多的逻辑放进去,或者怎么放进去。看看我的更新,只是几件事,还不太清楚