Spring Boot

Spring Boot 生成Webpack入口文件

2019-12-17  本文已影响0人  EasyNetCN

在实际业务中,有几百个组件,出于一些原因,需要独立打包成单独的入口文件。

Spring Boot Application

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) throws IOException {
        var context = SpringApplication.run(Application.class, args);
        var generator = context.getBean(EntryFileGenerator.class);

        generator.generate();
    }

}

生成代码类

import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.stereotype.Component;

@Component
public class EntryFileGenerator {
    private Set<String> skip = new HashSet<String>() {
        private static final long serialVersionUID = 1L;
        {
            add("yd-layout");
        }
    };

    @Autowired
    private VelocityEngine velocityEngine;

    @Autowired
    private ApplicationArguments applicationArguments;

    public void generate() throws IOException {

        var src = applicationArguments.getOptionValues("src").get(0);
        var dist = applicationArguments.getOptionValues("dist").get(0);

        var components = getComponents(src);

        System.out.println(components.size());

        clean(dist, components);
        generateEntry(dist, components);

    }

    private Set<String> getComponents(String src) throws IOException {
        var components = new HashSet<String>();

        try (var dirStream = Files.newDirectoryStream(Paths.get(src))) {
            dirStream.forEach(dir -> {
                if (Files.isDirectory(dir)) {
                    var fileName = dir.getFileName().toString();

                    if ((fileName.startsWith("yd-") || fileName.startsWith("ydo-")) && !skip.contains(fileName)) {
                        components.add(fileName);
                    }
                }
            });
        }

        return components;
    }

    private void clean(String dist, Collection<String> components) throws IOException {
        try (var dirStream = Files.newDirectoryStream(Paths.get(dist))) {
            dirStream.forEach(dir -> {
                if (Files.isRegularFile(dir)) {
                    var fileName = dir.getFileName().toString();
                    var baseName = fileName.substring(0, fileName.lastIndexOf('.'));

                    if ((fileName.startsWith("yd-") || fileName.startsWith("ydo-")) && !components.contains(baseName)) {
                        try {
                            Files.deleteIfExists(dir);
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
    }

    private void generateEntry(String dist, Collection<String> components) {
        components.forEach(component -> {
            var context = new VelocityContext();

            context.put("componentComment", component.startsWith("yd-") ? "ERP" : "管理平台");
            context.put("component", component);
            context.put("componentName", getComponentName(component));

            try (FileWriter fileWriter = new FileWriter(
                    Paths.get(dist, component + ".js").toAbsolutePath().toString())) {

                velocityEngine.mergeTemplate("vm/entry.vm", "UTF-8", context, fileWriter);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        });
    }

    private String getComponentName(String component) {
        var sb = new StringBuilder();
        var strs = component.split("-");

        for (var i = 0; i < strs.length; i++) {
            sb.append(StringUtils.capitalize(strs[i]));
        }

        return sb.toString();
    }
}

基于Velocity的模板文件

import Auth from './components/auth';
import AvatarList from './components/avatar-list';
import Calendar from './components/calendar';
import City from './components/city';
import Copy from './components/copy';
import CountDown from './components/count-down';
import CountUp from './components/count-up';
import DescriptionList from './components/description-list';
import Ellipsis from './components/ellipsis';
import Exception from './components/exception';
import FooterToolbar from './components/footer-toolbar';
import GlobalFooter from './components/global-footer';
import Grid from './components/grid';
import Login from './components/login';
import Notification from './components/notification';
import NumberInfo from './components/number-info';
import Numeral from './components/numeral';
import PageHeader from './components/page-header';
import Result from './components/result';
import ScrollIntoView from './components/scroll-into-view';
import ScrollTop from './components/scroll-top';
import TablePaste from './components/table-paste';
import TagSelect from './components/tag-select';
import TreeSelect from './components/tree-select';
import Trend from './components/trend';
import WordCount from './components/word-count';

// 公共组件
import ColumnSetup from "./components/column-setup";
import FlatTab from "./components/flat-tab";
import LeftSider from "./components/left-sider";
import PageTable from "./components/page-table";

// $componentComment
import YdLayout from './components/yd-layout';
#if($component=="ydo-login")
import YdLogin from './components/yd-login';
#end
import $componentName from './components/$component';

import locale from './locale/index';

// directives
import lineClamp from './directives/line-clamp';
import resize from './directives/resize';
import style from './directives/style';

// filters
import date from './filters/date';
import { formatDate, formatDateTime, formatStartDayDateTime, formatEndDayDateTime } from './utils/yd-assist';

// libraries
import dayjs from 'dayjs';

const components = {
    Auth,
    AvatarList,
    Calendar,
    Captcha: Login.Captcha,
    City,
    CountDown,
    CountUp,
    Description: DescriptionList.Description,
    DescriptionList,
    Ellipsis,
    Email: Login.Email,
    Exception,
    FooterToolbar,
    GlobalFooter,
    Grid,
    GridItem: Grid.Item,
    Login: Login,
    Mobile: Login.Mobile,
    Notification,
    NotificationItem: Notification.Item,
    NotificationTab: Notification.Tab,
    NumberInfo,
    Numeral,
    PageHeader,
    Password: Login.Password,
    Result,
    Submit: Login.Submit,
    TablePaste,
    TagSelect,
    TagSelectOption: TagSelect.Option,
    TreeSelect,
    Trend,
    UserName: Login.UserName,
    WordCount,

    // 公共组件
    ColumnSetup,
    FlatTab,
    LeftSider,
    PageTable,

    // $componentComment
    YdLayout,
#if($component=="ydo-login")
    YdLogin,
#end
    $componentName
};

const iview_pro = {
    ...components
};

const directives = {
    display: style.display,
    width: style.width,
    height: style.height,
    margin: style.margin,
    padding: style.padding,
    font: style.font,
    color: style.color,
    'bg-color': style.bgColor,

    resize,
    'line-clamp': lineClamp
};

const filters = Object.assign({}, date, {
    formatDate: formatDate,
    formatDateTime: formatDateTime,
    formatStartDayDateTime: formatStartDayDateTime,
    formatEndDayDateTime: formatEndDayDateTime
});

const install = function (Vue, opts = {}) {
    if (install.installed) return;
    locale.use(opts.locale);
    locale.i18n(opts.i18n);

    Object.keys(iview_pro).forEach(key => {
        Vue.component(key, iview_pro[key]);
    });

    Object.keys(directives).forEach(key => {
        Vue.directive(key, directives[key]);
    });

    Object.keys(filters).forEach(key => {
        Vue.filter(key, filters[key]);
    });

    Vue.prototype.$IVIEWPRO = {
        size: opts.size || '',
        transfer: 'transfer' in opts ? opts.transfer : ''
    };

    Vue.prototype.$Copy = Copy;
    Vue.prototype.$ScrollIntoView = ScrollIntoView;
    Vue.prototype.$ScrollTop = ScrollTop;
    Vue.prototype.$Date = dayjs;
};

// auto install
if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue);
}

const API = {
    version: process.env.VERSION, // eslint-disable-line no-undef
    locale: locale.use,
    i18n: locale.i18n,
    install,
    ...components
};

API.lang = (code) => {
    const langObject = window['iview/locale'].default;
    if (code === langObject.i.locale) locale.use(langObject);
    else console.log(`The ${code} language pack is not loaded.`); // eslint-disable-line no-console
};

module.exports.default = module.exports = API;   // eslint-disable-line no-undef
上一篇 下一篇

猜你喜欢

热点阅读