webpack微服务打包版本更新解决方案(怎么加版本号)

180 阅读1分钟

背景:杭州和上海的项目组共同维护一个项目,使用webpack的微服务搭建了两个服务模块,现在上海的项目更新,杭州引入上海的模块需要也需要跟新为最新的,发现目前必须杭州要配合重新发版才行,不然加载不了新版本。

怎么解决这个问题?两个项目组才能单独发版?

背景:

1、项目分为两个服务模块:模块A+模块B,两个都是作为单独的项目进行发版的。

2、现在要实现这个需求:

例如:模开A中引入模块B 中的用户管理功能,现在要实现模块B更新发版之后,模块A不需要重新打包发版,引入B的内容为最新的。

解决方案:

🌟加版本号

怎么加版本号?,发现版本号直接加随机数不行,只会在打包编译的时候执行一次,

image.png

🌟最终用了external-remotes-plugin,实现动态加载remotes

www.npmjs.com/package/ext… oskari.io/blog/dynami…

用了这个plugin,用中括号可以 使用变量

image.png

摘录文件:

const ExternalTemplateRemotesPlugin = require('external-remotes-plugin')

//
remotes: {
        'pscApp': `pscApp@${process.env.REMOTE_COMPONENT_URL}/remoteEntry.js?v1=[new Date().getTime()]`
      },
addWebpackPlugin(new ExternalTemplateRemotesPlugin()),

完整文件 config-overrides.js

const {
  override,
  disableEsLint,
  addWebpackExternals,
  overrideDevServer,
  watchAll,
  addWebpackPlugin,
  addWebpackAlias,
} = require("customize-cra");
const CompressionPlugin = require("compression-webpack-plugin")
const { ProgressPlugin } = require('webpack')
const ExternalTemplateRemotesPlugin = require('external-remotes-plugin')
const { ModuleFederationPlugin } = require('webpack').container;
const addMultipageSupply = require("./config/webpack/addMultipageSupply");
const addWorkerLoader = require("./config/webpack/addWorkerLoader")
const overrideProcessEnv = require('./config/webpack/overrideProcessEnv')
const overridePublicPath = require("./config/webpack/overridePublicPath")
const ignoreCSSOrder = require('./config/webpack/ignoreCSSOrder')
const setupProxy = require('./config/webpack/setupProxy')
const package = require('./package.json')
const path = require("path");

const { stringified } = require('./config/env');

const isEnvProduction = process.env.NODE_ENV === 'production'
const shouldUserSentry = process.argv.includes('--sentry')
const SentryPlugin = require('@sentry/webpack-plugin')
const moment = require('moment');
const packageTime = moment().format('YYYYMMDD_HH:mm:ss')
const release = `merchantadmin_${packageTime}`
console.log('Use Sentry: ', shouldUserSentry)

/**
 * auto 是 Module Federation 需要的配置
 * 设置为 ./ 或者 / 都无法启用 Module Federation
 */
const publicPath = isEnvProduction
  ? (process.env.CDN_PATH === './' ? 'auto' : process.env.CDN_PATH)
  : 'auto';

module.exports = {
  webpack: override(
    ignoreCSSOrder(),
    isEnvProduction && addWebpackPlugin(new ProgressPlugin({
      handler: (percentage, message, ...args) => {
        console.info(`${parseInt(percentage * 100)}%`, message, ...args)
      }
    })),
    addWebpackPlugin(new CompressionPlugin({
      include: /\.js$/,
    })),
    addWebpackPlugin(new ModuleFederationPlugin({
      name: "merchant",
      exposes: {
        './CustomTable': './src/components/table',
      },
      filename: 'remoteEntry.js',
      remotes: {
        'pscApp': `pscApp@${process.env.REMOTE_COMPONENT_URL}/remoteEntry.js?v1=[new Date().getTime()]`
      },
      shared: {
        react: {
          singleton: true,
          requiredVersion: package.dependencies.react,
          eager: true,
        },
        'react-dom': {
          singleton: true,
          requiredVersion: package.dependencies["react-dom"],
          eager: true,
        }
      }
    })),
    addWebpackPlugin(new ExternalTemplateRemotesPlugin()),
    // disable eslint in webpack
    disableEsLint(),
    // 多页应用
    addMultipageSupply(),
    // web-worker
    addWorkerLoader(),
    // addLessLoader(),
    // 环境变量
    overrideProcessEnv(Object.assign({}, stringified, {
      'RELEASE': JSON.stringify(release),
      'SHOULD_USE_SENTRY': JSON.stringify(shouldUserSentry),
      'CDN_PATH': JSON.stringify(process.env.CDN_PATH),
    })),
     overridePublicPath(publicPath),
     isEnvProduction && addWebpackExternals({
      'react': 'React',
      'react-dom': 'ReactDOM',
      'moment': 'moment',
      'antd': 'antd'
    }),
    isEnvProduction && shouldUserSentry && addWebpackPlugin(new SentryPlugin({
      include: `./${process.env.BUILD_PATH}`,
      urlPrefix: `~/${process.env.SUB_DIR}`,
      configFile: process.env.SENTRY_CONFIG_PATH,
      ignoreFile: '.sentrycliignore',
      release,
      errorHandler(err, _invokeErr, compilation) {
        compilation.warnings.push('Sentry CLI Plugin: ' + err.message)
      }
    })),
    addWebpackAlias({
      '@': path.resolve(__dirname, './src'),
      '@@': path.resolve(__dirname, './src/erp5-admin/src'),
    }),
    // removeModuleScopePlugin(),
  ),
  devServer: overrideDevServer(
    watchAll(),
    // 开发时接口代理
    setupProxy({
      '/ceboshitech/**': {
        target: process.env.PROXY_API_URL,
        changeOrigin: true,
      },
      '/shapi/**': {
        target: process.env.PROXY_SH_API_URL,
        changeOrigin: true,
        pathRewrite: {
          '^/shapi': '',
        },
      },
    }),
  ),
}