Coherent
Coherent

Reputation: 2113

configure webpack to use absolute path instead of relative path

I'm having an issue with setting webpack to use the absolute path. The problem is that I cannot figure out how to get both the load path for my fonts to match the actual spot that it saves the files. This is my folder structure:

public
  font
     font1
     font2
  css
     index.css
src
  font
     font1
     font2
  css
     index.scss
webpack.config.js

This is what my webpack file looks like. When I run webpack, it correctly adds the font files to the right spot in public->font but when I run the server, it tries to fetch the font from:

http://localhost:8080/css/public/font/font1.ttf

instead of:

http://localhost:8080/font/font1.tff

You can see that it is trying to look from the relative path of the css folder instead of the root. How can I fix this? Thanks!

 module.exports = {
    entry: {
        index: './src/javascript/index.js'
    },
    output: {
        filename: './public/javascript/[name].js',
    },
    module: {
        loaders: [
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            },
                        {
                            test: /\.(eot|svg|ttf|woff|woff2)$/,
                            loader: 'file-loader?name=./public/font/[name].[ext]'
                        },
                        {
                            test: /\.(jpg|png)$/,
                            loader: 'file-loader?name=./public/image/[name].[ext]'
                        }
        ]
    },
    plugins: [
        new ExtractTextPlugin('public/css/index.css')
    ]
};

Upvotes: 6

Views: 17770

Answers (1)

Michael Jungo
Michael Jungo

Reputation: 32972

It tries to fetch css/public/font/font1.ttf because the output CSS reference it as ./public/font/font1.ttf as that's the name you gave it from the file-loader. The file-loader respects the output.publicPath option and will add it to the beginning of the assets import path. Setting output.publicPath to / will give you the desired path.

output: {
    filename: './public/javascript/[name].js',
    publicPath: '/',
},

If you don't want to set output.publicPath (although it is recommended), you can also use the file-loader option publicPath, to configure it just for the given rule.


A small improvement you could make to your config is to set output.path to public because you want all files to end up in the public directory, so you don't have to specify it in every filename option. For this to work you'll also have to change output.publicPath to /public/.

The following config produces the same output (also changed the rules to use webpack 2 syntax):

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    entry: {
        index: './src/javascript/index.js'
    },
    output: {
        path: path.resolve(__dirname, 'public'),
        filename: 'javascript/[name].js',
        publicPath: '/public/',
    },
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            },
            {
                test: /\.(eot|svg|ttf|woff|woff2)$/,
                loader: 'file-loader',
                options: {
                    name: 'font/[name].[ext]'
                }
            },
            {
                test: /\.(jpg|png)$/,
                loader: 'file-loader',
                options: {
                    name: 'image/[name].[ext]'
                }
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin('css/index.css')
    ]
};

Upvotes: 11

Related Questions