Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack file-loader duplicate public path

Tags:

sass

webpack

I'm using url-loader and file-loader to package up my sass files, but having an issue with image urls.

I've tried using resolve.alias to alias my images directory in the root of the application so I can use url(~images/myimage.png) in my sass files - this works fine with the url-loader, but if the images are picked up by file-loader they are output with a duplicate public path, i.e. dist/dist/[hash].png - this is the case whether I use ~ or a relative path. It works if I use an absolute path to my images, but then breaks if my app is mounted under a sub-directory.

Directory structure:

- images/
- js/
- styles/
- webpack.config.js

Webpack config:

module.exports = {
    entry: {
        app: './js/bootstrap'
    },

    output: {
        filename: 'bundle.js',
        path: 'dist',
        publicPath: 'dist/'
    },

    module: {
        loaders: [
            {
                test: /\.scss$/,
                loader: ExtractPlugin.extract('style', 'css!sass')
            },
            {
                test: /\.(gif|png|svg|jpe?g)$/i,
                loader: 'url',
                query: {
                    limit: 1000
                }
            }
        ]
    },

    resolve: {
        // add alias for application code directory
        alias:{
            js: path.resolve(__dirname, 'js'),
            styles: path.resolve(__dirname, 'styles'),
            images: path.resolve(__dirname, 'images')
        },
        extensions: ['', '.js', '.scss', '.png', '.svg', '.jpg', '.jpeg', '.gif']
    }
};

Sass file:

.some-class{
    background: url('~images/myimage.png') // url-loader works, file-loader doesn't
    background: url('../../../images/myimage.png') // url-loader works, file-loader doesn't
    background: url('/images/myimage.png') // both loaders work until app mounted under a sub-directory
}

Hopefully I'm just missing something stupid!

like image 969
Lee Avatar asked Mar 12 '23 16:03

Lee


2 Answers

Use publicPath, starting with /, i.e. /dist/ instead of dist/.

Otherwise, paths to your assets will be interpreted as relative and if one sass document, say, dist/daddy.scss imports another one from e.g. dist/child.scss, the path to child will be interpreted as relative to daddy's url "folder", which is dist, so browser will look for dist/dist/child.scss.

like image 135
Boris Burkov Avatar answered Mar 25 '23 02:03

Boris Burkov


I found a fix, overriding publicPath in the ExtractPlugin was what did it:

ExtractPlugin.extract('style', 'css!sass', { publicPath: './' })

like image 30
Lee Avatar answered Mar 25 '23 03:03

Lee