在使用Gruntjs进行压缩/混淆后,如何更改HTML中的链接或脚本文件名?

22

我正在使用标准的css/js文件最小化和混淆,并将多个文件合并为main.min.css或app.min.js... 但是我的.html文件也需要修改,以指向这些新的文件名,包括在<link>或<script>中

是否有自动化的方法? 或如何使用gruntjs自动修改.html文件以重新命名其中的文件名?


你的HTML文件里不应该直接使用main.min.css吗?为什么需要改变它呢?当你更新源文件时,它应该会覆盖已编译的文件。 - Brian Glaz
1
这只是开发与生产环境的区别。我可以这样做。但在开发环境中,我的习惯是将文件分开以便于跟踪和调试。 - HP.
你是否使用了像 PHP 这样的服务器端语言?你可以在文件中放置一个条件 if 块来检查你当前是在开发环境还是生产环境。 - Brian Glaz
是的,Python。我猜你的建议也是一个有效的观点。 - HP.
5个回答

17
你可以使用 grunt-string-replace 来实现这个。以下是一个示例,说明如何使用它。
在我的 index.html 中,你会找到以下导入标签:
<!--start PROD imports
<script src="assets/dist/traffic.min.js"></script>
end PROD imports-->

<!--start DEV imports-->
<script src="assets/js/app.js"></script>
<script src="assets/js/services.js"></script> 
<script src="assets/js/directives.js"></script>
<script src="assets/js/filters.js"></script>
<script src="assets/js/resources.js"></script>
<script src="assets/js/controller/homeControllers.js"></script>
<script src="assets/js/controller/adminControllers.js"></script>
<script src="assets/js/controller/reportsControllers.js"></script>
<!--end DEV imports-->

注意 'start imports' 和 'end imports' 的注释。默认情况下(在 DEV 环境中),我们注释掉了 PROD 导入。

在我的 grunt 文件中,我添加了以下任务:

    'string-replace': {
        inline: {
            files: {
                'index.html': 'index.html'
            },
            options: {
                replacements: [
                    {
                        pattern: '<!--start PROD imports',
                        replacement: '<!--start PROD imports-->'
                    },
                    {
                        pattern: 'end PROD imports-->',
                        replacement: '<!--end PROD imports-->'
                    },
                    {
                        pattern: '<!--start DEV imports-->',
                        replacement: '<!--start DEV imports'
                    },
                    {
                        pattern: '<!--end DEV imports-->',
                        replacement: 'end DEV imports-->'
                    }
                ]
            }
        }
    }

运行任务(grunt string-replace)后,我得到了:

<!--start PROD imports-->
<script src="assets/dist/traffic.min.js"></script>
<!--end PROD imports-->

<!--start DEV imports
<script src="assets/js/app.js"></script>
<script src="assets/js/services.js"></script>
<script src="assets/js/directives.js"></script>
<script src="assets/js/filters.js"></script>
<script src="assets/js/resources.js"></script>
<script src="assets/js/controller/homeControllers.js"></script>
<script src="assets/js/controller/adminControllers.js"></script>
<script src="assets/js/controller/reportsControllers.js"></script>
end DEV imports-->

现在DEV导入已被注释掉,而PROD导入没有被注释掉。


如果我将PROD注释掉并取消注释DEV,该如何撤销这个操作? - ram
开发文件名仍然可以在html文件中使用页面源代码查看!我希望有一种方法可以完全删除开发文件名,并将构建后的文件名添加到主要的html文件中。 - Kaustubh
@ram,为了完整的开发/生产设置,我会创建一个任务来将我的HTML从源目录复制到生产目录,只有生产目录会被上述任务改变。因此,如果您查看源代码,它们始终处于开发状态,而prod目录可以随时清理并重新生成。 - JrBenito
@Kaustubh,我同意,另一个任务可以用于删除HTML注释,或者基于以下内容的另一个开发设置:将源文件作为模板,使用模板生成开发版本,使用模板生成生产版本,但是生产版本会进行文件压缩。 - JrBenito

14

使用grunt-processhtml可以轻松实现自动化。以下是来自文档的示例:

<!-- build:js app.min.js -->
<script src="my/lib/path/lib.js"></script>
<script src="my/deep/development/path/script.js"></script>
<!-- /build -->

<!-- changed to -->
<script src="app.min.js"></script>

阅读更多内容,请访问https://www.npmjs.org/package/grunt-processhtml


如果您的 min.js 文件名是在代码混淆时动态创建的,那么如何在不将其硬编码到 <!-- build:js app.min.js --> 标签下的 HTML 文件中的情况下使用它呢? - hyprstack
@hyprstack 看一下我的答案,它也处理这种情况,只要你可以使用通配符来匹配动态名称。(例如 *.min.js 或另一个目录用于缩小文件) - JrBenito

1

一个非常适合的grunt任务是grunt-html-build

它可以将HTML的某些部分从开发版本替换为生产版本。在那里看到示例,很容易设置。

现在,使用grunt-html-build的标准配置,如果在构建过程中动态命名缩小文件,例如:

some-file.js -> another-name.min.js

可以配置grunt-html-build

[...]
scripts: {
   bundle: [
            '<%= fixturesPath %>/scripts/*.min.js'
   ]
},
[...]

一个类似以下的HTML部分:

<!-- build:script bundle -->
<script type="text/javascript" src="/path/to/js/libs/jquery.js"></script>
<script type="text/javascript" src="/path/to/js/libs/knockout.js"></script>
<script type="text/javascript" src="/path/to/js/libs/underscore.js"></script>
<script type="text/javascript" src="/path/to/js/app/module1.js"></script>
<script type="text/javascript" src="/path/to/js/app/module2.js"></script>
<!-- /build -->

会被转换成类似下面的内容:

将产生一些这样的东西:

<script type="text/javascript" src="scripts/other-name.min.js"></script>
<script type="text/javascript" src="scripts/another-other-name.min.js"></script>

那就是@hyprstack在评论中询问的内容。

0
你可以使用grunt preprocess来实现这个功能:https://github.com/jsoverson/grunt-preprocess 基本上,你需要设置一个模板,并让preprocess替换相关部分。
Gruntfile的部分代码将如下所示:
preprocess: {
    dev: {
            options: {
                    context: {
                            DEBUG: true,
                            HOST: '<%= env.dev.HOST %>'
                    }
            },
            files: {
                    'index.html': 'tpl/index.tpl'
            }
    },
    production: {
            options: {
                    context: {
                            DEBUG: false,
                            HOST: '<%= env.production.HOST %>
                    }
            },
            files: {
                    'index.html': 'tpl/index.tpl'
            }
    }

},


这不是我想要的,因为所有的HTML代码都必须在模板中。我正在使用Middleman应用程序在gruntjs之前即时编译我的Haml。我想知道是否有一个搜索/替换功能可以使用正则表达式匹配链接/脚本标签。这样一来,当我完成代码后,只需要运行一次gruntjs就可以进行搜索/替换。 - HP.

0
我正在使用Middleman应用程序来区分我的html或haml文件中的dev vs build:
- 如果是开发环境? 和 - 如果是编译环境?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接