pring Boot 微服务项目通常是通过 REST API 来提供服务的,而不是直接集成 HTML 页面。不过,今天看到有小伙伴在咨询如何在 Spring Boot 项目中集成 HTML 页面,简单整理了一下,可以采用以下常用的方法:
举例来说,如果你选择使用 Thymeleaf,可以按照以下步骤来实现:
--1 在 pom.xml 中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
--2 在 application.properties 中添加以下配置:
# 配置 Thymeleaf 模板文件所在路径
spring.thymeleaf.prefix=classpath:/templates/
# 配置 Thymeleaf 模板文件后缀名
spring.thymeleaf.suffix=.html
# 配置 Thymeleaf 模板文件字符集
spring.thymeleaf.encoding=UTF-8
# 开启缓存
spring.thymeleaf.cache=true
--3 在 src/main/resources/templates 目录下创建 HTML 模板文件,并使用 Thymeleaf 标签进行动态数据绑定和条件渲染等操作。
例如,以下是一个简单的 HTML 模板文件 index.html:
<!DOCTYPE html>
<html>
<head>
<title>Spring Boot + Thymeleaf</title>
</head>
<body>
<h1>Welcome to Spring Boot</h1>
<p th:text="${message}">This is a placeholder text.</p>
</body>
</html>
--4 在 Spring Boot 应用程序的控制器中,使用 @GetMapping 注解定义一个返回 ModelAndView 对象的请求处理方法,并将模板文件名和动态数据传递给 ModelAndView 对象。
例如,以下是一个简单的控制器类 HomeController:
@Controller
public class HomeController {
@GetMapping("/")
public ModelAndView index() {
ModelAndView modelAndView = new ModelAndView("index");
modelAndView.addObject("message", "Hello, world!");
return modelAndView;
}
}
这样,在浏览器中访问 http://localhost:8080 就可以看到渲染后的 HTML 页面了。
再举一个FreeMarker的例子来简单说一下:
当使用Spring Boot构建Web应用程序时,可以使用FreeMarker作为模板引擎来渲染HTML页面。FreeMarker是一个开源的Java模板引擎,它允许您通过定义模板来生成HTML等文档。下面是在Spring Boot项目中集成FreeMarker的一些常用方法:
--1 添加依赖:在项目的pom.xml文件中添加FreeMarker的依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
--2 配置视图解析器:在application.properties文件中添加以下配置,以告诉Spring Boot使用FreeMarker作为模板引擎来解析视图:
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.ftl
--3 创建模板文件:在src/main/resources/templates目录下创建.ftl文件,该文件将用于渲染HTML页面。在模板文件中,您可以使用FreeMarker的模板语言来定义HTML页面的内容。
例如,以下是一个简单的模板文件,它将渲染一个包含“Hello World”的HTML页面:
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>
在上面的模板中,${message}将被替换为实际的值。您可以在Java代码中使用模型来设置这个值。
--4 创建控制器:在Spring Boot应用程序中创建一个控制器,以处理HTTP请求并返回模板的名称和模型。以下是一个示例控制器:
@Controller
public class HomeController {
@GetMapping("/")
public String home(Model model) {
model.addAttribute("message", "Hello World!");
return "home";
}
}
在上面的示例中,控制器返回了“home”字符串,这将作为模板文件的名称。它还将模型添加到视图中,该模型包含名为“message”的属性和“Hello World!”的值。
这是在Spring Boot项目中使用FreeMarker作为模板引擎的一些常用方法。当您使用FreeMarker时,还可以使用一些高级特性,例如条件语句、迭代器和宏,来更好地控制生成的HTML页面。
程设计是工作流的入口,开发者可以通过eclipse插件等来设计流程,但是用户并不会使用。所以可以在线设计的流程才是我们想要的,幸好activiti提供了在线设计功能,我们只需要把它集成到我们项目中就行了。
最终效果
image.png
集成Actviti
添加依赖
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.walle</groupId> <artifactId>activity-service</artifactId> <version>0.0.1-SNAPSHOT</version> <name>activity-service</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-boot-admin.version>2.1.1</spring-boot-admin.version> <spring-cloud.version>Greenwich.RC2</spring-cloud.version> <activiti.version>5.22.0</activiti.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!-- Activiti 启动器 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>${activiti.version}</version> </dependency> <!-- Activiti 流程图 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-diagram-rest</artifactId> <version>${activiti.version}</version> </dependency> <!-- Activiti 在线设计 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-modeler</artifactId> <version>${activiti.version}</version> </dependency> <dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.walle</groupId> <artifactId>common-service</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- swagger2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-dependencies</artifactId> <version>${spring-boot-admin.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project>
下载Activiti源码包
下载地址:https://www.activiti.org/get-started
解压下载的源码包后我们看到目录结构如下
创建数据库
在activiti-5.22.0/database/create 文件夹中找到对应数据库的sql文件 然后创建相关数据库。
另外,为了方便管理模型,我们才创建业务表来管理模型SQL如下
CREATE TABLE `ts_business_define` ( `business_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `business_code` varchar(100) DEFAULT NULL COMMENT '业务代码', `business_name` varchar(255) DEFAULT NULL COMMENT '业务名称', `proc_def_id` varchar(64) DEFAULT NULL COMMENT '流程定义ID', `model_id` varchar(64) DEFAULT NULL COMMENT '模型ID', `delete_status` int(11) DEFAULT '0' COMMENT '删除标记0=正常1=已删除', `create_by` bigint(20) DEFAULT '0' COMMENT '创建人', `create_byname` varchar(50) DEFAULT '0' COMMENT '创建人姓名', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `modify_by` bigint(20) DEFAULT NULL COMMENT '修改人', `modify_byname` varchar(50) DEFAULT NULL COMMENT '修改人姓名', `modify_time` datetime DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`business_id`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;
导入静态文件
将activiti-5.22.0/war/activiti-explorer.war解压
将文件夹内 diagram-viewer,editor-app,modeler.html拷贝到项目中resource/public目录下如图
这里需要修改editor-app/app-cfg.js 来设置项目跟路径 我们设置为空就可以
ACTIVITI.CONFIG = {
// 'contextRoot' : '/activiti-explorer/service',
'contextRoot' : '',
};
导入模型相关操作Controller
解压activiti-5.22.0\libs\activiti-modeler-5.22.0-sources.jar,将StencilsetRestResource.java,
ModelEditorJsonRestResource.java,ModelSaveRestResource.java三个文件拷贝到controller目录
下载汉化文件
汉化文件,下载文件并放在resource目录下
禁用登录验证
Activiti中自动集成了security的权限验证,当我们访问接口的时候会弹出登录界面,所以我们需要禁用掉登录验证
在启动类中添加注解
@SpringBootApplication @EnableAutoConfiguration(exclude = { org.activiti.spring.boot.SecurityAutoConfiguration.class, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class }) public class ActivityServiceApplication { public static void main(String[] args) { SpringApplication.run(ActivityServiceApplication.class, args); } }
创建模型
到此为止,我们的集成工作就基本完成了,我们可以通过浏览器访问
就可以新建一个模型了如图
模型管理
通过以上集成我们可以创建一个新的模型,然后我们会获取到一个模型ID 然后根据ID我们可以部署流程之类,现在我们通过一些简单的改造,来实现页面上对模型的操作和部署,并且和我们的业务关联起来。
业务关联模型
我们可以看到,这里需要一个模型ID的参数,我们可以把模型ID和业务定义关联起来,代码如下
@Autowired private RepositoryService repositoryService; @Autowired private BusinessDefineService businessDefineService; @PostMapping("getModelId") public ResultResponse getModel(Long businessId, HttpServletRequest request, HttpServletResponse response) { try { BusinessDefine businessDefine = businessDefineService.getById(businessId); String modelId = businessDefine.getModelId(); if (StringUtils.isBlank(modelId)) { modelId = createModel(businessId); } return ResultResponse.ofSuccess(modelId); } catch (Exception e) { log.error("",e); return ResultResponse.ofError(e.getMessage()); } } public String createModel(Long businessId) { try { String modelName = "modelName"; String modelKey = "modelKey"; String description = "description"; ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); ObjectMapper objectMapper = new ObjectMapper(); ObjectNode editorNode = objectMapper.createObjectNode(); editorNode.put("id", "canvas"); editorNode.put("resourceId", "canvas"); ObjectNode stencilSetNode = objectMapper.createObjectNode(); stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#"); editorNode.put("stencilset", stencilSetNode); Model modelData = repositoryService.newModel(); ObjectNode modelObjectNode = objectMapper.createObjectNode(); modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, modelName); modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1); modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description); modelData.setMetaInfo(modelObjectNode.toString()); modelData.setName(modelName); modelData.setKey(modelKey); //保存模型 repositoryService.saveModel(modelData); repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8")); BusinessDefine businessDefine = businessDefineService.getById(businessId); businessDefine.setModelId(modelData.getId()); businessDefineService.update(businessDefine); return modelData.getId(); } catch (Exception e) { return null; } }
这里我们进行了一下判断,业务是否关联了模型,如果关联返回模型ID 如果没关联,创建一个新的模型并返回Id并关联业务
部署模型
通过业务定义获取模型,然后部署模型
/**
* 根据Model部署流程
*/
@PostMapping(value = "deploy")
public ResultResponse deploy(Long businessId) {
try {
BusinessDefine businessDefine = businessDefineService.getById(businessId);
if (StringUtils.isBlank(businessDefine.getModelId())) {
throw new SystemException("请先设计模型");
}
Model modelData = repositoryService.getModel(businessDefine.getModelId());
ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
byte[] bpmnBytes = null;
BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
bpmnBytes = new BpmnXMLConverter().convertToXML(model);
String processName = modelData.getName() + ".bpmn20.xml";
Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes, "UTF-8")).deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
businessDefine.setProcDefId(processDefinition.getId());
businessDefineService.update(businessDefine);
return ResultResponse.ofSuccess();
} catch (Exception e) {
log.error("部署模型", e.getMessage(), e);
return ResultResponse.ofError(e.getMessage());
}
}
导出流程
/** * 导出model的xml文件 */ @GetMapping(value = "export") public void export(Long businessId, HttpServletResponse response) { try { BusinessDefine businessDefine = businessDefineService.getById(businessId); if (StringUtils.isBlank(businessDefine.getModelId())) { throw new SystemException("请先设计模型"); } String modelId = businessDefine.getModelId(); Model modelData = repositoryService.getModel(modelId); BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId())); BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode); BpmnXMLConverter xmlConverter = new BpmnXMLConverter(); byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel); ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes); OutputStream outputStream = response.getOutputStream(); IOUtils.copy(in, outputStream); String filename = bpmnModel.getMainProcess().getId() + ".bpmn.xml"; response.setHeader("content-type", "application/octet-stream"); response.setContentType("application/octet-stream;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename,"utf-8") ); outputStream.flush(); outputStream.close(); } catch (Exception e) { log.error("导出model的xml文件失败:{}",e.getMessage(), e); } }
导入流程
通过xml导入流程会生成流程定义,但是不会创建模型,所以我们要通过流程定义创建模型
导入流程定义
@PostMapping("import") public ResultResponse importXml(@RequestParam("file") MultipartFile file,Long businessId) { try { BusinessDefine businessDefine = businessDefineService.getById(businessId); InputStream fileInputStream = file.getInputStream(); Deployment deployment = repositoryService.createDeployment() .addInputStream(businessDefine.getBusinessName() +".bpmn", fileInputStream) .deploy(); ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult(); String modelId = changeProcessToModel(processDefinition); businessDefine.setProcDefId(processDefinition.getId()); businessDefine.setModelId(modelId); businessDefineService.update(businessDefine); return ResultResponse.ofSuccess(); } catch (Exception e) { log.error("导入流程定义失败:{}",e.getMessage(),e); return ResultResponse.ofError(e.getMessage()); } }
通过流程生成模型
/** * 流程转化为可编辑模型 * * @param processDefinition */ public String changeProcessToModel(ProcessDefinition processDefinition) { Model modelData = repositoryService.newModel(); ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); // 初始化Model ObjectMapper objectMapper = new ObjectMapper(); ObjectNode modelObjectNode = objectMapper.createObjectNode(); modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName()); modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1); modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription()); modelData.setMetaInfo(modelObjectNode.toString()); modelData.setName(processDefinition.getName()); modelData.setKey(processDefinition.getKey()); // 保存模型 repositoryService.saveModel(modelData); String deploymentId = processDefinition.getDeploymentId(); String processDefineResourceName = null; // 通过deploymentId取得某个部署的资源的名称 List<String> resourceNames = processEngine.getRepositoryService().getDeploymentResourceNames(deploymentId); if (resourceNames != null && resourceNames.size() > 0) { for (String temp : resourceNames) { if (temp.indexOf(".bpmn") > 0) { processDefineResourceName = temp; } } } InputStream bpmnStream = processEngine.getRepositoryService().getResourceAsStream(deploymentId, processDefineResourceName); createModelByInputStream(bpmnStream, modelData.getId()); return modelData.getId(); } public void createModelByInputStream(InputStream bpmnStream, String ModelID) { XMLInputFactory xif; InputStreamReader in = null; XMLStreamReader xtr = null; try { xif = XMLInputFactory.newFactory(); in = new InputStreamReader(bpmnStream, "UTF-8"); xtr = xif.createXMLStreamReader(in); BpmnModel bpmnModel = (new BpmnXMLConverter()).convertToBpmnModel(xtr); ObjectNode modelNode = new BpmnJsonConverter().convertToJson(bpmnModel); repositoryService.addModelEditorSource(ModelID, modelNode.toString().getBytes("UTF-8")); } catch (XMLStreamException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } finally { if (xtr != null) { try { xtr.close(); } catch (XMLStreamException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (bpmnStream != null) { try { bpmnStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } 完!
欢迎工作一到五年的Java工程师朋友们加入Java程序员开发: 854393687
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
HTML Webpack Plugin这是一个webpack插件,它简化了HTML文件的创建,以服务于你的webpack bundle。这对于在文件名中包含哈希的webpack包特别有用,因为文件名会改变每次编译。您可以让插件为您生成一个HTML文件,或者使用lodash模板提供您自己的模板,或者使用您自己的加载器。
针对webpack的版本,需要安装对应不同的版本。
webpack4
npm i --save-dev html-webpack-plugin@4
webpack5
npm i --save-dev html-webpack-plugin
这个插件会为你生成一个HTML5文件,其中包含了使用script标签的所有webpack的bundle。
只需将插件添加到webpack配置中,如下所示:
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: "./src/index.js",
output: {
filename:"index_bundle.js",
path: path.resolve(__dirname,"dist")
},
plugins: [
new HtmlWebpackPlugin()
]
}
这将生成一个包含以下内容的文件dist/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html>
如果您有多个webpack入口点,它们都将与script标签一起包含在生成的HTML中。
如果你在webpack的输出中有任何CSS资产(例如,用mini-css-extract-plugin提取的CSS),那么这些将包含在HTML头部的标签中。
如果你有使用它的插件,html-webpack-plugin应该在任何集成插件之前。
你可以传递一个配置选项到html-webpack-plugin。允许的值如下:
类型:String
默认值:Webpack App
描述:要用于生成的HTML文档的标题。
类型:String或Function
默认值:index.html
描述:要写入HTML的文件的文件名。默认为index.html。您也可以在这里指定一个子目录(例如:assets/admin.html)。占位符[name]将被条目名称替换。也可以是一个函数,例如(entryName) => entryName + '.html'。
类型:String
默认值:空
描述:默认情况下,它将使用src/index.ejs(如果存在的话)。
类型:string|Function|false
默认值:false
描述:可以用来代替模板提供一个内联模板。
类型:Boolean|Object|Function
默认值:false
描述:允许覆盖模板中使用的参数。
类型:Boolean|String
默认值:true
描述:true || 'head' || 'body' || false将所有资产注入到给定的模板或templateContent中。当传递'body'时,所有javascript资源将被放置在body元素的底部。'head'将把脚本放置在head元素中。设置为true时,将根据scriptLoading选项,决定是把脚本添加到head还是body中。使用false禁用自动注入。
类型:String|'auto'
默认值:auto
描述:publicPath属性值用于script和link 标签。
类型:blocking|defer
默认值:defer
描述:现代浏览器支持非阻塞javascript加载(“defer”),以提高页面启动性能。
类型:String
默认值:空
描述:将给定的图标路径添加到输出的HTML中。
类型:Object
默认值:{}
描述:允许注入meta标签。例如:meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}。
类型:Object|String|false
默认值:false
描述:注入一个base标签。如base:“https://example.com/path/page.html
类型:Boolean|Object
默认值:如果mode为'production'则为true,否则为false
描述:控制是否以及以何种方式压缩输出。
类型:Boolean
默认值:false
描述:如果为true,则附加一个唯一的webpack编译哈希到所有包含的脚本和CSS文件。这对于缓存销毁是很有用的
类型:Boolean
默认值:true
描述:只有当文件被更改时,才会删除它。
类型:Boolean
默认值:true
描述:错误的详细信息将写入HTML页面。
类型:?
默认值:?
描述:只允许添加一些chunk(例如:只添加unit-test 的chunk)
类型:String|Function
默认值:auto
描述:允许控制块在包含到HTML之前应该如何排序。允许的值是'none' | 'auto' | 'manual' | {Function}。
类型:Array.<string>
默认值:空
描述:允许你跳过一些chunk(例如不添加unit-test 的chunk)。
类型:Boolean
默认值:false
描述:如果为true,则将link标签呈现为自动关闭(XHTML兼容)
下面是一个webpack配置示例,演示了如何使用这些选项:
{
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
filename: 'assets/admin.html'
})
]
}
要生成多个HTML文件,请在插件数组中多次声明插件。
配置示例:
{
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin(), // Generates default index.html
new HtmlWebpackPlugin({ // Also generate a test.html
filename: 'test.html',
template: 'src/assets/test.html'
})
]
}
如果默认生成的HTML不能满足您的需要,您可以提供自己的模板。最简单的方法是使用template选项并传递一个定制的HTML文件。html-webpack-plugin会自动将所有必需的CSS, JS, manifest和favicon文件注入到标记中。
配置文件的部分内容:
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template',
// Load a custom template (lodash by default)
template: 'index.html'
})
]
模板文件index.html的内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>
如果您已经有一个模板加载器,您可以使用它来解析模板。请注意,如果您指定了html加载器并使用.html文件作为模板,也会发生这种情况。
module: {
loaders: [
{ test: /\.hbs$/, loader: "handlebars-loader" }
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template using Handlebars',
template: 'index.hbs'
})
]
您可以使用现成的lodash语法。如果inject特性不适合你的需要,而你又想完全控制资产的位置,可以使用html-webpack-template项目的默认模板作为你自己编写模板的起点。
*请认真填写需求信息,我们会在24小时内与您取得联系。