webpack5 打包css 引入的背景图片无法正确加载

知几自己
  • 1
新手上路,请多包涵

css文件里引入了图片
image.png
webpack配置如下:

'use strict';

const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
// const resolve = require('resolve');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
// const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');//webpack5已经废弃
// const safePostCssParser = require('postcss-safe-parser');
const paths = require('./paths');


const appPackageJson = require(paths.appPackageJson);


// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';


const imageInlineSizeLimit = parseInt(
    process.env.IMAGE_INLINE_SIZE_LIMIT || '10000', 10
);


// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;

const isEnvDevelopment = process.env.NODE_ENV === 'development';
const isEnvProduction = process.env.NODE_ENV === 'production';

const getStyleLoaders = (cssOptions, preProcessor) => {
    const loaders = [
        isEnvDevelopment && require.resolve('style-loader'),
        isEnvProduction && {
            loader: MiniCssExtractPlugin.loader,
            // options: paths.publicUrlOrPath.startsWith('.') ? {
            //     publicPath: '../../'
            // } : {}, //为 CSS 内的图片、文件等外部资源指定一个自定义的公共路径
        },
        {
            loader: require.resolve('css-loader'),
            options: cssOptions,
        },
        {
            loader: require.resolve('postcss-loader'),
            options: {
                postcssOptions: {
                    plugins: [
                        require('postcss-preset-env')({
                            autoprefixer: {
                                flexbox: 'no-2009',
                            },
                            stage: 3,
                        }),
                    ],
                },

            },
        },
    ].filter(Boolean);
    if (preProcessor) {
        loaders.push({
            loader: require.resolve('resolve-url-loader'),
            options: {
                sourceMap: isEnvProduction && shouldUseSourceMap,
            },
        }, {
            loader: require.resolve(preProcessor),
            options: {
                sourceMap: true,
            },
        });
    }
    return loaders;
};


const entryObj = {};
const htmlPluginsAray = paths.htmlArray.map((v) => {
    const fileParse = path.parse(v);
    const languageType = v.indexOf('/en/') !== -1 ? 'en' : 'zh'
    entryObj[`${fileParse.name}-${languageType}`] = [
        // require.resolve('./polyfills'),
        // path.join(paths.appSrc, `views/${languageType}/${fileParse.name}/${fileParse.name}.js`),
        path.join(fileParse.dir, `${fileParse.name}.js`)
    ].filter(Boolean);
    let filename = '';
    if (fileParse.name === 'index' && languageType === 'zh') { // 中文首页放在根目录下
        filename = `${fileParse.name}.html`;
    } else {
        filename = `${languageType}/${fileParse.name}.html`;
    }
    return new HtmlWebpackPlugin(
        Object.assign({}, {
            inject: true,
            chunks: [`${fileParse.name}-${languageType}`],
            template: path.normalize(v),
            filename: filename
        },
            isEnvProduction ? {
                minify: {
                    removeComments: false,
                    collapseWhitespace: false,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeStyleLinkTypeAttributes: true,
                    keepClosingSlash: true,
                    minifyJS: false,
                    minifyCSS: false,
                    minifyURLs: false,
                },
            } :
                undefined
        )
    );
});

// console.log('entryObj=', entryObj)
// console.log('htmlPluginsAray=', htmlPluginsAray)

module.exports = {
    mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
    // Stop compilation early in production
    bail: isEnvProduction,
    devtool: isEnvProduction ?
        shouldUseSourceMap ?
            'source-map' :
            false : isEnvDevelopment && 'cheap-module-source-map',

    entry: entryObj,
    output: {

        path: paths.appBuild || undefined, //isEnvProduction ? paths.appBuild : undefined,

        pathinfo: isEnvDevelopment,

        filename: isEnvProduction ? 'static/js/[name]-[contenthash:8].js' : 'static/js/[name].js',

        // There are also additional JS chunk files if you use code splitting.
        chunkFilename: isEnvProduction ? 'static/js/[name]-[contenthash:8].js' : 'static/js/[name].js',

        publicPath: '/', //paths.publicUrlOrPath,
        // Point sourcemap entries to original disk location (format as URL on Windows)
        devtoolModuleFilenameTemplate: isEnvProduction ?
            info => path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\/g, '/') : info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),


        globalObject: 'this',
    },
    optimization: {
        minimize: isEnvProduction,
        minimizer: [
            // This is only used in production mode
            new TerserPlugin({

                minify: (file, sourceMap) => {
                    const uglifyJsOptions = {
                        compress: {
                            drop_console: true
                        }
                    };
                    if (sourceMap) {
                        uglifyJsOptions.sourceMap = {
                            content: sourceMap,
                        }
                    }
                    return require('uglify-js').minify(file, uglifyJsOptions)
                },
            }),

            // This is only used in production mode
            // new OptimizeCSSAssetsPlugin({
            //     cssProcessorOptions: {
            //         parser: safePostCssParser,
            //         map: shouldUseSourceMap ?
            //             {
            //                 // `inline: false` forces the sourcemap to be output into a
            //                 // separate file
            //                 inline: false,
            //                 // `annotation: true` appends the sourceMappingURL to the end of
            //                 // the css file, helping the browser find the sourcemap
            //                 annotation: true,
            //             } :
            //             false,
            //     },
            //     cssProcessorPluginOptions: {
            //         preset: ['default', {
            //             minifyFontValues: {
            //                 removeQuotes: false
            //             }
            //         }],
            //     },
            // }),
            new CssMinimizerPlugin(),
        ],

        splitChunks: {
            chunks: 'all',
            name: false,
        },

        runtimeChunk: {
            name: entrypoint => `runtime-${entrypoint.name}`,
        },
    },
    resolve: {

        // modules: ['node_modules', paths.appNodeModules].concat( 
        //     modules.additionalModulePaths || []
        // ),

        extensions: ['.js']
        // alias: { },
        // plugins: [],
    },
    // resolveLoader: {
    //     plugins: [],
    // },
    module: {
        strictExportPresence: true, //将缺失的导出提示成错误而不是警告
        rules: [
            // Disable require.ensure as it's not a standard language feature.
            {
                parser: {
                    requireEnsure: false
                }
            },

            {

                oneOf: [

                    {
                        test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, /\.svg$/],
                        loader: require.resolve('url-loader'),
                        options: {
                            limit: imageInlineSizeLimit,
                            name: '/static/images/[name].[hash:8].[ext]',
                            esModule: false,
                            // publicPath: `./devbuild`
                            
                        },
                    },
                    {
                        test: /\.js$/,
                        include: paths.appSrc,
                        loader: require.resolve('babel-loader'),
                        options: {
                            presets: ['@babel/preset-env'],
                            cacheDirectory: true,
                            // See #6846 for context on why cacheCompression is disabled
                            cacheCompression: false,
                            compact: isEnvProduction,
                        },
                    },


                    {
                        test: cssRegex,
                        exclude: cssModuleRegex,
                        use: getStyleLoaders({
                            importLoaders: 1,
                            sourceMap: isEnvProduction && shouldUseSourceMap,
                            modules: {
                                localIdentName: "[local]",
                            },
                        }),

                        sideEffects: true,
                    },
                    // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
                    // using the extension .module.css
                    {
                        test: cssModuleRegex,
                        use: getStyleLoaders({
                            importLoaders: 1,
                            sourceMap: isEnvProduction && shouldUseSourceMap,
                            modules: {
                                localIdentName: "[name]__[local]--[hash:base64:5]",
                            },

                        }),
                    },
                    // Opt-in support for SASS (using .scss or .sass extensions).
                    // By default we support SASS Modules with the
                    // extensions .module.scss or .module.sass
                    {
                        test: sassRegex,
                        exclude: sassModuleRegex,
                        use: getStyleLoaders({
                            importLoaders: 3,
                            sourceMap: isEnvProduction && shouldUseSourceMap,
                        },
                            'sass-loader'
                        ),

                        sideEffects: true,
                    },
                    // Adds support for CSS Modules, but using SASS
                    // using the extension .module.scss or .module.sass
                    {
                        test: sassModuleRegex,
                        use: getStyleLoaders({
                            importLoaders: 3,
                            sourceMap: isEnvProduction && shouldUseSourceMap,
                            modules: {
                                localIdentName: "[name]__[local]--[hash:base64:5]",
                            },
                        },
                            'sass-loader'
                        ),
                    },

                    {
                        test: /.html$/,
                        use: 'html-withimg-loader'
                    },

                    {
                        loader: require.resolve('file-loader'),
                        exclude: [/\.js$/, /\.html$/, /\.json$/],
                        options: {
                            name: 'static/images/[name]-[hash:8].[ext]',
                        },
                    },

                    // {
                    //     test: /\.html.$/,
                    //     use: {
                    //         loader: 'html-loader',
                    //     }
                    // },

                    

                ],
            },
        ],
    },
    plugins: [

        ...htmlPluginsAray,


        isEnvDevelopment && new webpack.HotModuleReplacementPlugin(),

        isEnvProduction &&
        new MiniCssExtractPlugin({

            filename: 'static/css/[name]-[contenthash:8].css',
            chunkFilename: 'static/css/[name]-[contenthash:8].css',
        }),


        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),



    ].filter(Boolean),

    // node: {
    //     global: false,
    //     __filename: false,
    //     __dirname: false,
    // },

    performance: false,

    // devServer: {
    //     contentBase: path.join(__dirname, 'devbuild'),
    //     compress: true,
    //     host: 'localhost',
    //     port: 8000,
    //     open: true,
    //     hot: true,
    //     transportMode: 'ws',
    // },
};

打包后:
image.png

实际上我希望打包后的图片放在static/imageswen文件夹下,打包后这个文件下确实有那个图片,但css引用的不是那个图片,而是根文件下的一个名字为MD5hash的图片,且图片内容是一个地址,指向正确的图片
image.png

代码地址:https://gitee.com/zjy_king/my...

回复
阅读 312
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏