【发布时间】:2019-06-04 15:19:22
【问题描述】:
我对 webpack 和 html-webpack-plugin 相当熟悉,并在其他几个 (SPA) 项目中使用过它们。但是在这个新项目中,我必须将旧的多页网站转换为使用 webpack。有一个自定义的 asp.net 处理程序 (ashx),当前通过在脚本标记中的 .ashx 引用的查询字符串上放置一个逗号分隔的脚本名称列表来捆绑(并在 prod 构建中缩小)注册脚本:<script src="Script.ashx?i=jquery,jquery-ui,...">。
其中一个问题是几乎所有页面都使用母版页。因此,没有 <body> 标记可用于 html-webpack-plugin。
如果我正在处理少量条目,我会使用一些 html-webpack-plugin 模板来注入脚本并将输出文件放置在项目文件夹结构中的正确位置。但是在项目文件夹结构的不同位置有 50 个 aspx 页面。所以我非常希望避免为所有这些页面维护单独的模板。
但鉴于这些文件中没有<body> 标签,我该如何将脚本注入到所需的位置?
我已经构建了一个自定义代码生成器来读取项目中的所有 aspx 页面并找到 Script.ashx 引用。然后,它解析逗号分隔的查询字符串并生成一个伴随的 .js 文件,其中每个引用的脚本都有一个导入语句。这些伴随的 .js 文件将在 webpack “entry” 数组中被引用。因此,例如 /home.aspx 获得一个伴随的 /home-entry.js 文件。该文件位于 webpack 配置中:entry { "home" : "./home-entry", ... }。并且对应的Script.ashx在源aspx页面中被注释掉了。我还将代码生成 webpack entry 数组和每个 entry 的 html-webpack-plugin 引用到 webpack 配置中的 plugins 数组中。
Home.aspx (sn-p):
<asp:Content ID="Content6" ContentPlaceHolderID="footerPlaceHolder" runat="server">
<script type="text/javascript" src="/Script.ashx?i=jquery,jquery-migrate,jquery-ui,jquery-watermark,popr,acrobat-detection,pdflinkfix,device,navbar,jqdialoghelper,home&v=<%= "" + MyNameSpace.Scripts.ScriptHelpers.AssemblyVersion %>"></script>
</asp:Content>
条目示例:
"home" : "./home-entry",
插件示例:
new HtmlWebpackPlugin( {
chunks: ['home-entry'],
alwaysWriteToDisk: true,
filename: "./home.aspx",
inject: 'body', // or what?
chunkSortMode: "dependency",
hash: true
} ),
home-entry.js:
import '/Scripts/jquery-3.3.1.min'
import '/Scripts/jquery-migrate-min'
import '/Scripts/jquery-ui-1.12.1.min'
import '/Scripts/jquery.watermark.min'
import '/Scripts/popr/popr'
import '/Scripts/acrobat_detection'
import '/Scripts/PDFLinkFix'
import '/Scripts/Device'
import '/Scripts/NavBar'
import '/Scripts/jqDialogHelper'
import '/Scripts/Home'
预期结果:最大的问题是我不知道是否有办法告诉 html-webpack-plugin 注入特定标签。 IE。我想要它做的是找到特定的<asp:Content ID="Content6" ContentPlaceHolderID="footerPlaceHolder" runat="server"> 标签并将脚本标签注入其中。请注意,还有其他 <asp:Content> 标记具有不同的 ContentPlaceHolderID 值。所以 html-webpack-plugin 必须找到带有ContentPlaceHolderID="footerPlaceHolder" 的那个。
实际结果:我相信使用默认的 html-webpack-plugin 选项,在没有 <body> 标签的情况下,插件会将脚本放在文件末尾。这会混淆asp.net。
【问题讨论】:
-
我不知道 webpack。但是你对 aspx 页面做了两个错误的假设。 1:
<asp:Content标签不呈现客户端,因此您无法引用它。 2:总会有一个body标签,来自母版页的标签。主页面和一个或多个内容页面将合并为一个 html 页面。 -
是的,我知道母版页与 aspx 页面交互的方式。并且脚本标签需要进入 asp:Content 标签,以便在最终的 html 流中呈现。请记住,webpack主要是一个运行前构建工具。因此,捆绑包是在发布到站点之前编译的。这就是为什么 aspx 页面在设计时需要脚本引用的原因。
-
好吧,我想我已经想出了一个计划。我将只在
标记中使用 SSI,并让我的 webpack 模板仅将脚本标记呈现到包含的文件中:例如 <!-- #include file="~/home-scripts.html" -->。现在测试一下。 -
我打算将其发布为我自己问题的答案,但我仍然没有回答我的实际问题。我想出了一个可行的解决方案。我最终做的是在项目中设置一个空模板。对于每个入口页面,现在项目中都有一组文件。所以对于
/SomeFolder/SomePage.aspx,我正在生成代码/SomeFolder/SomePage-entry.js。html-webpack-plugin仅使用脚本标签编写/SomeFolder/SomePage-bundles.inc。在该 aspx 文件中,我将旧的Script.ashx引用替换为:<!-- #include file="SomePage-bundles.inc" --> -
嗯,我遇到了上述设置的障碍。在我的 POC 中,我决定尝试合并我的 CSS。现在包含文件是用
<head>标记编写的,该标记包含我的样式的<link>标记。所以我仍然希望得到我原来帖子的答案。
标签: asp.net webpack webforms webpack-4 html-webpack-plugin