我有一个使用 webpack(版本 3.6.0(和 vue-loader(版本 13.0.5(构建的 vue.js(版本 2.4.4(应用程序。
在 .vue 文件中,我需要根据我的应用程序环境修改<img>
标签的 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'
]
}
}
}
有没有简单的方法可以做到这一点?
捎带@Michael Levy的回答:
我目前在 Vue 3、@vue/cli 4.5.10 和 webpack 中遇到了这个问题。经过大量研究,我已经解决了它。
Webpack 配置进入vue.config.js
,其中有很多抽象。要微调控制,您可以使用链式 webpack 配置。为了帮助您,请在尝试通过链接访问特定加载程序时使用Vue Inspect
。
$ vue inspect > output.js
这将为您提供 vue-cli 正在使用的所有加载程序的漂亮列表。
例如 - 要在vue.config.js
中修改 webpack 图像选项,您可以使用vue inspect > 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;
});
},
};
Vue-loader
被预配置为处理 Vue 单个文件组件中的src
属性,如下所示。例如,模板中的<img src="../image.png">
转换为:
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]'
}
}
]
}
]
}
加载器负责将文件复制到dist
目录中并返回公共 URI,该 URI 将插入到src
属性中。
因此,通过指定正确的选项,可以在此处配置所需的内容。例如:
options: {
name: 'images/[name].[ext]'
publicPath: isDev ? __webpack_public_path__ : 'https://my-cdn.net/'
}
只需在构建后获取dist/images
目录的内容并部署它,以便https://my-cdn.net/images
可以访问它,它应该可以工作......
您可以为/src/images
创建别名,并根据环境在转译时更改网址:
{
//..
resolve: {
alias: {
'/src/images': isDev ? '/src/images' : process.env.IMAGE_CDN + '/images'
}
}
}
处理此问题的另一种方法是使用 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
文件,但策略应该非常相似。此外,如果您使用的是 eslint 之类的东西,则需要将全局部分中的变量指定为只读。