Question: Suggestion: Webpack hard to build desired structure

If we have

.
├── src
|   ├── css
|   |    └──  style.css
|   ├── images
|   |    └── image.png
|   └── js
|        └── main.js
.
/* src/css/style.css*/
body{
   background:url(../images/image.png)
}
/* src/js/main.js*/
require('../css/style.css')

I want compile to dist folder as the same structure like

.
├── dist
|   ├── css
|   |    └──  main-bundle.css
|   ├── assets
|   |    └── image.png
|   └── js
|        └── main-bundle.js
├── src
.   └── ...

so we wrote webpack.config.js using ExtractTextPlugin to extract css file seperately like

entry: {
    main:"main.js"
},
output: {
    path: path.join(__dirname, "dist"),
    filename: "./js/[name].bundle.js"
},
module: {
    loaders: [
        { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") },
        { test: /\.png$/, loader: "file-loader?name=./assets/[name].[ext]" }
    ],
    plugins: [
        new ExtractTextPlugin("./css/[name]-bundle.css")
    ]
}

So we got

/* dist/css/main-bundle.css*/
body{
   background:url(./assets/image.png)
}

But actually ,we want it to be url(../assets/image.png) when I config png loader file-loader?name=../images/[name].[ext] it put the image file to outside dist folder instead. I have found out that it’s impossible to set url correctly

Author: Fantashit

1 thought on “Question: Suggestion: Webpack hard to build desired structure

  1. Thank you for your approach I’ve never use manifest before it seems useful for me

    I’ve already carelessly hacked file-loader

    module.exports = function(content) {
        this.cacheable && this.cacheable();
        if(!this.emitFile) throw new Error("emitFile is required from module system");
        var query = loaderUtils.parseQuery(this.query);
    
        var url = loaderUtils.interpolateName(this, query.name || "[hash].[ext]", {
            context: query.context || this.options.context,
            content: content,
            regExp: query.regExp
        });
    
        var to = (query.to)&& loaderUtils.interpolateName(this, query.to, {
            context: query.context || this.options.context,
            content: content,
            regExp: query.regExp
        });
    
        this.emitFile((to)?to:url, content);
        return "module.exports = __webpack_public_path__ + " + JSON.stringify(url);
    }
    module.exports.raw = true;

    I separate url from emitFile method by replacing with another parameter to that means url() in css would be written with name but the image file will emit to different location to

    using

    { test: /\.png$/, loader: "file-loader?name=../assets/[name].[ext]&to=./assets/[name].[ext]" }

Comments are closed.