Mam aplikację vue.js (wersja 2.4.4) zbudowaną za pomocą webpacka (wersja 3.6.0) i vue-loader (wersja 13.0.5).

W plikach .vue muszę zmodyfikować adres URL zawarty w atrybucie src tagów <img> zgodnie ze środowiskiem mojej aplikacji.

  • W środowisku programistycznym obrazy muszą pochodzić z folderu aplikacji ze ścieżką względną: „/src/images/exemple.png”
  • W środowisku produkcyjnym obrazy muszą pochodzić z płyty CDN, z ścieżka bezwzględna: „https://my-cdn.net/images/exemple.png"

W pliku „webpack.config.js” już rozróżniam różne środowiska za pomocą „process.env.NODE_ENV”, na przykład:

const isDev = process.env.NODE_ENV === 'dev';

Ale nie wiem, jak zmodyfikować atrybut src tagów img w moich plikach .vue za pomocą programu ładującego vue (lub czegoś innego).

Dla informacji, oto definicja modułu ładującego vue w pliku „webpack.config.js”:

{
  test: /\.vue$/,
  loader: 'vue-loader',
  options: {
    loaders: {
      'scss': [
        'vue-style-loader',
        'css-loader',
        'sass-loader'
      ]
    }
  }
}

Czy jest na to prosty sposób?

6
Baptiste 19 grudzień 2019, 19:54

4 odpowiedzi

Możesz utworzyć alias dla /src/images i zmienić adres URL w czasie transpile na podstawie środowiska:

{
//..
  resolve: {
    alias: {
      '/src/images': isDev ? '/src/images' : process.env.IMAGE_CDN + '/images'
    }
  }
}
0
Ohgodwhy 19 grudzień 2019, 19:59
1
Myślę, że to nie jest prawidłowa odpowiedź. Aliasy służą tylko do rozwiązywania problemów (gdy pakiet webpack szuka wszystkich zależności)....
 – 
Michal Levý
19 grudzień 2019, 23:25

Innym sposobem poradzenia sobie z tym byłoby użycie DefinePlugin do utworzenia zmiennej globalnej, odniesień do Twoich obrazów.

module.exports = {
  chainWebpack: config => {
    console.log('\n')
    console.log('Setting global variables:')
    console.log(`__YOUR_GLOBAL_CONSTANT__: ${JSON.stringify(process.env.YOUR_GLOBAL_CONSTANT)}`)
    console.log('\n')

    config
      .plugin('provide')
      .use(require('webpack').DefinePlugin, [{
        __YOUR_GLOBAL_CONSTANT__: JSON.stringify(process.env.YOUR_GLOBAL_CONSTANT)
      }])
  }
}

Powyższy przykład wykorzystuje plik vue.config.js, ale strategia powinna być dość podobna. Ponadto, jeśli używasz czegoś takiego jak eslint, musisz określić zmienną w sekcji globals jako readonly.

0
Chase Ingebritson 19 grudzień 2019, 20:07

Vue-loader jest wstępnie skonfigurowany do obsługi atrybutów src w komponentach pojedynczego pliku Vue, tak jak możesz patrz tutaj. Na przykład <img src="../image.png"> w szablonie jest przekształcane na:

createElement('img', {
  attrs: {
    src: require('../image.png') // this is now a module request
  }
})

To, co Webpack robi z tym require, zależy od skonfigurowanych programów ładujących. Zwykle jest skonfigurowany file-loader. Wygląda to tak (z projektu wygenerowanego przez Vue CLI + uproszczony):

module: { 
  rules: [
    {
        test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'img/[name].[hash:8].[ext]'
            }
          }
        ]
      }
  ]
}

Loader jest odpowiedzialny za skopiowanie twojego pliku do katalogu dist i zwrócenie publicznego URI, który zostanie wstawiony do atrybutu src.

Więc to, co chcesz, możesz skonfigurować tutaj, określając odpowiednie opcje. Na przykład:

options: {
  name: 'images/[name].[ext]'
  publicPath: isDev ? __webpack_public_path__ : 'https://my-cdn.net/'
}

Po prostu weź zawartość katalogu dist/images po kompilacji i wdroż ją, aby była dostępna dla https://my-cdn.net/images i powinna działać....

2
Michal Levý 19 grudzień 2019, 23:22

Piggybacking od odpowiedzi @Michael Levy:

Obecnie mam ten problem z Vue 3, @vue/cli 4.5.10 i webpackiem. Rozwiązałem to po wielu badaniach.

Konfiguracje webpacków przechodzą do vue.config.js, gdzie jest dużo abstrakcji. Aby dostroić kontrolę, możesz użyć konfiguracji łańcucha webpack. Aby Ci pomóc, użyj Vue Inspect, gdy próbujesz uzyskać dostęp do określonych ładowaczy poprzez połączenie łańcuchowe.

$ vue inspect > output.js

To da ci ładną listę wszystkich programów ładujących, których używa vue-cli.

Na przykład - aby zmodyfikować opcje obrazów webpack w vue.config.js, możesz użyć vue inspect > output.js, przeszukać plik output.js i odkryć program ładujący, który zarządza obrazami.

Czyli: /* config.module.rule('images').use('url-loader') */

Aby odpowiedzieć na pytanie - w swoim vue.config.js

module.exports = {
  chainWebpack: (config) => {
    config.module
      .rule("images")
      .use("url-loader")
      .tap((options) => {

        options.name = "images/[name].[ext]";
        options.publicPath = isDev ? __webpack_public_path__ : 'https://my-cdn.net/';

        return options;
      });
  },
};

2
Rocky Kev 12 styczeń 2021, 09:54