Skip to content

Add a vue-cli resolve-url-loader example #2099

@Hebilicious

Description

@Hebilicious

What problem does this feature solve?

Looking for similar things in the issues, the only one I could find was this one #1019.

I'll use font awesome to illustrate :

This is the project structure :

/node_modules/font-awesome

/src/folder/MyComponent.vue

This style bloc in MyComponent.vue:

...
<style lang="scss">
@import '~font-awesome/scss/font-awesome';
//...
</style>

Throws this error :

These relative modules were not found:

* ../fonts/fontawesome-webfont.eot in ./node_modules/css-loader??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib??ref--8-oneOf-1-2!./node_modules/sass-loader/lib/l
oader.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/folder/MyComponent.vue?vue&type=style&index=0&lang=scss

EDIT : Here's a reproduction repository : https://github.com/Hebilicious/vue-cli-relative-url-import-issue-test
The font files are relative to '~font-awesome/scss/font-awesome', but webpack tries to resolve them relatively to 'MyComponent.vue'.

https://github.com/bholloway/resolve-url-loader solve this problem elegantly, but it needs to be 'placed' directly right after css loader :

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

According to https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader

TIP

For CSS related loaders, it's recommended to use css.loaderOptions instead of directly targeting loaders via chaining. This is because there are multiple rules for each CSS file type and css.loaderOptions ensures you can affect all rules in one single place.

I don't see any straightforward way to do it for all the styling related rules for vue cli with chain webpack.

There's a possible (very) dirty workaround, which is to modify @vue/cli-service/lib/config.css.js :

module.exports = (api, options) => {
   //...
    function createCSSRule (lang, test, loader, options) {
      //...
      function applyLoaders (rule, modules) {
       //...
        rule
          .use('css-loader')
          .loader('css-loader')
          .options(cssLoaderOptions)

       //Add resolve-url-loader here

        rule
          .use('resolve-url-loader')
          .loader('resolve-url-loader')
          .options({ //... })

Other ways to go around the problem is to actually have the assets at the relative path file from your source files, or to modify the font-awesome import statements, which isn't ideal.

What does the proposed API look like?

If there's a way to do it currently with chain webpack, documenting it would be very helpful.

Otherwise this ...

module.exports = {
  css: {
    loaderOptions: {
      resolveUrl: {
        // options here 
      }
    }
  }
}

...would be ideal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions