目录
ngAnnotate
拼接
压缩
首页 web前端 js教程 5分钟到最小的角度代码与咕unt声

5分钟到最小的角度代码与咕unt声

Feb 19, 2025 am 09:43 AM

5 Minutes to Min-Safe Angular Code with Grunt

网页性能优化是每个 Web 应用开发者都关注的首要问题。Grunt 等任务运行器在开发过程中扮演着关键角色,它们自动化了代码拼接和压缩等任务,这也是本教程的重点。我们将使用一系列 Grunt 插件来确保 AngularJS 应用能够安全地进行压缩。在讨论 AngularJS 和压缩之前,我想强调一点,所有技能水平的开发者都能从本教程中受益,但最好具备 Grunt 的基础知识。在本文中,我们将使用 Grunt 生成新文件夹,因此 Grunt 新手也能很好地了解其工作原理。

关键要点

  • 像 Grunt 这样的任务运行器自动化了代码拼接和压缩,优化了开发过程中的页面速度。Grunt 插件确保 AngularJS 应用能够安全地进行压缩。
  • 默认情况下,AngularJS 应用并非压缩安全的,必须使用数组语法编写。当 UglifyJS 运行时,它会重命名参数,但数组中 DI 注解的存在阻止了它们被重命名,确保重命名的参数仍然可以访问必要的依赖项。
  • Grunt 可用于自动化 AngularJS 应用的注解、拼接和压缩过程。安装必要的插件并将 Grunt 配置为读取“package.json”文件后,任务将被加载和注册。然后配置插件以定位特定文件。
  • Grunt 通过自动化捕获和防止错误的任务来帮助编写更安全的 Angular 代码。它可以在每次保存文件时对代码运行单元测试,立即向开发者发出错误警报。自动化节省了时间,并确保不会忽略重要任务。

Angular 应用压缩的问题

默认情况下,AngularJS 应用并非压缩安全的。它们必须使用数组语法编写。如果您不确定数组语法是什么,您可能已经编写过使用它的代码了。让我们来看两个 AngularJS 控制器示例,这两个控制器正在传递 $scope$http 参数。在下面的第一个示例中,模块的工厂和控制器包装在以 DI 注解开头的数组中,如您所见,它不遵循 DRY(不要重复自己)原则。

var form = angular.module('ControllerOne', [])
form.factory('Users', ['$http', function($http) {
    return {
        get: function() {
            return $http.get('/api/users');
        },
        create: function(userData) {
            return $http.post('/api/users', userData);
        },
        delete: function(id) {
            return $http.delete('/api/users/' + id);
        }
    };
}]);

form.controller('InputController', ['$scope', '$http', 'Users', function($scope, $http, Users) {
    formData = {};
    $scope.createUser = function () {
        if ($scope.formData != undefined) {
            Users.create($scope.formData)
                .success(function (data) {
                $scope.users = data;
                $scope.formData = {};
                $scope.myForm.$setPristine(true);
            });
        }
    };   
}]);
登录后复制
登录后复制
登录后复制
登录后复制

在下一个示例中,crud.config 模块代码仍然不是压缩安全的,但代码比之前的代码短。它只是命名服务,然后将必要的依赖项作为参数传递到函数中,而无需先将它们作为字符串写出来。只要不进行压缩,这段代码就可以正常运行。因此,很容易理解为什么人们在编写 AngularJS 代码时经常选择这种语法。

var form = angular.module('ControllerTwo', [])
form.factory('Users', function($http) {
    return {
        get: function() {
            return $http.get('/api/users');
        },
        create: function(userData) {
            return $http.post('/api/users', userData);
        },
        delete: function(id) {
            return $http.delete('/api/users/' + id);
        }
    };
});

form.controller('InputController', function($scope, $http, Users) {
    formData = {};
    $scope.createUser = function() {
        if ($scope.formData != undefined) {
            Users.create($scope.formData)
            .success(function(data) {
                $scope.users = data;
                $scope.formData = {};
                $scope.myForm.$setPristine(true);
            });        
        }
    };
});
登录后复制
登录后复制
登录后复制
登录后复制

既然您已经了解了这两段代码的物理差异,我将快速解释为什么这种语法不适合压缩。

数组表示法的运作方式

如上所述,数组表示法以 DI 注解开头,这在使代码压缩安全方面起着关键作用。当 UglifyJS 运行时,它会将我们的参数从 $scope$http 分别重命名为 ab。作为字符串传递到数组中的 DI 注解的存在阻止了它们被重命名。因此,这些重命名的参数仍然可以访问必要的依赖项。如果这些注解不存在,代码将中断。如您所见,以这种方式手动编写代码非常低效。为了帮助您避免这种情况,我现在将展示如何使用 Grunt 以完全优化的方式对 AngularJS 应用进行注解、拼接和压缩,并使其准备好用于生产环境。

使用 Grunt

可以在 GitHub 上找到项目的整个存储库,包括我们将要定位的文件。对于那些习惯使用 Grunt 的人,可以随意继续操作并创建您自己的构建,或将此代码添加到现有项目中。如果您正在使用空目录,则必须确保目录中有一个“package.json”文件。可以通过运行命令 npm init 来创建此文件。一旦您的项目中有了“package.json”文件,就可以通过运行以下命令下载插件:

var form = angular.module('ControllerOne', [])
form.factory('Users', ['$http', function($http) {
    return {
        get: function() {
            return $http.get('/api/users');
        },
        create: function(userData) {
            return $http.post('/api/users', userData);
        },
        delete: function(id) {
            return $http.delete('/api/users/' + id);
        }
    };
}]);

form.controller('InputController', ['$scope', '$http', 'Users', function($scope, $http, Users) {
    formData = {};
    $scope.createUser = function () {
        if ($scope.formData != undefined) {
            Users.create($scope.formData)
                .success(function (data) {
                $scope.users = data;
                $scope.formData = {};
                $scope.myForm.$setPristine(true);
            });
        }
    };   
}]);
登录后复制
登录后复制
登录后复制
登录后复制

这会将 Grunt 安装到您的项目中,以及我们将使用的三个插件:

  • grunt-contrib-concat
  • grunt-contrib-uglify
  • grunt-ng-annotate

尽管 ng-annotate 可以不用 Grunt 使用,但您很快就会看到 Grunt 使注解、拼接和压缩代码的过程多么无缝。它为压缩 AngularJS 代码提供了一个简单而有效的解决方案。如果您是从头开始跟踪此项目,则应该在项目根目录中有一个 Gruntfile.js,它将包含所有 Grunt 代码。如果您还没有,请立即创建它。

三步生成压缩安全的代码

步骤 1 – 配置 Grunt 以读取“package.json”文件

要访问我们之前安装的插件,您首先需要配置 Gruntfile 的 pkg 属性以读取“package.json”文件的内容。config 对象从 Grunt 包装函数的顶部开始,在下面的示例中从第 3 行到第 5 行扩展,但很快就会包含大部分代码。

var form = angular.module('ControllerTwo', [])
form.factory('Users', function($http) {
    return {
        get: function() {
            return $http.get('/api/users');
        },
        create: function(userData) {
            return $http.post('/api/users', userData);
        },
        delete: function(id) {
            return $http.delete('/api/users/' + id);
        }
    };
});

form.controller('InputController', function($scope, $http, Users) {
    formData = {};
    $scope.createUser = function() {
        if ($scope.formData != undefined) {
            Users.create($scope.formData)
            .success(function(data) {
                $scope.users = data;
                $scope.formData = {};
                $scope.myForm.$setPristine(true);
            });        
        }
    };
});
登录后复制
登录后复制
登录后复制
登录后复制

步骤 2 – 加载和注册 Grunt 任务

在配置 Grunt 以读取我们的“package.json”文件后,需要加载插件,以便 Grunt 可以访问它们。这是通过将插件的名称作为字符串传递到 grunt.loadNpmTask() 中来完成的。务必确保这些插件是在包装函数内部config 对象外部加载的。如果没有满足这些条件,Grunt 将无法正常工作。接下来我们需要做的是创建一个默认任务,当 Grunt 在没有特定目标的情况下被调用时将执行此任务。您应该注意添加这些任务的顺序,因为它们将根据其配置运行。在这里,ngAnnotate 配置为首先运行,然后是 concat 和 UglifyJS,我相信这是构建代码的最佳方式。此外,重要的是要记住,grunt.registerTask() 必须放在加载插件之后。根据我们刚才讨论的内容,Gruntfile.js 应该如下所示:

var form = angular.module('ControllerOne', [])
form.factory('Users', ['$http', function($http) {
    return {
        get: function() {
            return $http.get('/api/users');
        },
        create: function(userData) {
            return $http.post('/api/users', userData);
        },
        delete: function(id) {
            return $http.delete('/api/users/' + id);
        }
    };
}]);

form.controller('InputController', ['$scope', '$http', 'Users', function($scope, $http, Users) {
    formData = {};
    $scope.createUser = function () {
        if ($scope.formData != undefined) {
            Users.create($scope.formData)
                .success(function (data) {
                $scope.users = data;
                $scope.formData = {};
                $scope.myForm.$setPristine(true);
            });
        }
    };   
}]);
登录后复制
登录后复制
登录后复制
登录后复制

步骤 3 – 配置插件

ngAnnotate

现在我们的 Gruntfile 已准备就绪,让我们回到 config 对象中,并指定我们希望 ngAnnotate 插件定位的文件。为此,我们首先必须为 ngAnnotate 创建一个部分并创建一个目标,在本例中称为 spApp。在此目标中,您将指定要向其添加 DI 注解的文件,以及应将其生成的文件夹。在此示例中,Grunt 将获取在 public/js 中指定的三个文件,并将它们生成到名为 public/min-safe 的新文件夹中。配置完成后,您可以运行 grunt ngAnnotate 并查看代码的生成方式。此外,您可以访问 grunt-ng-annotate 的 GitHub 页面,并查看它允许您指定的不同选项。

var form = angular.module('ControllerTwo', [])
form.factory('Users', function($http) {
    return {
        get: function() {
            return $http.get('/api/users');
        },
        create: function(userData) {
            return $http.post('/api/users', userData);
        },
        delete: function(id) {
            return $http.delete('/api/users/' + id);
        }
    };
});

form.controller('InputController', function($scope, $http, Users) {
    formData = {};
    $scope.createUser = function() {
        if ($scope.formData != undefined) {
            Users.create($scope.formData)
            .success(function(data) {
                $scope.users = data;
                $scope.formData = {};
                $scope.myForm.$setPristine(true);
            });        
        }
    };
});
登录后复制
登录后复制
登录后复制
登录后复制

拼接

现在您已经生成了一个包含新注解的 AngularJS 代码的文件夹,让我们继续通过编译或将此代码拼接成一个单一文件。与我们为 ngAnnotate 创建部分的方式相同,我们现在将为 concat 和 UglifyJS 执行相同的操作。与 ngAnnotate 一样,这两个任务都接受一个目标,在本例中为 js。可以将许多配置选项传递到这些任务中,但我们只是简单地指定 srcdest 以指向正确文件。正如您可能猜到的那样,这些插件将获取传递到 src 对象的文件内容,并将它们处理到 dest 后面指定的文件夹中。让我们尝试理解这里发生了什么。您可以通过在终端中运行 grunt concat 来测试这一点,它应该导致创建 ./public/min/app.js

var form = angular.module('ControllerOne', [])
form.factory('Users', ['$http', function($http) {
    return {
        get: function() {
            return $http.get('/api/users');
        },
        create: function(userData) {
            return $http.post('/api/users', userData);
        },
        delete: function(id) {
            return $http.delete('/api/users/' + id);
        }
    };
}]);

form.controller('InputController', ['$scope', '$http', 'Users', function($scope, $http, Users) {
    formData = {};
    $scope.createUser = function () {
        if ($scope.formData != undefined) {
            Users.create($scope.formData)
                .success(function (data) {
                $scope.users = data;
                $scope.formData = {};
                $scope.myForm.$setPristine(true);
            });
        }
    };   
}]);
登录后复制
登录后复制
登录后复制
登录后复制

压缩

我们需要做的最后一件事是从代码中删除无用的空间,方法是压缩它。这就是 UglifyJS 插件发挥作用的地方。在使用 UglifyJS 时,我们希望 Grunt 完成压缩应用程序的最终过程。因此,我们要定位包含所有新拼接代码的文件,在本例中为 public/min/app.js。要测试这一点,请运行 grunt uglify,并查看您新压缩的文件。以下是此任务的相关配置:

var form = angular.module('ControllerTwo', [])
form.factory('Users', function($http) {
    return {
        get: function() {
            return $http.get('/api/users');
        },
        create: function(userData) {
            return $http.post('/api/users', userData);
        },
        delete: function(id) {
            return $http.delete('/api/users/' + id);
        }
    };
});

form.controller('InputController', function($scope, $http, Users) {
    formData = {};
    $scope.createUser = function() {
        if ($scope.formData != undefined) {
            Users.create($scope.formData)
            .success(function(data) {
                $scope.users = data;
                $scope.formData = {};
                $scope.myForm.$setPristine(true);
            });        
        }
    };
});
登录后复制
登录后复制
登录后复制
登录后复制

在本课程中,我们分别使用了所有这些任务。现在,让我们使用之前创建的默认任务。它允许 Grunt 按注册顺序一个接一个地运行所有指定的任务。现在,只需在项目中运行 grunt,您的代码就会被注解、拼接和压缩。

结论

我希望通过本简短教程,您能够很好地理解数组表示法,以及为什么它对于使 AngularJS 应用压缩安全至关重要。如果您是 Grunt 新手,我强烈建议您尝试使用这些插件以及其他插件,因为它们可以节省大量时间。与往常一样,请随时在下方发表评论,或者如果有什么问题,请通过我的个人资料中的地址给我发送电子邮件。

关于使用 Grunt 进行压缩安全的 Angular 代码的常见问题解答 (FAQ)

(此处应包含与原文中相同的FAQ部分,但语言更流畅自然)

以上是5分钟到最小的角度代码与咕unt声的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

神秘的JavaScript:它的作用以及为什么重要 神秘的JavaScript:它的作用以及为什么重要 Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

谁得到更多的Python或JavaScript? 谁得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? 如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

JavaScript难以学习吗? JavaScript难以学习吗? Apr 03, 2025 am 12:20 AM

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

如何实现视差滚动和元素动画效果,像资生堂官网那样?
或者:
怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? 如何实现视差滚动和元素动画效果,像资生堂官网那样? 或者: 怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? Apr 04, 2025 pm 05:36 PM

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript的演变:当前的趋势和未来前景 JavaScript的演变:当前的趋势和未来前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

console.log输出结果差异:两次调用为何不同? console.log输出结果差异:两次调用为何不同? Apr 04, 2025 pm 05:12 PM

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...

See all articles