[英]How to replace images and files at build without referencing them in the app?
We are rewriting our existing Angular 8 PWA to Vuejs and we are facing a few issues concerning the build process.我们正在将现有的 Angular 8 PWA 重写为 Vuejs,我们在构建过程中面临一些问题。 (We are not here to discuss the reasons of that choice nor anyone's opinion on it) (我们不是来讨论这个选择的原因,也不是任何人对此的看法)
Our app must be built for different customers with specific assets for each customers (manifest.json file, icons and images).我们的应用程序必须为不同的客户构建,为每个客户提供特定的资产(manifest.json 文件、图标和图像)。
In Angular, we accomplish file replacements by defining rules in angular.json file using the fileReplacements key like this:在 Angular 中,我们通过使用 fileReplacements 键在 angular.json 文件中定义规则来完成文件替换,如下所示:
"configurations": {
"production-customer-a": {
"fileReplacements": [
{
"replace": "src/manifest.json",
"with": "src/environments/customer-a/assets/manifest.json"
},
],
// Some more json stuff
We tried to implement a similar process in our vue app in vue.config.js using webpack's NormalModuleReplacementPlugin like this:我们尝试使用 webpack 的 NormalModuleReplacementPlugin 在 vue.config.js 中的 vue 应用程序中实现类似的过程,如下所示:
configureWebpack: () => {
let plugins;
switch (customer) {
case customer-a:
plugins = [
new NormalModuleReplacementPlugin(
/\.\.\/public\/manifest\.json/,
"../environments/customer-a/assets/manifest.json"
),
// Some more config
It works great if the concerned files are actually referenced in the app using its url at build .如果相关文件实际上是在应用程序中使用其在 build 中的 url引用的,则效果很好。 Let me explain with an example:让我用一个例子来解释:
<img src="@/assets/myImageWhichShouldBeReplacedAtBuild.png" /> /* Will actually be replaced and the dist folder will contain the file properly */
<img src="@/assets/myImageWhichShouldBeReplacedAtBuildButIsBase64EncodedWithWebpackUrlLoader.png" /> /* Will be replaced as the base64 string but the dist folder wont contain the file and might be an issue if the image is to be used by files like manifest.json */
The later is not a complete issue since we can override webpack's url-loader in vue.config.js like explained here .后者不是一个完整的问题,因为我们可以在 vue.config.js 中覆盖 webpack 的 url-loader,就像这里解释的那样。 But still a good catch to know about.但仍然是一个很好的了解。
Since we don't reference files like manifest.json or favicon.ico in the Vue templates, those files are not replaced .由于我们没有在 Vue 模板中引用 manifest.json 或 favicon.ico 等文件,因此不会替换这些文件。
Is there anyway to make sure every file we need will be replaced at build to obtain the same result as with Angular's angular.json config file ?无论如何要确保我们需要的每个文件都将在构建时被替换以获得与 Angular 的 angular.json 配置文件相同的结果? Maybe using something different than NormalModuleReplacementPlugin ?也许使用与 NormalModuleReplacementPlugin 不同的东西?
So for any lost soul that comes around here, we managed to find a proper solution.因此,对于来到这里的任何迷失灵魂,我们设法找到了合适的解决方案。
We got rid of webpack's NormalModuleReplacementPlugin and worked in combination with a task runner (gulp, in our case) and Vue static assets handling.我们摆脱了 webpack 的 NormalModuleReplacementPlugin 并结合了任务运行器(在我们的例子中是 gulp)和 Vue 静态资产处理。
Since the concerned assets where always the same, we put the default ones in the public folder of the solution and recreated the same structure in our environments folders for each customer.由于相关资产始终相同,我们将默认资产放在解决方案的公共文件夹中,并在我们的环境文件夹中为每个客户重新创建相同的结构。
-public
--img
---icons
-environments
--customer
---img
----icons
Making use of Vue's URL transform rule , we referenced all our assets in the app with an absolute path, so the files won't go through webpack's processing.利用Vue 的 URL 转换规则,我们使用绝对路径引用应用程序中的所有资产,因此文件不会经过 webpack 的处理。 After the build, we run our gulpfile that takes all the customer's assets (passed as argument) and override them in the dist folder.在构建之后,我们运行我们的 gulpfile,它获取所有客户的资产(作为参数传递)并在 dist 文件夹中覆盖它们。
gulpfile.js: gulpfile.js:
const gulp = require('gulp');
const yargs = require('yargs').argv;
gulp.task('moveassets', () => {
return gulp.src(`environments/${yargs.customer}/**/**/**`)
.pipe(gulp.dest('dist'));
})
package.json script: package.json 脚本:
"build:customer": "vue-cli-service build && gulp moveassets --customer customer"
It might cause a bit of trouble with cache handling since webpack would have put hashes to files, but Angular is not doing it also so it won't change our habits.它可能会导致缓存处理有点麻烦,因为 webpack 会将哈希值放入文件中,但 Angular 也没有这样做,因此它不会改变我们的习惯。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.