Conditional compilation of <template> and <script> tags



  • When building the same app for Web & Capacitior targets I’m having errors in such simple code:

    import { Plugins } from '@capacitor/core'
    const { SplashScreen } = Plugins
    

    as this module is not defined in Web but defined in Capacitor. So some problems exists with rendering widgets at mobiles that have software buttons so max-height CSS for them must have different value than Web.

    How people solve this problem ?

    The main idea is to have something like:

    <template>
    #ifdef _capacitor_
    ...
    #endif
    </template>
    
    <script>
    #ifdef _capacitor_
    import 'some capacitor specific'
    #endif
    </script>
    


  • Any solutions ?



  • @Sfinx

    here’s a thread about platform conditional import:
    https://forum.quasar-framework.org/topic/6894/spa-capacitor-dynamic-import-capacitor-plugins/3

    rendering widgets at mobiles that have software buttons so max-height CSS

    you can use all kinds of different techniques here. For example:

    1. use entire different template\component\layout for mobile. This is more work but also is more customizable.

    2. use different classes on elements with platform conditions.

    3. Use the screen size ( not platform type ) to conditionally render entire components.

    example for 1, this project uses different layout/components for different modes( electron, web, ect):
    https://github.com/vycoder/qodo

    example for 2, apply bg-red and text-white class if on capacitor, otherwise apply bg-yellow:

    <aComponent :class="{ 'bg-red text-white': isCapacitor, bg-yellow: !isCapacitor}"</aComponent >
    ...
    computed: {
        isCapacitor () {
          return process.env.MODE === 'capacitor'
        }
    }
    

    example for 3, myComponent will only render when screen size is greater than small:

    <myComponent class="gt-sm">
    

    See:
    https://quasar.dev/style/visibility#Window-Width-Related

    Other usefull links:
    https://quasar.dev/style/body-classes



  • Thanks but late 😉 Solved more elegant with webpack-preprocessor-loader. It works everywhere:


    // #!if capacitor
    import capModule from ‘module-name’;
    // #!else
    const anotherModule = import(‘another-module-name’);
    // #!endif

    <!-- #!if capacitor -->
    <some tag />
    <!-- #!endif -->

    Sure the runtime platform check is still used but I think it is really intended for another things.



  • It is really pitty that quasar do not pass to webpack any info about platform type build so using ENV for now



  • @Sfinx it’s inside your ctx.mode in your quasar.conf.js export. https://quasar.dev/quasar-cli/quasar-conf-js#The-basics in other files like dobbel suggested https://quasar.dev/quasar-cli/handling-process-env. it’s already doable without extra package.



  • Aaa, you rocks ! ctx was commented out at the top… But who is looking at the top, really ? For anyone needed this:

    ...
         chainWebpack (chain, { isServer, isClient }) {
            chain.module.rule('preprocessor')
              .test(/\.(js|vue)$/)
              .enforce('pre')
              .exclude
              .add((/[\\/]node_modules[\\/]/))
              .end()
              .use('webpack-preprocessor-loader')
              .loader('webpack-preprocessor-loader')
              .options({
                params: {
                  capacitor: (ctx.modeName == 'capacitor')
                },
                directives: {
                  capacitor: (ctx.modeName == 'capacitor')
                }
            })
          },
    ...
    


  • @Sfinx

    For what purpose do pass this info to webpack ?



  • See subject. The purpose to have conditionally compiled code depending from platform. This way you can freely use any module for each without any unusable and complex runtime checks.


Log in to reply