Detailed explanation of the path problem of static resources in vue (in-depth good article)

Keywords: Vue.js Webpack

Foreword: require parsing in webpack

First, make it clear that the requirements used in the project configuration files such as webpack.config.js belong to the category of nodejs, and after entering index.js, the requirements in the loaded components belong to the category of webpack parsing.

Usage of require in webpack:

let url = "@/assets/images/carousel/logo.svg"
require(url)    //report errors

let url = "logo.svg"
require("@/assets/images/carousel/"+url); //correct

This is because after you modify the page, the webpack compiles and waits for the compilation. You need to package the project, and then package it correctly before you can hot load, run and refresh the page.
If a variable is passed in the require and it may be any file in any directory in the computer system, it may traverse the entire disk of your computer when packaging static resources (it's silly). Therefore, at least the path should be given, so that the corresponding file under that path can be packaged accurately. Then, when the code runs, the regular matching can be generated directly with the corresponding file name (because the packaged file may have hash value. You can't directly check the file name). After finding it, it can be loaded into the code.

So, remember to specify the path in require in as much detail as possible, and then splice the variables

Next, the path problem after packaging:

After webpack compiles and packages the static resources in the project, the generated path is no longer the original path. as

src/assets/image/logo.jpg

May become

dist/public/image/logo.1d997ea3.jpg

Through require("src/assets/image/logo.jpg"), the dist/public/image/logo.1d997ea3.jpg file will be found and loaded automatically

1, Path processing of < template > section

When Vue Loader compiles the < template > block in a single file component, it will also convert all encountered resource URL s into webpack module requests. (in this way, we don't need to call require manually, but leave it to Vue Loader)

The tag / feature combinations that Vue loader can handle by default are as follows:

{
  video: ['src', 'poster'],
  img: 'src',   //Namely img On element src attribute
  source: 'src',  //source On element src attribute
  image: 'xlink:href'
}

Facing the above label combination, Vue loader will automatically convert the resource url.

Conversion rules:
a. If the path is absolute, it is retained as is. For example, / src/assets/image/login/title.png

//code
<template>
   <img src="/src/assets/image/login/title.png" alt="">
</template>

//Rendered html page
<img data-v-70c98a68="" src="/src/assets/image/login/title.png" alt="">
//Of course, this picture cannot be displayed, because the compiled title.png is no longer under src/assets/image/login

b. If the path starts with. It will be regarded as a relative module dependency. For example. / titlea.png

//code
<img src="./titlea.png" alt="">

//Rendered html page
<img data-v-70c98a68="" src="/static/img/titlea.1e9fa570.png" alt="">

c. If the path starts with @ it is also considered a module dependency. This is useful if @ is configured with alias in your webpack configuration. All Vue cli created projects are configured to point @ to / src by default

//code
<img src="@/assets/image/login/title.png" alt="">

//Rendered html page
<img data-v-70c98a68="" src="/static/img/title.1e9fa570.png" alt="">

d. If the path starts with ~, the subsequent parts will be regarded as module dependencies. You can load both static resources with aliases and resources in node modules. as

//code
<img src="~@/assets/image/login/title.png" alt="">
//Rendered html page
<img data-v-70c98a68="" src="/static/img/title.1e9fa570.png" alt="">


//code
<img src="~[npm Package name]/xxx/logo.png" alt="">
//Rendered html page
<img data-v-70c98a68="" src="/static/img/logo.2f53e458.png" alt="">

2, Path handling for < style > section

Because Vue loader uses style loader when dealing with style, the conversion rules may be different from those in the < template > section above.
The following configurations are used inside Vue loader (not necessarily, rules can also be assigned directly through js):

//stay vue-loader Internal use of css-loader
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        loader: 'css-loader',
        options: {  
          url: true, //Default options
        },
      },
    ],
  },
};

When the url is true, it means that the string in the url can be loaded through require().

Conversion rules

a. If the path is absolute, it is retained as is. For example, / src/assets/image/login/title.png

//code
<style scoped>
.login-wrap {
  background-image: url("/src/assets/image/login/title.png");
}
</style>

//css after rendering
.login-wrap[data-v-70c98a68] {
  background-image: url(/src/assets/image/login/title.png);
}

Similarly, this picture cannot be displayed because the compiled title.png is no longer under src/assets/image/login.

b. If the path starts with. It will be regarded as a relative module dependency. For example. / titlea.png

//code
<style scoped>
.login-wrap {
  background-image: url("./titlea.png");
}
</style>

//css after rendering
.login-wrap[data-v-70c98a68] {
  background-image: url(/static/img/titlea.1e9fa570.png);
}

c. If the path starts with ~, the following parts will be regarded as module dependencies, that is, you can load static resources with aliases and resources in node modules. as

//code
<style scoped>
.login-wrap {
  background-image: url("~[npm Package name]/logo.png");
}
</style>

//css after rendering
.login-wrap[data-v-70c98a68] {
  background-image: url(/static/img/logo.e05643fc.png);
}
//code
<style scoped>
.login-wrap {
  background-image: url("~@/assets/image/login/bg.png");
}
</style>

//css after rendering
.login-wrap[data-v-70c98a68] {
  background-image: url(/static/img/bg.1d997ea3.png);
}

be careful:   Compared with the above < template >, only the url("@/assett/logo.png") starting with @ is less, so the following writing is wrong

//code
<style scoped>
.login-wrap {
  background-image: url("@/assets/image/login/bg.png");
}
</style>

Transferred from: https://segmentfault.com/a/1190000018472635

Posted by D_tunisia on Wed, 24 Nov 2021 05:33:58 -0800