Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

copy-webpack-plugin with fonts from /node_modules

Tags:

webpack

I've an Angular application which uses webpack as module bundler. This application also uses some assets (images, fonts, styles) from some other projects which are imported as node_modules.

The structure of my application is something like this

src/
  app/
    ...
  stylesheets/
    application.scss

Now, in my scss I have some references to images src="/images/...", which are in node_modules/my_assets/images, so I used copy-webpack-plugin to include the images in bundle time

new CopyWebpackPlugin([
  { from: 'node_modules/my-assets/images', to: 'images' },
  { from: 'node_modules/my-assets/favicons', to: 'favicons' },

This is working fine.

Problem now is with fonts. I have the same structure, but when the stylesheet references a font is now with a relative url ./fonts/Open-Sans-300/Open-Sans-300.eot

So I tried to do the same as before

new CopyWebpackPlugin([
  { from: 'node_modules/my-assets/images', to: 'images' },
  { from: 'node_modules/my-assets/favicons', to: 'favicons' },
  { from: 'node_modules/my-assets/fonts', to: 'fonts' }
])

This is not working. If I copy manually the /fonts folder directly in my /src/stylesheets folder it works fine. I'm guessing that as it's relative I'm not copying the folder where I have to, so I tried many variations:

{ from: 'node_modules/my-assets/fonts', to: '/fonts' },
{ from: 'node_modules/my-assets/fonts', to: './fonts' },
{ from: 'node_modules/my-assets/fonts', to: 'src/stylesheets/fonts' },
{ from: 'node_modules/my-assets/fonts', to: '/src/stylesheets/fonts' }

None of these work. Any idea why not? And what should I write instead?

I should also mention that I have a loader for the fonts

{ 
 test: /\.(png|woff|woff2|eot|ttf|svg)$/, 
 loader: 'url-loader?limit=100000'
}

which seems to work fine.

EDIT: I must also say that this problem happens when using webpack-dev-server, so I don´t really know where is webpack copying the files when doing something like this { from: 'node_modules/my-assets/images', to: 'images' }

Thanks

like image 411
David Avatar asked Apr 26 '17 10:04

David


1 Answers

If you just want your SASS files to be able to resolve paths to statics assets like images or fonts, CopyWebpackPlugin is not the tool for you.

Given your font and SCSS loaders in place, Webpack should be able to build the dependencies tree by itself.

Remove CopyWebpackPlugin setting from your Webpack configuration and make sure to explicitly set the output.publicPath setting.

output: {
  publicPath: '/',
  /* follows your output config */
},

Since Webpack sass-loader does not provide url rewriting, you have to tell webpack to rewrite them accordingly to the place where the assets are moved after the build.

Webpack resolve-url-loader plugin does exactly that. Place it directly after the sass-loader in the CSS loader chain and you should be ready to go.

{
    test   : /\.scss$/,
    loaders: ['style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader?sourceMap']
}

Side note

copy-webpack-plugin docs, clearly explain why the plugin doesn't copy files with webpack-dev-server:

Starting in version 3.0.0, we stopped using fs to copy files to the filesystem and started depending on webpack's in-memory filesystem:

... webpack-dev-server will serve the static files in your build folder. It’ll watch your source files for changes and when changes are made the bundle will be recompiled. This modified bundle is served from memory at the relative path specified in publicPath (see API). It will not be written to your configured output directory.

If you must have webpack-dev-server write to your output directory, you can force it with the write-file-webpack-plugin.

like image 60
Andrea Carraro Avatar answered Oct 16 '22 21:10

Andrea Carraro