如何使用 webpack 和 vue-loader 更改 .vue 文件中 <img> 的 src 属性?

Posted

技术标签:

【中文标题】如何使用 webpack 和 vue-loader 更改 .vue 文件中 <img> 的 src 属性?【英文标题】:How to change the src attribute of <img> in .vue files with webpack and vue-loader? 【发布时间】:2020-04-12 07:12:48 【问题描述】:

我有一个使用 webpack(3.6.0 版)和 vue-loader(13.0.5 版)构建的 vue.js(2.4.4 版)应用程序。

在.vue文件中,我需要根据我的应用环境修改&lt;img&gt;标签的src属性中包含的url。

在开发环境中,图片必须来自 应用程序文件夹,相对路径:“/src/images/exemple.png” 在生产环境中,图片必须来自cdn,带有 绝对路径:“https://my-cdn.net/images/exemple.png”

在“webpack.config.js”文件中,我已经使用“process.env.NODE_ENV”区分了不同的环境,如下所示:

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

但我不知道如何使用 vue-loader(或其他东西)修改我的 .vue 文件中 img 标签的 src 属性。

有关信息,这里是“webpack.config.js”文件中vue-loader的定义:


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

有没有简单的方法来做到这一点?

【问题讨论】:

【参考方案1】:

您可以为/src/images 创建一个别名,并在编译时根据环境更改 url:


//..
  resolve: 
    alias: 
      '/src/images': isDev ? '/src/images' : process.env.IMAGE_CDN + '/images'
    
  

【讨论】:

我认为这不是正确的答案。别名仅用于解析(当 webpack 正在寻找所有依赖项时)......【参考方案2】:

解决此问题的另一种方法是使用DefinePlugin 创建一个全局变量,供您的每个图像引用。

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)
      ])
  

上面的例子使用了vue.config.js file,但策略应该非常相似。此外,如果您使用的是 eslint 之类的东西,则需要将 globals 部分中的变量指定为只读。

【讨论】:

【参考方案3】:

Vue-loader 已预先配置为处理 Vue 单文件组件中的 src 属性,就像 see here 一样。所以例如模板中的&lt;img src="../image.png"&gt;被转化为:

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

Webpack 用这个require 做什么取决于配置的加载器。通常有一个file-loader 配置。它看起来像这样(来自 Vue CLI + 简化生成的项目):

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

Loader 负责将您的文件复制到dist 目录并返回公共URI,该URI 将插入到src 属性中。

所以你可以在这里配置你想要的,通过指定正确的options。例如:

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

只需在构建后获取dist/images 目录的内容并部署它,以便https://my-cdn.net/images 可以访问它并且它应该可以工作....

【讨论】:

【参考方案4】:

借鉴@Michael Levy 的回答:

我目前在使用 Vue 3、@vue/cli 4.5.10 和 webpack 时遇到了这个问题。经过大量研究,我已经解决了。

Webpack 配置进入vue.config.js,那里有很多抽象。要微调控制,您可以使用chain webpack configs。为了帮助您,当您尝试通过链接访问特定加载程序时,请使用 Vue Inspect

$ vue inspect > output.js

这将为您提供 vue-cli 正在使用的所有加载程序的一个很好的列表。

例如 - 要修改 vue.config.js 中的 webpack 图像选项,您可以使用 vue inspect &gt; output.js,搜索 output.js 文件,然后找到管理图像的加载程序。

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

回答这个问题 - 在你的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;
      );
  ,
;

【讨论】:

以上是关于如何使用 webpack 和 vue-loader 更改 .vue 文件中 <img> 的 src 属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Vue-Loader / Webpack 指向外部(动态)资产

使用 vue-loader 和 webpack2 加载 Stylus 库和全局工作表

如何在 Vue+webpack+vue-loader 项目中从不同的 js 文件中导入函数

组件的 vue.js 自定义 css(没有 webpack 和 vue-loader)

vue24-webpack+vue-loader

由搭建Vue.js了解webpack,vue-loader和热重载