Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

loading css url() files in a specific folder with webpack

I'm using a node library that has a css file inside, that css file loads an image like this

background-image: url("image.png");

The file "image.png" is being requested at http://localhost:9000/ (the root) is dirty to have images all over the root of the project.

Also I have another problem, I don't know why the image file of the module is not being copied to the build folder automatically, only works if I copy the image file manually to the build folder. Playing with Webpack config parameters I got working the feature to copy the images to root, but it puts random names to them and I do not want them in root.

I want all the images loaded to be copied to a "img" subfolder inside the build folder with thier original file names, and to be requested there, so the root is not dirty with all the files there.

This is my webpack config file:

var webpack               = require('webpack');
var WebpackNotifierPlugin = require('webpack-notifier');

"use strict";
module.exports = {
    entry:   "./source/typescript/Main.ts",
    output: {
        filename: "./js/bundle.js"
    },
    devtool: "inline-source-map",
    devServer: {
        contentBase: ".",
        host: "localhost",
        port: 9000,
        open: true
    },
    module: {
        rules: [
            {
                test:/\.(s*)css$/,
                use: [
                    {
                        loader: "style-loader"
                    },
                    {
                        loader: "css-loader",
                        options: {
                            url: false
                        }
                    },
                    {
                        loader: "sass-loader"
                    }
                ]
            },
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                enforce: 'pre',
                test: /\.js$/,
                loader: "source-map-loader"
            },
            {
                test: /\.(png|jpg|gif|svg|eot|ttf|otf|woff|woff2|json|xml|ico)$/,
                use: [{loader: 'file-loader'}]
            },
            {
                test: /\.(csv|tsv)$/,
                use: [{ loader: 'csv-loader' }]
            },
            {
                test: /\.exec\.js$/,
                use: [{ loader: 'script-loader' }]
            },
            {
                test: require.resolve('jquery'),
                use:
                [
                    {
                        loader: 'expose-loader',
                        options: 'jQuery'
                    },
                    {
                        loader: 'expose-loader',
                        options: '$'
                    }
                ]
            }

        ]
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
    },
    plugins: [
        new WebpackNotifierPlugin({excludeWarnings: true}),
        //new webpack.optimize.UglifyJsPlugin({compress: {warnings: false}}) // Uncoment to minify bundle
    ]
};
like image 609
fermmm Avatar asked Dec 01 '17 09:12

fermmm


People also ask

How do I load a CSS file into webpack?

To be able to use CSS in your webpack app, you need to set up a new loader. Out-of-the-box, webpack only understands Javascript and JSON. With a loader, you can translate another type of file to a format that webpack understands and can work with. There are many webpack loaders and each loader has a specific purpose.

How do I bundle CSS with webpack?

By default, Webpack will inline your CSS as Javascript tags that injects the CSS into the page. This sounds strange but it lets you do hot reloading in development. In production you extract them to a file using the ExtractTextPlugin, and require it with a normal link tag.

How does webpack CSS loader work?

Loaders are the node-based utilities built for webpack to help webpack to compile and/or transform a given type of resource that can be bundled as a javascript module. css-loader is the npm module that would help webpack to collect CSS from all the css files referenced in your application and put it into a string.


Video Answer


1 Answers

I solved the problems:

"outputPath" and "name" parameters can be used to tell webpack to copy all the image files to a specific folder in the build folder and with a specific name rule. So I solved the problems like this:

1) The solution to the files copied in the root with random file names: I changed the webpack configuration file to tell webpack that any image loaded should be copied to the build folder inside a img sub-folder with their original name. This is done in the file-loader options using the "outputPath" and "name" parameters.

2) The solution to the images files not being copied to the build folders: Removed "url: false" in the css-loader, so now the paths are managed by css-loader. (The default behavior). I originally set that option because I didn't understand how css-loader resolves urls so I disabled that feature because it was throwing some errors. Now I realised that css url() paths are relative to the root of the project starting with /, for example: url("/img/my-image.png"); That prevented webpack to copy the image files to the build folder.

Now everything works, my final webpack configuration of loaders is this:

    module: {
        rules: [
            {
                test: /\.(png|jpg|gif|svg|ico)$/,
                loader: 'file-loader',
                query:{
                    outputPath: './img/',
                    name: '[name].[ext]?[hash]'
                }
            },
            {
                test: /\.(eot|ttf|otf|woff|woff2|json|xml)$/,
                loader: 'file-loader',
                query:{
                    outputPath: './fonts/',
                    name: '[name].[ext]?[hash]'
                }
            },
            {
                test: /\.(json|xml)$/,
                loader: 'file-loader',
                query:{
                    outputPath: './data/',
                    name: '[name].[ext]?[hash]'
                }
            },
            {
                test: /\.(s*)css$/,
                use: [{ loader: "style-loader" }, { loader: "css-loader" }, { loader: "sass-loader" }]
            },
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                enforce: 'pre',
                test: /\.js$/,
                loader: "source-map-loader"
            },
            {
                test: /\.(csv|tsv)$/,
                use: [{ loader: 'csv-loader' }]
            },
            {
                test: /\.exec\.js$/,
                use: [{ loader: 'script-loader' }]
            }           
        ]
    }
like image 127
fermmm Avatar answered Dec 13 '22 03:12

fermmm