egova-treasure 項(xiàng)目架構(gòu)觀后有感

1. 開(kāi)發(fā)自由度與開(kāi)發(fā)疑問(wèn)

1.項(xiàng)目腳手架依賴的組件包來(lái)源于私有庫(kù)子項(xiàng)目的 egova-component-web

image

2.egova-component-web 項(xiàng)目使用了npm7的workspaces特性,需要先npm i -g npm升級(jí)npm,然后會(huì)根據(jù)配置的workspaces來(lái)npm install這些工作區(qū)下的目錄里的package.json依賴,以此填補(bǔ)了node_moudules的空間黑洞,非常給力,yarn舊版本就有,只不過(guò)我們yarn用的比較少

image

3.npmrc文件的作用,就是配置npm源

4.先 npm run lib:dist npm run ui:dist來(lái)構(gòu)建本地代碼到node_modules下對(duì)應(yīng)包的dist,來(lái)維持本地開(kāi)發(fā)

5.npm run web:serve來(lái)測(cè)試修改或者開(kāi)發(fā)的代碼(公用組件),組件必須為受控支持v-model雙向綁定

6.vue.config.js 是一個(gè)可選的配置文件,如果項(xiàng)目的 (和 package.json 同級(jí)的) 根目錄中存在這個(gè)文件,那么它會(huì)被 @vue/cli-service 自動(dòng)加載。也可以使用 package.json 中的 vue 字段


// require("@hapi/joi");

const path = require("path");

const { name } = require("./package");

const isProd = process.env.NODE_ENV === "production";

const pageConfig = require("./page.config");

module.exports = {

    //基本路徑

    publicPath: "./",

    //輸出文件目錄

    outputDir: "dist",

    // eslint-loader 是否在保存的時(shí)候檢查

    lintOnSave: true,

    //放置生成的靜態(tài)資源 (js、css、img、fonts) 的 (相對(duì)于 outputDir 的) 目錄。

    assetsDir: "static",

    //以多頁(yè)模式構(gòu)建應(yīng)用程序。

    pages: pageConfig.pages,

    //是否使用包含運(yùn)行時(shí)編譯器的 Vue 構(gòu)建版本

    runtimeCompiler: true,

    //是否為 Babel 或 TypeScript 使用 thread-loader。該選項(xiàng)在系統(tǒng)的 CPU 有多于一個(gè)內(nèi)核時(shí)自動(dòng)啟用,僅作用于生產(chǎn)構(gòu)建,在適當(dāng)?shù)臅r(shí)候開(kāi)啟幾個(gè)子進(jìn)程去并發(fā)的執(zhí)行壓縮

    parallel: require("os").cpus().length > 1,

    //生產(chǎn)環(huán)境是否生成 sourceMap 文件,一般情況不建議打開(kāi)

    productionSourceMap: false,

    // webpack配置

    //對(duì)內(nèi)部的 webpack 配置進(jìn)行更細(xì)粒度的修改 https://github.com/neutrinojs/webpack-chain see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md

    chainWebpack: (config) => {

        // 以便支持 @component({ template: require("./index.html") }) 這種模版加載方式

        // 注意:寫(xiě)include和exclude要在use和loader之前寫(xiě)

        config.module

            .rule("html")

            .test(/\.html$/)

            .exclude.add(/public/)

            .end()

            .use("raw-loader")

            .loader("raw-loader");

        // 只輸出src下ts文件錯(cuò)誤

        config.plugin("fork-ts-checker").tap((args) => {

            args[0].reportFiles = ["src/**/*.{ts,tsx}"];

            return args;

        });

        config.resolve.alias.set("@", path.join(__dirname, "src"));

        pageConfig.plugin(config);

    },

    //調(diào)整 webpack 配置 https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F

    configureWebpack: (config) => {

        const StyleLintPlugin = require("stylelint-webpack-plugin");

        config.plugins.push(

            new StyleLintPlugin({

                files: ["src/**/*.{vue,html,css,scss,sass,less}"],

                failOnError: false,

                cache: true,

                fix: false

            })

        );

        config.output.library = `${name}-[name]`;

        config.output.libraryTarget = "umd";

        config.output.jsonpFunction = `webpackJsonp_${name}`;

    },

    css: {

        // // 啟用 CSS modules

        requireModuleExtension: true,

        // 是否使用css分離插件

        extract: isProd,

        // 開(kāi)啟 CSS source maps,一般不建議開(kāi)啟

        sourceMap: false,

        // css預(yù)設(shè)器配置項(xiàng)

        loaderOptions: {

            sass: {

                //設(shè)置css中引用文件的路徑,引入通用使用的scss文件(如包含的@mixin)

                prependData: `

        $baseUrl: "/";

                @import '~@/assets/styles/common/_var.scss';

                @import '~@/assets/styles/common/_mixin.scss';

                @import '~@/assets/styles/common/_function.scss';

        `

            }

        }

    },

    // webpack-dev-server 相關(guān)配置 https://webpack.js.org/configuration/dev-server/

    devServer: {

        headers: {

            "Access-Control-Allow-Origin": "*"

        },

        host: "0.0.0.0",

        port: 8100, // 端口號(hào)

        https: false, // https:{type:Boolean}

        open: true, //配置自動(dòng)啟動(dòng)瀏覽器  http://172.16.1.12:7071/rest/mcdPhoneBar/

        hot: true // 熱更新

        // proxy: 'http://localhost:8000'   // 配置跨域處理,只有一個(gè)代理

    },

    // 第三方插件配置 https://www.npmjs.com/package/vue-cli-plugin-style-resources-loader

    pluginOptions: require("./dll.config")

};

2. 接下來(lái)開(kāi)始項(xiàng)目結(jié)構(gòu)解析

程序入口main.ts

image.png

component的實(shí)際導(dǎo)出就是來(lái)自vue-class-component的vue類組件裝飾器,并且默認(rèn)將我們要實(shí)現(xiàn)的頁(yè)面組件進(jìn)行了鉤子掛載,在類里實(shí)現(xiàn)對(duì)應(yīng)的方法(應(yīng)該是個(gè)迭代器方法)即可, 如:

@Component
class MyComp extends Vue {
  // class 組件現(xiàn)在可以處理 beforeRouteEnter 鉤子和 
  // beforeRouteLeave 鉤子作為 Vue Router 鉤子
  beforeRouteEnter (to, from, next) {
    console.log('beforeRouteEnter')
    next() // 需要調(diào)用這個(gè)來(lái)確認(rèn)導(dǎo)航
  }

  beforeRouteLeave (to, from, next) {
    console.log('beforeRouteLeave')
    next() // 需要調(diào)用這個(gè)來(lái)確認(rèn)導(dǎo)航
  }
}

來(lái)看一下autoWired的代碼

export function autowired(serviceType: Function) {
    return function (target: any, name: any) {
        let serviceInstanceName = serviceType;
        if (serviceInstanceName && !ObjectFactory.has(serviceInstanceName)) {
            ObjectFactory.set(serviceInstanceName, ObjectFactory.create(serviceType));
        }
        if (serviceInstanceName) {
            Object.defineProperty(target, name, {
                get: function () {
                    return ObjectFactory.get(serviceInstanceName);
                },
            });
        }
    };
}

serviceType service類
target 組件類
name 綁定的屬性名

這個(gè)屬性裝飾器將service的flagwind.Activator.createInstance封裝實(shí)例進(jìn)行了在ObjectFactory的上的map靜態(tài)屬性掛載,并且也能通過(guò)組件的屬性名來(lái)調(diào)用這個(gè)實(shí)例

import flagwind from "@egova/flagwind-core";

export class ObjectFactory {
  public static maps: Map<any, any> = new Map<any, any>();

  public static get(key: any): any {
    return this.maps.get(key);
  }

  public static set(key: any, value: any) {
    this.maps.set(key, value);
  }

  public static has(key: any): boolean {
    return this.maps.has(key);
  }

  public static match(head: any): Array<any> {
    let list = new Array<any>();
    this.maps.forEach((value, key) => {
      if (key.startsWith(head)) {
        list.push(value);
      }
    });
    return list;
  }

  public static create<T>(serviceType: Function | string, ...params: Array<any>) {
    return flagwind.Activator.createInstance<T>(serviceType, ...params);
  }
}

所以,這個(gè)ObjectFactory的實(shí)例可以通過(guò)原型鏈來(lái)獲取所有組件注冊(cè)的Service類,暫時(shí)不知道有啥用,還待研究。。。

3. 組件引用

@component({
  template: require("./index.html"),
  components: {
    "u-header": HeaderComponent
  }
})
<!DOCTYPE html>
<div class="v-layout-wrapper">
    <u-header v-if="!hideHeader"> </u-header>
    <section class="main-content">
        <keep-alive>
            <router-view v-if="$route.meta.keepAlive"> </router-view>
        </keep-alive>
        <router-view v-if="!$route.meta.keepAlive"> </router-view>
    </section>
</div>

采用配置key value的形式來(lái)引用子組件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容