vue大型プロジェクトのモジュール別運行/パッケージの実現


本文はvue-cli 3+を例にとって、多システム統合下のモジュールパッキングを実現する。モジュール別パッケージ方式は様々であり、以下は多システム間の相互干渉に適用でき、メインシステムは各サブシステムを統合し、各サブシステムは単独で動作することができるビジネスシーンに適用できる。
一、目標
私たちは何を実現しますか?モジュールに分けて包装するということは、各モジュール内に独自の入口ファイルとルートファイルが必要です。このような構想に基づいて、私は新しい足場srcディレクトリの下でプロジェクトスディレクトリを作成しました。
图1
上記の図のように、Aroject、B、C、Dの4つの項目が見られます。私はAプロジェクトの中でassites、commonとviewフォルダを建てました。その中にassetsはcssのフォルダを再構築できます。common内で公共のコンポーネントや方法を置くことができます。viewページはページを置くことができます。さらに、componentsフォルダを作ってコンポーネントを置くこともできます。
はい、私達のビューディレクトリの構造は大体上のようです。私たちが期待しているのは、このAモジュールという“小vue”をパッケージ化して、完全なvueプロジェクトをパッケージ化するようにすることです。この部分はどうやって実現しますか?
二、単一モジュールの包装
私たちは、package.jsonにプロジェクトの起動、パッケージ化のコマンドがあることを知っています。
在这里插入图片描述
ここから入手できます。
ここではcross-envというモジュールに言及しなければなりません。
私たちは以前に生産環境を設け、環境をテストし、開発環境にもこのモジュールを使いました。ここでは詳しく述べません。

cross-env:npm install --save-dev cross-env
今私達の考えは大体このようです。梱包命令を実行する時、cross-envを通じて私達の入り口のファイルを見つけてから包装します。
環境変数の書き方を真似して、パッケージに下記のコードを書き込むことができます。
在这里插入图片描述
コード:

 "dev:projectA": "cross-env PROJECT_NAME=projectA vue-cli-service serve",
  "dev:projectB": "cross-env PROJECT_NAME=projectB vue-cli-service serve",
  "dev:projectC": "cross-env PROJECT_NAME=projectC vue-cli-service serve",
  "dev:projectD": "cross-env PROJECT_NAME=projectD vue-cli-service serve",
  "build:projectA": "cross-env PROJECT_NAME=projectA vue-cli-service build",
  "build:projectB": "cross-env PROJECT_NAME=projectB vue-cli-service build",
  "build:projectC": "cross-env PROJECT_NAME=projectC vue-cli-service build",
  "build:projectD": "cross-env PROJECT_NAME=projectD vue-cli-service build",
これらを書き上げると、私たちはvueの設定を模倣したファイルに着手することができます。
mail.jsでは下記のコードを設定します。

  import Vue from "vue";
		import App from "./App.vue";
		import router from "./router";
		import store from "./store";
		
		Vue.config.productionTip = false;
		
		new Vue({
		  router,
		  store,
		  render: h => h(App)
		}).$mount("#app");
App.vueには以下のコードが設定されています。

  <template>
		 <div id="app">
		  <router-view />
		 </div>
		</template>
		
		<style lang="less">
		
		</style>
router.jsに下記のコードを配置します。

import Vue from "vue";
		import Router from "vue-router";
		import Home from "./views/Home.vue";
		
		Vue.use(Router);
		
		export default new Router({
		 routes: [
		  {
		   path: "/",
		   name: "home",
		   component: Home
		  }
		 ]
		});
pageフォルダにHome.vueを作成し、下記のコードを書き込みます。

<template>
		 <div>
		    a  
		 </div>
		</template>
		
		<script>
		export default {};
		</script>
		
		<style></style>
プロジェクトの最外層にconfigフォルダを作成し、その中にprojects Config.jsを新たに作成します。

const config = {
 projectA: {
  pages: {
   index: {
    entry: "src/projects/projectA/main.js",
    template: "public/index.html",
    filename: "index.html"
   }
  },
  devServer: {
   port: 8080, //     
   open: false, //            
   host: "0.0.0.0", //        host,    localhost
   https: false, //   https    
   disableHostCheck: true,
   //     
   proxy: {
    "/eopenhapi": {
     target: "http://open.jdpay.com",
     changeOrigin: true
    },
    "/hapi": {
     target: "http://open.jdpay.com",
     changeOrigin: true
    }
   }
  }
 },
 projectB: {},
 projectC: {}
};
module.exports = config;
projects Config.jsをvue.co.nfig.jsに組み込み、vue.com fig.jsのコードは以下の通りです。

const config = require("./config/projectsConfig.js");
let projectName = process.env.PROJECT_NAME;

module.exports = {
 ...config[projectName],
 // pages: conf.pages,

 //     
 // baseUrl: './',//vue-cli3.3      
 publicPath: "./", // vue-cli3.3+     

 //       
 outputDir: "dist/" + projectName + "/"
};
ここまで書いてください。私たちは完全なvueを作ります。
実行コマンドcnpm run dev:project A
在这里插入图片描述
実行コマンドcnpm run build:project A
在这里插入图片描述
効果は完璧です。
三、包装総項目とサブシステム
大きなプロジェクトには必ず公共モジュールがあります。ここにナビゲーションバーを公共部品として書いています。
projectで公共モジュールのフォルダcomonを作成し、前のA項目のディレクトリ構造を書き込みます。
在这里插入图片描述
package.jsonに運転コマンドとパッケージコマンドを書き込みます。

"dev:common": "cross-env PROJECT_NAME=common vue-cli-service serve",
 "build:common": "cross-env PROJECT_NAME=common vue-cli-service build",
Home.vueに公共ナビゲーションを書きます。
ここではiviewをuiコンポーネントとして使用しますが、そのために一つの問題があります。私のA、B、C、Dの四つの項目は各項目にUIフレームを導入しています。パッケージ化するとプロジェクト全体が非常に大きいので、サブプロジェクトで必要に応じて導入しなければなりません。プロジェクトの中で、それとも全ivewをダウンロードしますか?
次のコードを書き込みます。

<template>
 <div class="main-content">
  <Layout>
   <header class="head-box">
    <Menu
     mode="horizontal"
     theme="primary"
     active-name="1"
     @on-select="menuClick"
    >
     <div class="layout-logo">Oralinge</div>
     <div class="layout-nav">
      <div class="layout-nav-content">
       <!--      -->
       <span v-for="(item, index) in systemList" :key="index">
        <MenuItem
         :name="item.basepath + '?systemId=' + item.systemId"
         @click="go(item)"
        >
         <Icon type="ios-navigate"></Icon>
         {{ item.title }}
        </MenuItem>
       </span>
      </div>
     </div>
     <div class="layout-right">
      <Dropdown>
       <!--      -->
       <a href="javascript:void(0)" rel="external nofollow" >
        {{ user.userName }}
        <Icon type="ios-arrow-down"></Icon>
       </a>
       <!--      -->
       <DropdownMenu slot="list">
        <DropdownItem name="logout">    </DropdownItem>
       </DropdownMenu>
      </Dropdown>
     </div>
    </Menu>
   </header>
  </Layout>
  <iframe
   :src="systemUrl"
   width="100%"
   height="100%"
   frameborder="0"
   class="iframe"
   id="bossIframe"
  ></iframe>
 </div>
</template>
<script>
import {
 Layout,
 Menu,
 MenuItem,
 Dropdown,
 DropdownItem,
 DropdownMenu
} from "view-design";

export default {
 components: {
  Layout,
  Menu,
  MenuItem,
  Dropdown,
  DropdownItem,
  DropdownMenu
 },
 data() {
  return {
   systemUrl: "",
   isFullscreen: false,
   loading: false,
   systemList: [
    {
     title: "A  ",
     basepath: "http://localhost:8080/#/",
     systemId: "A"
    },
    {
     title: "B  ",
     basepath: "http://localhost:8082/#/",
     systemId: "B"
    },
    {
     title: "C  ",
     basepath: "http://localhost:8083/#/",
     systemId: "c"
    },
    {
     title: "D  ",
     basepath: "http://localhost:8084/#/",
     systemId: "D"
    }
   ],
   user: {}
  };
 },
 mounted() {
  this.systemUrl =
   this.systemList[0].basepath + "?systemId=" + this.systemList[0].systemId;
 },
 methods: {
  menuClick(name) {
   this.systemUrl = name;
  }
 }
};
</script>

<style lang="less" scoped>
@head-height: 50px;
.main-content {
 height: 100%;
 padding-top: @head-height;
 box-sizing: border-box;
 overflow: hidden;
}
.head-box {
 width: 100%;
 height: @head-height;
 line-height: @head-height;
 position: fixed;
 top: 0;
 left: 0;
 min-width: 1200px;

 .ivu-menu-horizontal {
  height: 100%;
  line-height: @head-height;
 }
 .layout-logo {
  display: inline-block;
  width: 200px;
  color: #fff;
  font-size: 28px;
  text-align: center;
  vertical-align: top;
  position: absolute;
  left: 0;
  top: 0;
  background-color: #2d8cf0;
  z-index: 5;
 }
 .layout-nav {
  display: inline-block;
  width: 100%;
  height: 100%;
  padding-left: 200px;
  padding-right: 100px;
  box-sizing: border-box;
  overflow-x: auto;
  z-index: 4;
  &-content {
   //  width: 100%;
   overflow: hidden;
   height: 100%;
  }
 }
 .layout-right {
  padding-right: 20px;
  padding-left: 20px;
  position: absolute;
  right: 0;
  top: 0;
  background-color: #2d8cf0;
  z-index: 5;
  a {
   color: #fff;
  }
 }

 .ivu-menu-item-active {
  font-size: 20px;
 }
}
</style>
効果:
在这里插入图片描述
B項目は同じ方法でファイルを配置します。
設定後の効果は以下の通りです。
在这里插入图片描述
ここまで来て、私達は基本的にモジュールの運行と集団運行を実現しました。
包装を見てみます。
B項目とcomonパッケージコマンドをそれぞれ実行した後、効果は正常です。
在这里插入图片描述
また、私はここでiframe方式を採用して他の項目を組み込んでいます。導入した方法で包装する時には多すぎるからです。
このようにするメリットは公共プロジェクトが一つのケースとしてしか使われないことです。他の項目はあまり関連がなく、各プロジェクトモジュールの独立性を保証しています。
四、demo住所
https://github.com/Oralinge/pointsmodule
ここでvueの大型プロジェクトのモジュール運行/パッケージ化の実現に関する記事を紹介します。これに関連して、より多くの関連内容を紹介します。以前の文章を検索してください。または下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。