记录下微前端中vue模块的相关写法和配置

224 阅读1分钟

放一个配置的参照,vue-loader版本会比较讲究,一般都用15版本

  "name": "simple-single-spa-webpack-example",
  "version": "1.0.0",
  "description": "A simple example of how to use webpack with single-spa",
  "scripts": {
    "watch": "webpack-dev-server --open",
    "build": "webpack --config webpack.config.js -p"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/joeldenning/simple-single-spa-webpack-example.git"
  },
  "author": "Joel Denning",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/joeldenning/simple-single-spa-webpack-example/issues"
  },
  "homepage": "https://github.com/joeldenning/simple-single-spa-webpack-example#readme",
  "devDependencies": {
    "babel-core": "^6.25.0",
    "babel-jest": "^24.9.0",
    "babel-loader": "^7.1.1",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-preset-env": "^1.6.0",
    "babel-preset-react": "^6.24.1",
    "clean-webpack-plugin": "^0.1.16",
    "http-server": "^0.10.0",
    "jest": "^24.9.0",
    "ts-loader": "^5.3.3",
    "typescript": "3.5.*",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.3.0",
    "webpack-dev-server": "^3.2.1"
  },
  "dependencies": {
    "@angular/common": "^8.2.14",
    "@angular/compiler": "^8.2.14",
    "@angular/core": "^8.2.14",
    "@angular/platform-browser": "^8.2.14",
    "@angular/platform-browser-dynamic": "^8.2.14",
    "@angular/router": "^8.2.14",
    "core-js": "^2.5.7",
    "es6-promise": "^4.1.1",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "reflect-metadata": "^0.1.10",
    "rxjs": "~6.5.3",
    "single-spa": "^3.8.1",
    "single-spa-angular": "^2.2.1",
    "single-spa-react": "^2.9.0",
    "single-spa-vue": "^2.5.1",
    "vue": "^2.7.14",
    "vue-loader": "^15.10.1",
    "zone.js": "^0.8.16"
  }
}

webpack配置

const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
//vue-loader是新引入的
const {VueLoaderPlugin} = require('vue-loader')

module.exports = {
  entry: {
    'root-application': 'src/root-application/root-application.js',
    'common-dependencies': [
      // We want just one version of angular, so we put it into the common dependencies
      'core-js/client/shim.min.js',
      '@angular/common',
      '@angular/compiler',
      '@angular/core',
      '@angular/platform-browser-dynamic',
      '@angular/router',
      'reflect-metadata',
      /* Just one version of react, too. react-router is fine to have multiple versions of,
       * though, so no need to put it in common dependencies
       */
      'react',
      'react-dom',
      'vue',
    ],
  },
  output: {
    publicPath: '/dist/',
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [{
        test: /\.js?$/,
        exclude: [path.resolve(__dirname, 'node_modules')],
        loader: 'babel-loader',
      },
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
      },
      //规则也是新引入的
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ],
  },
  node: {
    fs: 'empty'
  },
  resolve: {
    alias: {
      vue: 'vue/dist/vue.js'
    },
    modules: [
      __dirname,
      'node_modules',
    ],
  },
  optimization: {
    splitChunks: {
      name: 'common-dependencies.js',
    },
  },
  plugins: [
    new CleanWebpackPlugin(['dist']),
    new ContextReplacementPlugin(
      /(.+)?angular(\\|\/)core(.+)?/,
      path.resolve(__dirname, '../src')
    ),
    ////vue-loader方法
    new VueLoaderPlugin(),
  ],
  devtool: 'source-map',
  externals: [],
  devServer: {
    historyApiFallback: true
  }
};

vue的引入方法参照官方的demo来写

目录结构

image.png

src/app3

//app3.js
import Vue from 'vue';
import singleSpaVue from 'single-spa-vue';
import Main from './main.vue'

//比较值得注意的就是vue的创建dom元素方法似乎无法放在singleSpaVue里,需要提前创建元素才能往下写
domElementGetter()
const vueLifecycles = singleSpaVue({
  Vue,
  appOptions: {
    el: '#app3',
    render: r => r(Main)
  },
});

export const bootstrap = [
  vueLifecycles.bootstrap,
];

export const mount = [
  vueLifecycles.mount,
];

export const unmount = [
  vueLifecycles.unmount,
];
function domElementGetter() {
  // Make sure there is a div for us to render into
  let el = document.getElementById('app3');
  if (!el) {
    el = document.createElement('div');
    el.id = 'app3';
    document.body.appendChild(el);
  }

  return el;
}
//main.vue
<template>
  <div style="marginTop: 100px">
      <h1>Hello from Vue</h1>
  </div>
</template>

<script>
export default {
  name: 'Main',
}
</script>

其余文件补充vue的部分

index.html

image.png

root-application.js

image.png