【问题标题】:Ionic PWA get version number from config.xmlIonic PWA 从 config.xml 获取版本号
【发布时间】:2021-01-27 21:57:23
【问题描述】:

我想在 Ionic PWA 中显示来自 config.xml 的版本号。

使用 ionic 原生应用版本插件很容易为 ios/android 构建完成。

但是什么是 PWA 构建的好方法 (npm run build --release --prod)?

【问题讨论】:

  • 试试这个github post从配置文件中获取应用版本。
  • 我知道这个插件并且我们使用它,但它在 PWA 版本中不起作用。

标签: webpack ionic3 progressive-web-apps


【解决方案1】:

好的,所以如果 cordova-plugin-app-version 在 PWA 上不可用,访问 config.xml 文件的另一种方法是使用将版本复制到模板的 grunt 任务(如您所知,在 Ionic config.xml 文件未放置在“可服务”位置,因此无法从 config.xml 读取执行时间版本。

例如,如果我们在 package.json 中控制应用版本,我们可以配置一个 grunt 任务,将版本复制到 config.xml 和 src/index.html。

  1. package.json上设置应用版本。

    {
    "name": "my-app",
    "version": "1.0.7",
    ...
    
  2. 在您的项目上安装 grunt

    $> npm install grunt --save-dev
    $> npm install grunt-string-replace --save-dev
    
  3. 在 config.xml 和 index.html 上设置版本,并在每次发布版本时创建替换版本号的 gruntfile.js。

Config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget version="1.0.7" id="...

src/index.html

<head>
      <meta charset="UTF-8">
      <title>Ionic App</title>
      <meta name="version" content="1.0.7">
      ...

gruntfile.js

    module.exports = function(grunt) {
    // Project configuration.
    grunt.initConfig({
      pkg: grunt.file.readJSON('package.json'),
      // replace version to config.xml
      'string-replace': {
        inline:{
          files: {
             'config.xml': 'config.xml',
          },
          options: {
            replacements: [{
              pattern: /widget version="([\d\D]*?)"/ig,
              replacement: 'widget version="' + '<%= pkg.version %>"'
            }]
          }
        }
      },
      // replace version to index.html
      'string-replace': {
        inline:{
          files: {
            'src/index.html': 'src/index.html',
          },
          options: {
            replacements: [{
              pattern: /name="version" content="([\d\D]*?)"/ig,
              replacement: 'name="version" content="' + '<%= pkg.version %>"'
            }]
          }
        }
      },
    });

    grunt.loadNpmTasks('grunt-string-replace');

    // Default task(s).
    grunt.registerTask('default', ['string-replace']);

    };
  1. 使用 Meta 组件,如果插件不可用,则从 index.html 中读取版本。

    import { AppVersion } from '@ionic-native/app-version';
    import { Platform } from 'ionic-angular';
    import { Meta } from '@angular/platform-browser';
    ...
    @IonicPage({
      name: 'main'
    })
    @Component({
      selector: 'page-main',
      templateUrl: 'main.html',
    })
    export class MainPage {
      protected versionNumber: string;
      constructor(private app: AppVersion, private meta: Meta) {
        if (this.platform.is('cordova')) {
          this.appVersion.getVersionNumber().then(
            (v) => { this.versionNumber = v;},
            (err) => { 
              // PWA
              const viewport = this.meta.getTag('name=version');
              this.versionNumber = viewport.content;
            }
          );
        }else{
          // Debug
          const viewport = this.meta.getTag('name=version');
          this.versionNumber = viewport.content;
        }
      }
      ...
    
  2. 在您的 html 模板上打印应用版本号。

    <div  class="app-version" text-center>version {{ versionNumber }}</div>
    

【讨论】:

  • 对于那些第一次这样做的人: 1. 首先阅读 Grunt gruntjs.com/getting-started 2. 如果一切设置正确,在终端中运行“grunt default”后,您将看到消息“2 个文件已更改”。 3. 为避免手动运行“grunt default”,请更新主 package.json 中的“start”:“grunt default && ng serve”行。每次您执行“npm start”时,它都会为您运行 grunt。重要提示:检查代码中文件的路径,尤其是在多应用项目中。
【解决方案2】:

找到了使用自定义 webpack 配置和 webpack.DefinePlugin 完成所有这些工作的正确方法。它在任何地方都可以工作,在ionic serve 期间也是如此(我需要,因为我将它发送到 API),而不仅仅是在真实设备上作为 cordova-plugin-app-version。只有当你做ionic serve --devappissue in @ionic/angular-toolkit)时它不起作用的地方

以下所有内容均适用于 Ionic 4(Angular 7):

  • 添加@angular-builders/custom-webpack@7 @angular-builders/dev-server@7 开发包和yarn add @angular-builders/custom-webpack@7 @angular-builders/dev-server@7 --dev
  • 需要将angular.json中的architect.build和architect.serve builder替换为新的:
...
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./custom.webpack.config.js"
            },
...
...
        "serve": {
          "builder": "@angular-builders/dev-server:generic",
          "options": {
            "browserTarget": "app:build"
          },
...
  • 使用下一个内容创建 custom.webpack.config.js:
const webpack = require('webpack');
console.log('[WEBPACK] custom.webpack.config.js is loaded');

function getAppVersion() {
  const fs = require('fs');
  const DOMParser = require('xmldom').DOMParser;

  const content = fs.readFileSync('./config.xml').toString('utf-8');
  const config = new DOMParser().parseFromString(content, 'text/xml');
  return config.getElementsByTagName('widget')[0].getAttribute('version');
}


module.exports = (config, options) => {
  config.plugins.push(
    new webpack.DefinePlugin({
      'APP_VERSION': JSON.stringify(getAppVersion()),
    }),
  );

  return config;
};
  • 如果一切正确,运行应用程序时您将在终端中看到[WEBPACK] custom.webpack.config.js is loaded
  • 现在全局变量 APP_VERSION 将被注入并且应该在应用程序的任何地方都可用。 console.log('APP_VERSION', APP_VERSION);。有了它,您可以注入其他变量,例如仅在构建时知道的变量或添加其他自定义 Webpack 插件。
  • 您可能需要将 TypeScript 的 APP_VERSION 定义添加到您的 custom-typings.d.ts 中,如下所示:
// Variables injected by webpack DefinePlugin
declare const APP_VERSION: string;

【讨论】:

    【解决方案3】:

    我认为 @pablo.nunez 提供了正确的解决方案,但对我来说,我必须在 Gruntfile.js 中进行一些小修改才能同时成功更改 index.htmlconfig.xml 文件。

    这是我修改后的 Gruntfile.js:

    module.exports = function(grunt) {
      // Project configuration.
      grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        // replace version to config.xml and index.html in the same action
        'string-replace': {
          inline: {
            files: {
              'config.xml': 'config.xml',
              'src/index.html': 'src/index.html'
            },
            options: {
              replacements: [
                {
                  pattern: /widget id="([\d\D]*?)" version="([\d\D]*?)"/gi,
                  replacement: 'widget id=' + '"$1"' + ' version="' + '<%= pkg.version %>"'
                },
                {
                  pattern: /name="version" content="([\d\D]*?)"/gi,
                  replacement: 'name="version" content="' + '<%= pkg.version %>"'
                }
              ]
            }
          }
        }
      });
    
      grunt.loadNpmTasks('grunt-string-replace');
    
      // Default task(s).
      grunt.registerTask('default', ['string-replace']);
    };
    
    

    我还整合了一个事实,即在 IONIC 4 (Angular) 项目中,项目 id 会在 config.xml 文件中的版本号之前自动替换。

    【讨论】:

      【解决方案4】:

      一种更简单的方法,适用于在 ionic 4 中只有 PWA 的人

      1. src/index.html

        <head>
        <meta charset="utf-8"/>
        <title>title App</title>
        <meta name="version" content="0.0.1">
        ....
      

      2。 page.ts

        ...
        ionViewWillEnter() {
          console.log('ionViewWillEnter');
          const aux: any = document.getElementsByTagName('META');
          // tslint:disable-next-line:prefer-for-of
          for (let i = 0; i < aux.length; i++) {
           if (aux[i].name === 'version') {
             this.versionNumber = aux[i].content;
            }
          }
        }
        ....
      

      3. page.html

        ....
        <div *ngIf="versionNumber">
          <ion-text color="dark">
            <p>{{versionNumber}}</p>
          </ion-text>
        </div>
        ....
      

      【讨论】:

        【解决方案5】:

        使用https://github.com/whiteoctober/cordova-plugin-app-version,您可以从控制器或模板访问您的 config.xml 版本。

        使用 Ionic 4,添加 Cordova 插件和 Ionic Native 包装器:

        $ ionic cordova plugin add cordova-plugin-app-version
        $ npm install @ionic-native/app-version
        

        并将 AppVersion 作为提供程序添加到您的页面 main.ts 中

        import { AppVersion } from '@ionic-native/app-version';
        import { Platform } from 'ionic-angular';
        ...
        @IonicPage({
          name: 'main'
        })
        @Component({
          selector: 'page-main',
          templateUrl: 'main.html',
        })
        export class MainPage {
           protected versionNumber: string;
           constructor(private app: AppVersion) {
              if (this.platform.is('cordova')) {
                 this.appVersion.getVersionNumber().then(
                    (v) => { this.versionNumber = v;}
                 );
              }else{
                 this.versionNumber = '???';
              }
           }
           ...
        

        然后在您的 .html 模板 main.html 上,您可以打印应用程序版本号:

        <div  class="app-version" text-center>version {{ versionNumber }}</div>
        

        另外(阅读官方文档),您可以访问appName、appPackageName、appVersionCode和appVersionNumber。

        【讨论】:

        • 但这并不能解决我没有可用插件的 PWA 的问题,对吧?
        • 是的,我为 PWA 提出了另一种解决方案:stackoverflow.com/questions/48231990/…
        • 太棒了。会试试那个。谢谢。
        【解决方案6】:

        我创建了一个 npm 模块,它为您的 Ionic 项目生成一个 buildInfo.ts 文件 - 然后您可以导入该文件并获取构建号和构建日期。您可以在此处找到该模块:https://www.npmjs.com/package/ionic-build-info

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-10-26
          • 2015-04-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-23
          • 2018-04-01
          相关资源
          最近更新 更多