基于maven插件实现vue前端工程打包

基于maven插件实现vue前端工程打包

一、问题背景

公司项目管理平台为前后端分离框架,前端工程系基于vue-admin框架实现。每次jenkins编译出包时需针对vue前端工程执行以下单独的shell编译打包流程,详细如下:

#0. 代理连接外网,nodejs需要拉js包
export http_proxy=http://172.30.28.35:3128
export https_proxy=http://172.30.28.35:3128

export NODE_HOME=/home/devops/node-v10.13.0-linux-x64
export PATH=$NODE_HOME/bin:$PATH

#1. xxx-admin-frontent前端工程构建

# 1.1 xxx-admin-fronted构建
source ~/.bash_profile

cd $WORKSPACE/xxx-admin/xxx-admin-frontend/target/

npm cache clean --force
npm config set registry https://registry.npm.taobao.org/

npm install
npm install webpack
npm run test

# 将编译生成的dist文件夹打成tar包并scp到目标机器tmp目录
cd $WORKSPACE/xxx-admin/xxx-admin-frontend/target/dist/
tar czvf xxx-admin-frontent.tar . --warning=no-file-changed
cd $WORKSPACE/xxx-admin/xxx-admin-frontend/target/
scp ./xxx-admin-frontend.tar [email protected]:/home/xxx/tmp

现希望直接基于maven插件实现前后端工程的混合编译打包,省略上述配置。

二、解决方案

1、方案一:基于exec-maven-plugin插件实现对vue前端工程打包

该方案实现以下目标:

  • 基于maven插件实现编译vue前端工程生成dist文件夹。
  • 将编译生成的dist文件夹打包成tar文件。
  • 支持根据profile传参进行不同环境的编译打包。
  • 由于vue前端工程改动较少,每次出包耗时长,允许jenkins编译打包工程时,根据传参跳过vue前端工程的打包。

具体实现如下:

前端工程xxx-admin-frontent工程pom.xml配置文件增加如下配置:

<build>
        <finalName>xxx-admin-frontendfinalName>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojogroupId>
                <artifactId>exec-maven-pluginartifactId>
                <version>1.6.0version>
                <configuration>
                    <skip>${skipDeploy}skip>
                configuration>
                <executions>
                    
                    <execution>
                        <id>exec-npm-installid>
                        <phase>generate-resourcesphase>
                        <goals>
                            <goal>execgoal>
                        goals>
                        <configuration>
                            <executable>npmexecutable>
                            <arguments>
                                <argument>installargument>
                            arguments>
                            <workingDirectory>${basedir}/vueworkingDirectory>
                        configuration>
                    execution>

                    
                    <execution>
                        <id>exec-npm-run-buildid>
                        <phase>generate-resourcesphase>
                        <goals>
                            <goal>execgoal>
                        goals>
                        <configuration>
                            <executable>npmexecutable>
                            <arguments>
                                <argument>runargument>
                                <arguments>${package.environment}arguments>
                            arguments>
                            <workingDirectory>${basedir}/vueworkingDirectory>
                        configuration>
                    execution>
                executions>
            plugin>

            
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-assembly-pluginartifactId>
                <version>3.3.0version>
                <executions>
                    <execution>
                        <id>make-assemblyid>
                        <phase>packagephase>
                        <goals>
                            <goal>singlegoal>
                        goals>
                        <configuration>
                            <skipAssembly>${skipDeploy}skipAssembly>
                            <appendAssemblyId>falseappendAssemblyId>
                            <finalName>xxx-admin-frontendfinalName>
                            <descriptors>
                                <descriptor>assembly.xmldescriptor>
                            descriptors>
                        configuration>
                    execution>
                executions>
            plugin>
        plugins>
    build>

    <profiles>
        <profile>
            <id>localid>
            <properties>
                <package.environment>localpackage.environment>
            properties>
        profile>
        <profile>
            <id>testid>
            <properties>
                <package.environment>testpackage.environment>
            properties>
            <activation>
                <activeByDefault>trueactiveByDefault>
            activation>
        profile>
        <profile>
            <id>uatid>
            <properties>
                <package.environment>uatpackage.environment>
            properties>
        profile>
        <profile>
            <id>prodid>
            <properties>
                <package.environment>build:prodpackage.environment>
            properties>
        profile>
    profiles>

其中assembly.xml配置内容如下:

<assembly>
    <id>xxx-admin-frontendid>
    <formats>
        
        <format>tarformat>
    formats>

    <includeBaseDirectory>falseincludeBaseDirectory>

    
    <fileSets>
        <fileSet>
            <directory>${basedir}/vue/distdirectory>
            <includes>
                <include>**/*include>
            includes>
            <outputDirectory>/outputDirectory>
        fileSet>
    fileSets>
assembly>

其中pom.xml中支持profile环境参数的配置,对应的package.json中npm执行参数配置如下:

"scripts": {
  "init": "webpack --progress --config build/webpack.local.config.js",
  "lint": "eslint --fix --ext .js,.vue src",
  "local": "webpack-dev-server --host 0.0.0.0 --content-base ./ --open --inline --hot --compress --config build/webpack.local.config.js",
  "test": "webpack --progress --hide-modules --config build/webpack.test.config.js",
  "uat": "webpack --progress --hide-modules --config build/webpack.uat.config.js",
  "build:prod": "webpack --progress --hide-modules --config build/webpack.prod.config.js"
}

maven构建的参数如下:

-s /home/devops/.m2/settingsnewglobal.xml -Dmaven.test.skip=true clean install -P test -DskipDeploy=false

-DskipDeploy=true 即指定jenkins编译出包时跳过前端vue工程的编译打包环节。

注意:以上配置生效的前提是jenkins服务器已经安装有node.js以及npm环境,当前jenkins服务器安装的node.js版本为node 12.18.3,方案一生效的前提是jenkins服务器已经安装有node.js以及npm环境,如需打包时安装node.js以及npm环境,可参考方案二。

2、方案二:基于frontend-maven-plugin 插件实现对vue前端工程打包

方案二实现以下目标:

  • 基于maven插件实现编译vue前端工程生成dist文件件。
  • 将编译生成的dist文件夹打包成tar文件。
  • 支持根据profile传参进行不同环境的编译打包。
    <build>
        <finalName>xxx-admin-frontendfinalName>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojogroupId>
                <artifactId>exec-maven-pluginartifactId>
                <version>1.6.0version>
                <configuration>
                    <skip>${skipDeploy}skip>
                configuration>
                <executions>
                    
                    <execution>
                        <id>exec-npm-installid>
                        <phase>generate-resourcesphase>
                        <goals>
                            <goal>execgoal>
                        goals>
                        <configuration>
                            <executable>npmexecutable>
                            <arguments>
                                <argument>installargument>
                            arguments>
                            <workingDirectory>${basedir}/vueworkingDirectory>
                        configuration>
                    execution>

                    
                    <execution>
                        <id>exec-npm-run-buildid>
                        <phase>generate-resourcesphase>
                        <goals>
                            <goal>execgoal>
                        goals>
                        <configuration>
                            <executable>npmexecutable>
                            <arguments>
                                <argument>runargument>
                                <arguments>${package.environment}arguments>
                            arguments>
                            <workingDirectory>${basedir}/vueworkingDirectory>
                        configuration>
                    execution>
                executions>
            plugin>

            
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-assembly-pluginartifactId>
                <version>3.3.0version>
                <executions>
                    <execution>
                        <id>make-assemblyid>
                        <phase>packagephase>
                        <goals>
                            <goal>singlegoal>
                        goals>
                        <configuration>
                            <skipAssembly>${skipDeploy}skipAssembly>
                            <appendAssemblyId>falseappendAssemblyId>
                            <finalName>xxx-admin-frontendfinalName>
                            <descriptors>
                                <descriptor>assembly.xmldescriptor>
                            descriptors>
                        configuration>
                    execution>
                executions>
            plugin>
        plugins>
    build>

    <profiles>
        <profile>
            <id>localid>
            <properties>
                <package.environment>localpackage.environment>
            properties>
        profile>
        <profile>
            <id>testid>
            <properties>
                <package.environment>testpackage.environment>
            properties>
            <activation>
                <activeByDefault>trueactiveByDefault>
            activation>
        profile>
        <profile>
            <id>uatid>
            <properties>
                <package.environment>uatpackage.environment>
            properties>
        profile>
        <profile>
            <id>prodid>
            <properties>
                <package.environment>build:prodpackage.environment>
            properties>
        profile>
    profiles>

其中pom.xml中支持profile环境参数的配置,对应的package.json中npm执行参数配置如下:

  "scripts": {
    "init": "webpack --progress --config build/webpack.local.config.js",
    "lint": "eslint --fix --ext .js,.vue src",
    "local": "webpack-dev-server --host 0.0.0.0 --content-base ./ --open --inline --hot --compress --config build/webpack.local.config.js",
    "test": "webpack --progress --hide-modules --config build/webpack.test.config.js",
    "uat": "webpack --progress --hide-modules --config build/webpack.uat.config.js",
    "build:prod": "webpack --progress --hide-modules --config build/webpack.prod.config.js"
  }

aseemble.xml配置如下:

<assembly>
    <id>xxx-admin-frontendid>
    <formats>
        
        <format>tarformat>
    formats>

    <includeBaseDirectory>falseincludeBaseDirectory>

    
    <fileSets>
        <fileSet>
            <directory>${basedir}/vue/distdirectory>
            <includes>
                <include>**/*include>
            includes>
            <outputDirectory>/outputDirectory>
        fileSet>
    fileSets>
assembly>

cleanFiles.js内容如下:

const fs = require('fs')
const p = require('path')

const nodeModulesPath = p.join(__dirname, '../../node_modules')
const lockJsonPath = p.join(__dirname, '../../package-lock.json')

if (fs.existsSync(nodeModulesPath)) {
  const fileUtil = require('./fileUtil')

  fileUtil.deleteFolderByRimraf(nodeModulesPath)
  console.log('删除 node_modules 成功!')
  
  fileUtil.deleteFile(lockJsonPath)
  console.log('删除 package-lock.json 成功!')
}

fileUtil.js内容如下:

const fs = require('fs')
const rimraf = require('rimraf');

/**
 * 删除文件夹
 * @param path
 */
function deleteFolder (path) {
  let files = [];
  if (fs.existsSync(path)) {
    if (fs.statSync(path).isDirectory()) {
      files = fs.readdirSync(path)
      files.forEach((file) => {
        const curPath = path + '/' + file;
        if (fs.statSync(curPath).isDirectory()) {
          deleteFolder(curPath)
        } else {
          fs.unlinkSync(curPath)
        }
      })
      fs.rmdirSync(path)
    } else {
      fs.unlinkSync(path)
    }
  }
}

/**
 * 使用 rimraf 删除文件夹
 * @param path
 */
function deleteFolderByRimraf (path) {
  rimraf(path, (err) => {
    if (err) {
      console.log(err)
    }
  })
}

/**
 * 删除文件
 * @param path
 */
function deleteFile (path) {
  if (fs.existsSync(path)) {
    if (fs.statSync(path).isDirectory()) {
      deleteFolder(path)
    } else {
      fs.unlinkSync(path)
    }
  }
}

/**
 * 复制文件夹到指定目录
 * @param from
 * @param to
 */
function copyFolder (from, to) {
  let files = []
  // 文件是否存在 如果不存在则创建
  if (fs.existsSync(to)) {
    files = fs.readdirSync(from)
    files.forEach((file) => {
      const targetPath = from + '/' + file;
      const toPath = to + '/' + file;

      // 复制文件夹
      if (fs.statSync(targetPath).isDirectory()) {
        copyFolder(targetPath, toPath)
      } else {
        // 拷贝文件
        fs.copyFileSync(targetPath, toPath)
      }
    })
  } else {
    fs.mkdirSync(to)
    copyFolder(from, to)
  }
}

module.exports = {
  deleteFolder,
  deleteFolderByRimraf,
  deleteFile,
  copyFolder
}

你可能感兴趣的:(前端,前端,maven)