Search code examples
webpackwebpack-file-loader

Webpack file loader does not copy files


In an Angular2 application, I have a file loader setup in webpack config, like so:

  {
    test: /\.(eot|svg|ttf|woff|woff2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
    loader: 'file?name=/assets/fonts/[name].[ext]'
  }

I also have this elsewhere in the config:

modulesDirectories: ['node_modules']

As I understand, the file loader searches the node_modules folder for any files that match the expression given (in this case font files), and copies them over to the /assets/fonts folder in the build output. However this does work, as no files actually get copied to to the destination folder. What am I missing?

On a side note, I also would like to know how conflicts are handled, as there could be files in node_modules in multiple packages with the same name.

More information: vendor.scss file includes the following: $zmdi-font-path: "assets/fonts"; @import "~material-design-iconic-font/scss/material-design-iconic-font.scss";

The sass-loader eventually applies this to result in the following css:

@font-face {
font-family: 'Material';
src:url('assets/fonts/Material-Design-Iconic-Font.woff2?v=2.2.0') format('woff2'),url('assets/fonts/Material-Design-Iconic-Font.woff?v=2.2.0') format('woff'),url('assets/fonts/Material-Design-Iconic-Font.ttf?v=2.2.0}') format('truetype');
font-weight: normal;
font-style: normal;
}

The two steps above will cause a request from the browser to the font file at assets/fonts/Material-Design-Iconic-Font.woff2?v=2.2.0. This does not happen until runtime obviously. Where would I require the file so that it is copied to assets/fonts at build time?

I am also using the sass-loader in the pipeline: { test: /.scss$/, loaders: ['raw-loader', 'sass-loader'] }

and include the sass in my component like this:

styleUrls: [
'./../assets/scss/main.scss'
]

I can see that the css is included in the HTML when seen from the browser, but calls to the fonts return 404.


Solution

  • It works a little differently:

    It does not simply copy all files matching the test regex. It will copy all required files matching the regex. What this means is that somewhere in your code, you must require a css file (or sass or less) that loads the font. Webpack will then make sure the font is copied over to your assets folder.

    Note, you can drop the / in front of /assets/fonts/....

    EDIT Make sure to require your sass file vendor.scss somewhere at the beginning of your app inside your js.

    Example

    require('./path-to-vendor/vendor.scss');
    

    Webpack will then load the file and prepare any dependencies for you. It looks weird to require your sass inside js, but that's how it works. :)