素材牛VIP会员
webpack file-loader 解析 css 文件中 background-images路径问题。
 疯***了  分类:Node.js  人气:1115  回帖:5  发布于6年前 收藏

通过 webpack 的 file-loader 把 css 中的 background-image 图片提取出来构建到产出目录,发现图片被生成在了产出目录的根目录。

目录结构:
构建之后:

原本 src/css/02.png 的 png 图片构建之后目录变为 build/02.png。丢失了一层 css 目录,导致 css 中引用图片404。

有没有办法保证 src/css/02.png 构建之后的目录结构为 build/css/02.png,而不是 build/02.png。

附上极简的 demo 包文件下载。
再附上文件完整源码:
webpack.config.js :

var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
    entry : {
        "demo" : "./src/js/demo.js"
    },
    output: {
        path: path.resolve("./build"),
        filename: 'js/[name].js'
    },
    module: {
        loaders: [
        {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/
        }, 
        {
            test: /\.css$/,
            // loader: 'style-loader!css-loader'
            loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader' })
        }, 
        {
            test: /\.(png|jpe?g|gif)(\?\S*)?$/,
            loader: 'file-loader',
            query: {
                name: 'css/[name].[ext]'
            }
        }]
    },
    plugins : [new ExtractTextPlugin("css/[name].css")]
}

demo/src/js/demo.js

import "../css/layout.css";

demo/src/css/layout.css

h1 { color: red; background: url(./02.png) no-repeat; }

几点尝试:
1、修改 file-loader的配置,比如 name 追加css目录路径:

这样可以实现图片在 build/css/内生成,但是同时也会修改掉 layout.css的源码,使

h1 { color: red; background: url(./02.png) no-repeat; }

变为

h1 { color: red; background: url(css/02.png) no-repeat; }

图片是构建到了 css 目录下了,然而引用路径又变成了 css/02.png。无奈依然404。

2、指定 publicPath
比如:

output: {
        path: path.resolve("./build"),
        filename: 'js/[name].js',
        publicPath : '/build/'
    },

其实比较难把握项目的跟目录,换句话说,根目录下不一定有 build这个目录,有可能在根目录下的任何一级子目录。或者另外一种方法,使用生产环境的绝对路径

output: {
        path: path.resolve("./build"),
        filename: 'js/[name].js',
        publicPath : 'http://xxx.123.cn/demo/build/' + versions
    },

生成的样式表通过绝对路径引用生成的图片地址,看起来完美了,但是有个尴尬的地方,这个 version(版本号)从何而来,并不是每个公司都通过 webpack的 hash 生成版本号,可能有自己的一套版本发布系统,webpack 只是做资源文件的合并打包,本身不参与正式的版本生成,不幸的是,鄙人就属于这种情况(悲了个剧的),资源文件构建前需要指定 publicPath,要指定 publicPath 就得知道版本号,而这个版本要要资源文件构建完成之后,才会生成,死循环了。

所以,需要样式表通过相对路径引用同级目录下的图片。而想要在 webpack 构建之后保留样式表和图片的相对路径引用,有点尴尬。求各位大神指点迷津...

讨论这个帖子(5)垃圾回帖将一律封号处理……

Lv5 码农
疯***斯 职业无 6年前#1

设置一下 path 看看

Lv1 新人
霍***跑 产品经理 6年前#2

我也碰到了这个问题,把图片压缩下就好了,不需要file-loader这个模版。

Lv6 码匠
d***悠 Web前端工程师 6年前#3

你好,请问你现在解决了吗

Lv3 码奴
34***86 JAVA开发工程师 6年前#4

使用自己的规则,那你可以直接使用CopyWebpackPlugin拷贝资源,不要使用webpack loader

new CopyWebpackPlugin([{
    from: 'static',
    to: 'static'
}])

预定 static 目录是不会被webpack处理的,直接copydist目录,这样路径的引用以及版本啥的都可以自己控制了。

Lv6 码匠
d***悠 Web前端工程师 6年前#5

请看file-loader的官方说明:https://github.com/webpack-co...

You can configure a custom filename template for your file using the query parameter name. For instance, to copy a file from your context directory into the output directory retaining the full directory structure, you might use ?name=path.[ext].

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取