在实际业务中,有几百个组件,出于一些原因,需要独立打包成单独的入口文件。
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
网友评论