Skip to content

编译器

uni-simple-router V3.0 版本中,我们意识到仅依赖于uni-app的默认源码可能无法满足开发者对特定功能的需求,例如嵌套路由路由表接管pages.json以及动态增减路由表等功能。为了解决这些问题,我们引入了编译器的概念。

编译器的作用是修改uni-app的默认源码,以便在uni-simple-router的运行时实现开发者期望的功能。使用编译器,开发者无需关注源码的实现逻辑,而是更关注如何配置和使用编译器的功能。

我们很庆幸地宣布,我们的编译器在内部提供了强大的功能,并且在外部提供了简单明了的配置选项。你只需进行几行简单的配置,就可以开始使用编译器,实现你想要的功能。

vitePluginUniRouter

创建一个编译器实例,该实例为 vite 插件,直接放入 plugins 首位即可。

  • 类型

    ts
    interface InitOptionsRule {
        /**
         * 插件文件目录 可以是绝对路径也可以是相对路径
        */
        pluginPath: string;
        /**
         * 日志或者检测文件输出地址
        */
        outputDir?: string;
        /**
         * 排除文件变动时不更新上下文 动态编译输出文件
        */
        exclude?: RegExp[];
        /**
         * 排除文件成功时回调函数
        */
        excludeCallBack?: (path: string) => void;
        /**
         * 指定解索入口位置
        *
        * 如果你的项目是将所有路由表放在一个目录下,你可以指定该字段
        * 插件将不会全项目解索 只会在该入口js中解索
        * 大大提高处理速度
        *
        * 可以是绝对路径也可以是相对路径
        */
        routesMain?: null | string;
        /**
         * app 启动项
        */
        app?: {
            /**
             * 是否等待首页渲染完毕后再关闭启动界面 默认为false
            */
            alwaysShowBeforeRender?: boolean;
            /**
             * 是否自动关闭启动界面 默认为false
            */
            autoclose?: boolean;
        };
        /**
         * 小程序的编译配置
         * v1.0.4 新增
        */
        applet?:{
            /**
             * 加载页配置信息
            */
            enterPage?:{
                /**
                 * 用户自定义加载页样式风格配置
                */
                style?:Record<string,any>;
                /**
                 * 用于重新定义加载页的整体内容
                */
                content?:string
            }
        }
    }
    
    function vitePluginUniRouter(initOptions: InitOptionsRule): any[];
  • 详细

    在使用编译器时,确保将编译器配置放在vite.config.js文件的plugins数组中的首位。这样做是为了确保编译器能够优先于其他插件进行处理,以便正确地修改uni-app的默认源码。

  • 示例

    js
    import { defineConfig } from "vite";
    import uni from "@dcloudio/vite-plugin-uni";
    import vitePluginUniRouter from './src/uni-simple-router/compiler'
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [
        vitePluginUniRouter({
          pluginPath: `./uni-simple-router`,
        }),
        uni()
      ],
    });
  • 参考 指南 - 第二步配置 vite.config.js

InitOptionsRule.pluginPath

插件包文件目录,可以是绝对路径也可以是相对路径。如果你还未下载,可在此处 获得授权并下载

  • 必填

  • 示例

    ts
    export default defineConfig({
      plugins: [
        vitePluginUniRouter({
          pluginPath: `./uni-simple-router`,
          // 或者
          // pluginPath: path.resolve(
          //   process.env.UNI_INPUT_DIR,
          //   './uni-simple-router'
          // ),
        }),
        uni()
      ],
    });

陷阱提示

  • 当前只支持将 uni-simple-router 插件包放置在项目目录下,不允许放置在项目目录以外的位置。此外,对于 CLI 项目,建议将插件包放置在 src 目录下。

InitOptionsRule.outputDir

日志或者检测文件输出目录,目前会生成到插件包下的指定路径下。

  • 必填

  • 默认值

    ts
    InitOptionsRule.outputDir = `inspect`
  • 示例

    ts
    export default defineConfig({
      plugins: [
        vitePluginUniRouter({
          outputDir:`output`
        }),
        uni()
      ],
    });
  • 详细

    该配置会与 InitOptionsRule.pluginPath 路径拼接并最终得到 outputDir 目录,你只需要在该配置下设置需要输出的目录名即可。

InitOptionsRule.exclude

该配置用于排除那些不需要进行编译的文件,从而有效提高编译效率。在配置中,你应该充分地排除所有未使用 __dynamicImportComponent__ 函数的文件,因为这些文件是不需要进行编译的。

  • 必填

  • 默认值

    ts
    // 插件包目录 字符正则
    const diffPath = path
                        .relative( UNI_INPUT_DIR,initOptions.pluginPath)
                        .replace(/(\/|\\)/g,'(\\/|\\\\)')
                        +`.+(?<=\\.[A-Za-z]?js)`;
    
    const _defExclude:RegExp[]= [
        /node_modules|(\.n?vue$)|(\.scss$|\.css$|\.styl$|\.sass$)/,
        // 排除插件包目录
        new RegExp(diffPath)
    ]
  • 示例

    ts
    export default defineConfig({
      plugins: [
        vitePluginUniRouter({
          exclude:[
            /uni_modules/
          ]
        }),
        uni()
      ],
    });
  • 详细

    如果你传递了 exclude 参数,它将与默认配置正则进行合并。这意味着你仍然可以享受原有的两个默认配置正则的支持。

InitOptionsRule.excludeCallBack

它与 InitOptionsRule.exclude 配置配合使用。当在编译时遇到符合 exclude 的正则时会将文件路径传入 excludeCallBack 钩子。

  • 必填

  • 示例

    ts
    export default defineConfig({
      plugins: [
        vitePluginUniRouter({
          excludeCallBack:(gnorePath)=>{
            console.log(gnorePath)
          }
        }),
        uni()
      ],
    });

InitOptionsRule.routesMain

该配置用于指定路由表的入口位置。如果你的项目将所有路由表文件都放在同一个目录下,你可以通过设置该字段来指定入口文件,从而提高编译速度。

当你设置了 routesMain 配置后,插件将仅解析指定的入口文件,而不会遍历整个项目来搜索路由表文件。这种方式可以极大地提高处理速度,特别是在项目规模庞大时,编译速度的提升效果会更加明显。

  • 必填

  • 示例

    ts
    export default defineConfig({
      plugins: [
        vitePluginUniRouter({
          routesMain:'./router/routes.js',
        }),
        uni()
      ],
    });

    路由表文件目录

    ts
    E:\codeTest\playground\router
    ├─index.js
    ├─routes.js
    ├─routes
    |   ├─animation.js
    |   ├─custom-tabbar.js
    |   ├─demo-routes.js
    |   ├─dynamic-addRoue.js
    |   ├─guard.js
    |   ├─nesting.js
    |   ├─nvue.js
    |   ├─params.js
    |   └uni-tabbar.js

    routes.js

    ts
    import {uniTabbar} from './routes/uni-tabbar.js'
    import {customTabbar} from './routes/custom-tabbar.js'
    import {nvueRoutes} from './routes/nvue.js'
    import {paramsRoutes} from './routes/params.js'
    import {staticAddRoue} from './routes/dynamic-addRoue.js'
    import {nestingRoutes} from './routes/nesting.js'
    import {animationRoutes} from './routes/animation.js'
    import {demoRoutes} from './routes/demo-routes.js'
    import {guardRoutes} from './routes/guard.js'
    
    export const routes = [
      ...uniTabbar,
      ...customTabbar,
      ...nvueRoutes,
      ...paramsRoutes,
      ...staticAddRoue,
      ...nestingRoutes,
      ...animationRoutes,
      ...demoRoutes,
      ...guardRoutes,
    ]

    index.js

    ts
    import {
      createRouter,
    } from '@/uni-simple-router'
    import {routes} from './routes'
    
    const router = createRouter({
      platform: process.env.VUE_APP_PLATFORM,
      routes,
    })
    
    export default router
  • 详细

    强烈建议开发者在使用编译器时配置 routesMain 字段,并将所有路由表集中管理。这样做可以显著提高编译效率。你可以像上面一样,创建一个名为 routes.js 的文件,将所有的路由表集中在这个文件中,并通过导出的方式提供给 createRouter 函数作为静态路由表。

    通过集中管理路由表,你可以更好地组织和维护你的路由代码。同时,配置 routesMain 字段后,编译器只会解析指定的入口文件,而不会遍历整个项目来搜索路由表文件。这种优化可以大大减少不必要的解析工作,从而提升编译速度。

InitOptionsRule.app

用于接管项目下 manifest.json 中的 启动界面选项 配置。

  • 必填

  • 默认值

    ts
    InitOptionsRule.app = {
      /**
       * 是否等待首页渲染完毕后再关闭启动界面 默认为false
       */
      alwaysShowBeforeRender:false,
      /**
       * 是否自动关闭启动界面 默认为false
       */
      autoclose:false
    }
  • 示例

    ts
    export default defineConfig({
      plugins: [
        vitePluginUniRouter({
          alwaysShowBeforeRender:true,
          autoclose:true
        }),
        uni()
      ],
    });
  • 参考 指南 - 原生启动界面

陷阱提示

  • 如果你正在尝试修改 manifest.json->app-plus->splashscreen 中的 alwaysShowBeforeRenderautoclose,你应该在编译器中配置。

InitOptionsRule.applet 1.0.4+

用于控制小程序端编译时的配置选项。

  • 必填

  • 默认值

    版本警告

    V1.1.4 之前的版本,默认值如下:

    ts
    const WRITECONTENT = 
    `
      <template>
        <view class="bg"><view class="loading"></view></view>
    </template>
    <script>
    export default {
        data(){
            return {
                __router_main_mark__:"${env_npm_package_name}"
            }
        },
        setup(){
            const router = uni.$Router;
            if(router && router._launched){
                const start_location_normalized = router.utils.START_LOCATION_NORMALIZED();
    
                router.currentRoute.value = start_location_normalized;
                router.utils.locationAppHome(router)();
            }
        }
    }
    </script>
    <style>
    .bg{
        background-color: #fffeff;
        width: 100vw;
        height: 100vh;
        overflow: hidden;
    }
    .loading {
        position: fixed;
        top: 50%;
        left: 50%;
        width: 60rpx;
        height: 60rpx;
        margin-left: -30rpx;
        margin-top: -30rpx;
        border: 4rpx solid #000;
        border-top-color: rgba(0, 0, 0, 0.1);
        border-right-color: rgba(0, 0, 0, 0.1);
        border-bottom-color: rgba(0, 0, 0, 0.1);
        border-radius: 100%;
        animation: circle infinite 0.75s linear;
    }
    @keyframes circle {
        0% {
            transform: rotate(0);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    </style>
    `
    
    InitOptionsRule.applet = {
      enterPage:{
          style:{
              backgroundColor:`#ffffff`,
              navigationStyle:`custom`   
          },
          content:WRITECONTENT
      }
    }

    版本警告

    V1.1.4 及以后的版本,默认值如下:

    ts
    const WRITECONTENT = 
    `
    <template>
      <view class="bg"><view class="loading"></view></view>
    </template>
    <script>
    export default {
      data(){
          return {
              __router_main_mark__:"${env_npm_package_name}"
          }
      },
      onLoad(options){
          const router = uni.$Router;
          if(router && router._launched){
              const start_location_normalized = router.utils.START_LOCATION_NORMALIZED();
    
              router.currentRoute.value = start_location_normalized;
              router.utils.locationAppHome(router,false,options)();
          }
      },
    }
    </script>
    <style>
    .bg{
      background-color: #fffeff;
      width: 100vw;
      height: 100vh;
      overflow: hidden;
    }
    .loading {
      position: fixed;
      top: 50%;
      left: 50%;
      width: 60rpx;
      height: 60rpx;
      margin-left: -30rpx;
      margin-top: -30rpx;
      border: 4rpx solid #000;
      border-top-color: rgba(0, 0, 0, 0.1);
      border-right-color: rgba(0, 0, 0, 0.1);
      border-bottom-color: rgba(0, 0, 0, 0.1);
      border-radius: 100%;
      animation: circle infinite 0.75s linear;
    }
    @keyframes circle {
      0% {
          transform: rotate(0);
      }
      100% {
          transform: rotate(360deg);
      }
    }
    </style>
    `
    
    InitOptionsRule.applet = {
    enterPage:{
        style:{
            backgroundColor:`#ffffff`,
            navigationStyle:`custom`   
        },
        content:WRITECONTENT
    }
    }

InitOptionsRule.applet.enterPage 1.0.4+

用于控制编译到小程序下的默认加载页样式和内容,在这里查看 WRITECONTENT 完整内容。

  • 必填

  • 默认值

    ts
    InitOptionsRule.applet.enterPage = {
      style:{
          backgroundColor:`#ffffff`,
          navigationStyle:`custom`   
      },
      content:WRITECONTENT
    }
  • 详细

    • style 表示该加载页的风格样式,你可以在这里找到可使用的完整配置
    • content 表示加载页的完整内容,你可以重新生成自定义的风格样式。但是需要注意的是,尽管你完全自定义但是你依旧应该按照默认的内容结构及逻辑编写。也就是你可以在默认模板中改写htmlstyle部分,尽量不要去修改 script 部分。详细模板在这里找到
编译器 has loaded