Webpack url and file loaders don't working on

2019-04-25 20:28发布

问题:

I’m building an app with angular 2, sass and webpack and I’m having troubles with url on sass files that are required inside each component (using require); it doesn’t take those files and copy it to assets folder and don’t modify the url to the builded css styles. It work's correctly when I use import and with the assets inside html component's.

loaders:

        ...{
            test: /\.html$/,
            loader: 'html'
        },
        {
            test: /\.(png|jpe?g|gif)$/,
            loader: 'file?name=assets/[name].[hash].[ext]'
        },
        {
            test: /\.scss/,
            exclude: helpers.root('src', 'app'),
            loader: ExtractTextPlugin.extract('style', 'css?sourceMap!sass?sourceMap')
        },
        {
            test: /\.scss$/,
            include: helpers.root('src', 'app'),
            loaders: ['raw', 'resolve-url', 'sass?sourceMap']
        }...

Require styles:

...
styles: [require('./hero-image.scss')]
template: require('./hero-image.component.html')
...

Sass

...
background: url('../../../public/img/hero-bg.jpg');
...

Here the loaders (when build) should copy hero-bg.jpg to /assets/ and in the builded css the background should be /assets/hero-bg.jpg but it doesn't copy the image to assets folders and css builded remains like the sass.

NOTE: When I use import instead of require (modifying the loaders rules of course) at this point it works correctly. Inside the html component (hero-image.component.html) I have this <img src="../../../public/img/btn-google-play.jpg" /> and it work's correctly too.

I try with this angular 2 starter pack and the issue also happens.

Thanks for helping, I really appreciate it.

Edit: I forgot to mention that this also happens using only css (without sass) and following the official angular documentation about webpack

回答1:

After a lot of research and many attempts I found an approach using the exports-loader that work's and can be easily updated.

{
   test: /\.scss$/,
   include: helpers.root('src', 'app'),
   loaders: ['exports-loader?module.exports.toString()', 'css', 'sass']
}

Thanks @BobSponge for your help, you guided me in the right direction.



回答2:

Looks like incorrect config example in Angular docs.

Neither of this loaders process url() in css and publish assets to destination folder: 'raw', 'resolve-url', 'sass'. Despite the name, resolve-url loader just replacing relative urls to suitable for css-loader.

So, you should add css-loader to the last scss loader's config:

{
   test: /\.scss$/,
   include: helpers.root('src', 'app'),
   loaders: ['css', 'resolve-url', 'sass?sourceMap']
}

Styles require will changed to:

styles: [require('./hero-image.scss').toString()]

From docs: @import and url(...) [in css files] are interpreted like require() and will be resolved by the css-loader.



回答3:

An alternative to exports-loader?module.exports.toString() is to use the to-string-loader mentioned in the css-loader readme