亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue CLI3搭建的項(xiàng)目中路徑相關(guān)問題的解決

 更新時(shí)間:2018年09月17日 11:25:44   作者:billychan  
這篇文章主要介紹了Vue CLI3搭建的項(xiàng)目中路徑相關(guān)問題的解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

這是開頭

最近在試水 Vue CLI 3,并且嘗試配置一個(gè)多頁面(多應(yīng)用)項(xiàng)目出來,期間又遇到各種路徑問題,于是...于是有了下面的嘮叨。

以下都是基于 Vue CLI 3 來舉例說明的,使用 2.x 版本的其實(shí)也類似

首先,參考 官方文檔對靜態(tài)資源處理的說明,并通過自己的實(shí)踐,可以總結(jié)出以下內(nèi)容

靜態(tài)資源可以通過兩種方式進(jìn)行處理:

1、以下情況下,資源不會被 webpack 處理,而是被直接拷貝:

  1. 放置在 public 目錄下,即使未被使用。
  2. 通過絕對路徑被引用,即以 / 開頭的路徑。

2、以下情況下,資源會被 webpack 處理(URL的resolve、minify、uglify、轉(zhuǎn) base64 等):

  1. 使用 JavaScript 導(dǎo)入。
  2. 在 template/CSS 中通過相對路徑(即以 . 開頭或直接以文件(夾)名開頭)被引用。
  3. URL 以 ~ 開頭,其后的任何內(nèi)容都會作為一個(gè)模塊請求被解析。
  4. URL 以 @ 開頭,它也會作為一個(gè)模塊請求被解析(@ 是在 webpack 設(shè)置的 alias)。

我們應(yīng)該根據(jù)實(shí)際情況去選擇我們要引用的資源是否要被處理,然后用對應(yīng)的、正確的方式去引用它們以達(dá)到目的。以下對使用絕對路徑和相對路徑的方法和注意事項(xiàng)進(jìn)行描述。

使用絕對路徑

默認(rèn)情況下,Vue CLI 會假設(shè)你的應(yīng)用是被部署在一個(gè)域名的根路徑上(對應(yīng)選項(xiàng) baseUrl: '/'),例如 https://www.my-app.com/。如果應(yīng)用被部署在一個(gè)子路徑上,你就需要用這個(gè)選項(xiàng)指定這個(gè)子路徑。例如,如果你的應(yīng)用被部署在 https://www.my-app.com/my-app/,則設(shè)置 baseUrl 為 /my-app/。正因?yàn)橐陨系目赡芮闆r,我們應(yīng)該在打算引用純靜態(tài)資源(那些不被webpack處理的資源,一般就是 public 目錄下的資源)的時(shí)候,都確保使用 baseUrl 作為 URL 的開頭,以下列舉在不同文件中配合 baseUrl 選項(xiàng)寫絕對路徑的使用方法和注意事項(xiàng):

在入口html文件中使用

我們可以使用lodash template 語法插入 baseUrl:

<link rel="icon" href="<%= BASE_URL %>favicon.ico" rel="external nofollow" >

在 *.vue 中使用

我們可以通過 Vue CLI 提供的客戶端環(huán)境變量 process.env.BASE_URL 來獲取 baseUrl:

/* 在需要的組件中定義 baseUrl,然后在 <template> 下使用 */
<template>
  <div id="app">
    <img :src="imgUrl">
    <img :src="`${baseUrl}imgs/my_image.png`">
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      baseUrl: process.env.BASE_URL,
      isBigImg: Math.random() > 0.5
    }
  }
  computed: {
    // 動態(tài)地獲取不同的靜態(tài)資源
    imgUrl() {
      if (this.isBigImg) {
        return `${baseUrl}imgs/my_image_big.png`
      } else {
        return `${baseUrl}imgs/my_image.png`
      }
    }
  }
};
</script>

 
/* 個(gè)人建議可以在全局定義,減去在每個(gè)組件內(nèi)定義的麻煩
Vue.prototype.$baseUrl = process.env.BASE_URL
// 在 <template> 下使用
<img :src="`${$baseUrl}imgs/my_image.png`">

在其他 js 模塊中使用

import axios from 'axios';

const baseUrl = process.env.BASE_URL;

axios.defaults.baseURL = `http://www.example.com${baseUrl}api/`

在樣式文件中使用(以 sass/scss 為例)

因?yàn)?sass 文件中無法獲取環(huán)境變量或 webpack 內(nèi)的配置,于是最直接的方法就是自定義一個(gè)變量,然后在每個(gè)需要使用到它的文件引用它。

// config.scss
$baseUrl: "/";

// icon.scss

@import "config"

.icon-test {
  display: inline-block;
  background: url($baseUrl + 'imgs/icon_test.png') no-repeat;
  width: 10px;
  height: 10px;
}

這樣做還是有比較大的麻煩:

  • 如果生產(chǎn)環(huán)境和開發(fā)環(huán)境的 baseUrl 不同,每次轉(zhuǎn)換環(huán)境去編譯都要去手動修改這個(gè)變量,十分之麻煩而且可能出現(xiàn)錯(cuò)誤;
  • 兩處地方相同的定義,不方便代碼的維護(hù);
  • 在后續(xù)講到的關(guān)于 相對路徑 的坑會涉及到,每次引用 config.scss 的路徑并不一定是一樣的,且很容易出現(xiàn)編譯錯(cuò)誤;

那么,有沒有什么辦法能避免人工操作、避免多次的定義并且避免使用可能潛在錯(cuò)誤的引用呢?幸虧的確是有的! sass-loader 提供了一個(gè) data 選項(xiàng),可以為全局注入變量或樣式文件;

// vue.config.js

const baseUrl = process.env.NODE_ENV === 'production' ? '/sub/' : '/';

module.exports = {
  baseUrl,

  css: {
    loaderOptions: {
      sass: {
        data: `$baseUrl: "${baseUrl}";`
      }
    }
  }
}

這樣我們就可以在全局的 `sass` 文件中使用 `$baseUrl` 這個(gè)變量了,而且在只定義一次的情況下,能根據(jù)編譯環(huán)境變化而變化。

使用相對路徑

使用相對路徑也會存在一些坑,接下來會列舉常見的關(guān)于相對路徑的坑與解決方法:

JavaScript 動態(tài)引用資源,編譯沒報(bào)錯(cuò),但頁面上請求返回 404

有時(shí)候我們需要使用 JavaScript 動態(tài)的引用某些資源,且希望這些資源被 webpack 一同打包,我們先看這種做法:

computed: {
  background () {
    return `./bgs/${this.id}.jpg`
  }
}

我們會發(fā)現(xiàn)打包沒報(bào)錯(cuò),但是在頁面上可以發(fā)現(xiàn)這些資源的請求都是 404。這是因?yàn)轭愃?./bgs/${this.id}.jpg 這樣的動態(tài)字符串在打包階段不會被 webpack 識別為依賴,資源也就不會被打包了。為了讓 webpack 識別這些依賴,我們可以這樣做:

computed: {
  background () {
    return require('./bgs/' + this.id + '.jpg')
  }
}

通過使用 require() 讓 webpack 將括號內(nèi)的 URL 識別為一個(gè)依賴并傳入對應(yīng)的 loader 進(jìn)行處理。

要特別注意,以上的例子中,./bgs/ 目錄下的所有圖片都會被打包,因?yàn)?webpack 無法得知頁面在運(yùn)行時(shí)會使用哪張圖片,所以 webpack 會把所有的圖片都打包了。

在 sass 中使用相對路徑引用圖片或字體文件,編譯報(bào)錯(cuò)

先來看一個(gè)例子:

// 文件目錄
// src
// |--assets
// |  |
// |  |-fonts
// |  |  |- iconfont.eot
// |  |
// |  |-css
// |    |
// |    |-iconfont.scss
// |
// |--app.vue
// iconfont.scss
@font-face {
  font-family: "iconfont";
  src: url("../fonts/iconfont.eot");
  ...
}
// app.vue
<style lang="scss">
@import './assets/css/iconfont.scss'
</style>

往往我們在打包的時(shí)候會報(bào)錯(cuò)(以上例子會報(bào)錯(cuò)),說找不到 iconfont.eot。 sass-loader 文檔中有對 url() 進(jìn)行了單獨(dú)的說明

Since Sass/libsass does not provide url rewriting, all linked assets must be relative to the output.

If you're just generating CSS without passing it to the css-loader, it must be relative to your web root.
If you pass the generated CSS on to the css-loader, all urls must be relative to the entry-file (e.g. main.scss).

大致意思就是, sass-loader 并不提供 url 的重寫,所有的 scss 文件被 sass-loader 處理成最終的 CSS 后(編譯過程中 url 不會被重寫即保持原樣),再傳遞給 css-loader 處理。也就是說,所有的 url 都是相對于輸出的!在 Vue CLI 搭建的項(xiàng)目中,它們都是相對于使用這些 scss 文件的 vue 文件的。對于上例,是相對于 app.vue 的,因此報(bào)錯(cuò)。我們會很自然的會希望路徑的引用是相對于 scss 文件本身的,sass-loader 文檔中也給出了解決方案:

Add the missing url rewriting using the resolve-url-loader. Place it before the sass-loader in the loader chain.
Library authors usually provide a variable to modify the asset path. bootstrap-sass for example has an $icon-font-path. Check out this working bootstrap example.

第一個(gè)方法:使用 resolve-url-loader 來彌補(bǔ) sass-loader 缺失的 url 重寫功能,注意要放到 sass-loader 以前調(diào)用。

第二個(gè)方法:Library 作者一般都會提供變量,用來設(shè)置資源路徑,如 bootstrap-sass 可以通過 $icon-font-path 來設(shè)置。參見this working bootstrap example。

這樣看來解決的思路有兩種:

  1. 寫 url 的時(shí)候就寫 vue 文件相對于資源的路徑。這種方法較為暴力,當(dāng)項(xiàng)目層級復(fù)雜了之后容易寫錯(cuò)路徑(加上現(xiàn)有的編輯器、IDE應(yīng)該認(rèn)為你寫的路徑是錯(cuò)誤的)。當(dāng)同個(gè) scss 文件被多個(gè)不同層級的 vue 文件引用的時(shí)候,這種暴力的方法就行不通了!
  2. 使用第三方庫補(bǔ)充 sass-loader 的路徑重寫功能,讓路徑的引用是相對于當(dāng)前 scss 文件本身的。這個(gè)方法能較好的解決問題。

在這里提供一下我喜歡的方法。與其考慮 讓路徑的引用是相對于 scss 文件本身 或 讓路徑直接相對于 vue 文件,我們可以換個(gè)思路,讓所有路徑都是以根目錄往下找,并讓 webpack 對路徑進(jìn)行重寫,但是直接用 /src/ 這種絕對路徑的寫法會讓這些資源不被 webpack 打包。在前文提及到的,webpack 有個(gè)強(qiáng)大的機(jī)制,也就是 ~,通過在 url 前面添加 ~ 可以告訴 webpack 要把它當(dāng)做一個(gè)模塊來處理,也就是會被 webpack 打包。配合 webpack 提供的別名 @(/src),我們可以對上例做修改:

// iconfont.scss
@font-face {
  font-family: "iconfont";
  src: url("~@/assets/fonts/iconfont.eot");
  ...
}

這樣子,通過 webpack 對模塊的處理,可以正確通過編譯!這樣做的好處是可大大避免書寫相對路徑可能產(chǎn)生的錯(cuò)誤,每次只需“無腦”從根目錄往下找就是了,又可以減小依賴、減少配置項(xiàng)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論