原文:韦斯·博斯
翻译:博乐在线专栏作家——段新丽
链接:
JavaScript 环境正在迅速变化,网站和应用程序的依赖关系也在迅速变化。
本文适合大量使用脚本标签加载 JS 的程序员,随着网页数量和项目规模的增大,他们觉得依赖管理变得越来越繁琐。
如果你想深入了解每一个细节,并将CommonJS与AMD规范进行比较,请查看Axel Rauschmayer的探索ES6书,尤其是第17章。
什么是 JavaScript 模块?
JavaScript 模块允许我们将项目中的代码传播到单独的文件中,或者使用通过 npm 安装的开源模块。以模块化形式编写代码有助于组织、维护、测试,最重要的是,有助于依赖关系管理。
当我们编写 JavaScript 时,理想的情况是确保每个模块都专注于一件事并做好它。这种分工使我们能够在需要时加载模块。模块化是 NPM 背后的核心原则。当需要特定功能时,我们可以安装相应的模块并将其加载到应用程序中。
随着时间的推移,我们注意到大而完整的框架越来越少,而更多的是一个专注于一件事并做对的大模块。
例如,大多数人都使用过jQuery。这个库几乎包含了从CSS操作到ajax调用的所有内容。如今,许多人正在迁移到 React 的通用版本,我们经常需要加载额外的模块来完成 ajax 或路由等任务。
本文将概述 npm 和 ES6 模块的使用。对于其他包管理(如 Bower)和模块加载工具(如 CommonJS 和 AMD),已经讨论了许多文章和主题。
无论你是在做Node还是后端开发,我相信ES6模块和npm都是未来的发展方向。如果你看看像 React 或 lodash 这样的流行开源项目,你会发现它们都使用 ES6 模块 + npm。
当前开发流程
许多 JavaScript 开发过程如下所示:
找到符合您要求的插件或库,然后从 GitHub 下载。
通过脚本标签加载到网站。
使用全局变量或作为jQuery插件调用。
这种类型的开发过程多年来一直表现良好,除了一些问题:
插件必须自动升级 - 很难知道何时修复了关键错误或新功能可用。
令人困惑的源代码版本控制 - 所有依赖项都添加到源代码中,这可能会导致更新库时特别不愉快的结果(版本问题)。
基本上没有依赖管理 - 许多脚本具有重复功能,如果分成小模块,可以轻松共享。
代码污染和潜在的全局命名空间冲突。
这
编写模块化 JavaScript 的想法并不新鲜,但随着 ES6 的出现以及业界采用 npm 作为 JavaScript 的首选包管理工具,我们已经看到许多开发从以前的工作流转移到使用 ES6 和 npm 的标准化流程。
等等,npm?这不是特定于节点的吗?
npm 很久以前就开始作为 Node.js 的包管理工具,它已经演变成 JavaScript 和后端开发的包管理工具。现在,我们可以将库的安装过程简化为 2 个步骤:
1. 从 npm 安装依赖项,例如:
npm install lodash --save
2. 导出当前文件中昨天的依赖项,例如:
从“洛达什”导入 _;
在这个开发过程中还有很多工作要做,关于模块的导出和导入也有很多需要学习的地方,所以让我们仔细看看。
模块背后的理念
我们不是加载全局命名空间下的所有代码,而是使用导出和导入句子在文件之间共享代码(变量、函数、数据、任何代码)。每个模块导出所需的依赖项,您还可以为其他文件导入所需的代码。
让代码在浏览器中运行需要一个打包步骤,我们将在本文旁边讨论,但让我们专注于 JavaScript 模块背后的核心思想。
创建您自己的模块
假设我们正在构建一个在线购物应用程序,该应用程序需要一个文件来存储所有帮助程序函数。我们可以创建一个名为 helpers 的模块.js该文件包含帮助程序函数 - formatPrice(price)、addTax(price) 和 discountPrice(price、percent),以及一些关于在线商店的变量。
我们的助手.js文件如下所示:
常量税率 = 0.13;
constcouponCodes = ['黑色星期五','自由运输','HOHOHO'];
函数格式价格(价格){
:做一些低级的事情
返回格式的价格;
函数添加税(价格){
退货价格 * (1 + 税率);
函数折扣价格(价格,百分比){
退货价格 * (1 - 百分比);
现在,每个文件都有自己的局部函数和变量,只要它们没有显式导入,它们就永远不会渗透到其他文件的范围。在前面的反示例中,我们可能不希望其他模块访问 taxRate 变量,但我们确实需要在模块中使用它。
我们如何使这些函数和变量可供其他模块访问?答案是导入它们。ES6 中有两种导入方法,分别名为导入和默认导入。由于需要访问多个函数和 couponCodes 变量,因此我们使用命名导入。我们稍后会详细说明。
从模块导入代码的最简单形式是在行首添加 export 关键字,如下所示:
常量税率 = 0.13;
导出 constcouponCodes = ['黑色星期五','自由运输','呵'];
导出函数格式价格(价格){
:做一些低级的事情
返回格式的价格;/
/...
我们也可以在最后导入:
出口优惠券代码;
导出格式价格;
出口附加税;
出口折扣价格;
或者一次导入全部:
导出{优惠券代码,格式价格,添加税,折扣价格};
还有许多其他方便的导入方式,如果存在不符合您工作需求的情况,请查看 MDN 的文档。
默认导入
如前所述,有两种方法可以从模块导入 - 命名或默认。上面的示例使用命名导入。如果我们希望其他模块导出此出口jquery全局变量,我们必须知道要导出的变量/函数的名称 - 接下来将有一个示例。使用命名导入的有用之处在于,您可以从模块导入多个项。
另一种导入方法是默认导入。当你需要导入多个变量/函数时,可以使用命名导入,当你的模块只需要导入一个变量/函数时jquery全局变量,使用默认导入。尽管可以在模块中同时使用默认导入和命名导入,但我建议您每个模块仅使用一个窗体。
默认导入的案例是单独的 StorePicker React 组件或字段。例如,以下字段需要可供其他组件访问,我们可以默认导入它。
人.js
constfullNames = ['德鲁·明斯','希瑟·佩恩','克里斯汀·斯宾塞','韦斯·博斯','瑞安·克里斯蒂安尼'];
constfirstNames = fullNames.map(name => name.split(' ').shift());
export defaultfirstNames;// [“Drew”, “Heather”, “Kristen”, “Wes”, “Ryan”]
和以前一样,您可以将 export default 关键字添加到要导入的函数的末尾。
export default function yell(name) { return 'HEY ${name.toUpperCase()}!! ' }
导入您创建的模块
现在,我们已将代码分解为小模块并根据需要导入它们,是时候继续将模块导出到应用程序的其余部分了。
如果模块到
导出是代码库的一部分,我们使用import语句,然后指定文件相对于当前模块的路径 - 与通常以HTML格式导出资源路径或CSS背景图像相同。您会注意到,我们删除了.js后缀,因为后缀不是必需的。
应该注意的是,可以像全局变量一样访问整个应用程序,而不是导出一次模块。每当一个模块依赖于另一个模块时——例如,我们的代码需要一个 lodash 方法——我们必须导出它。如果我们有 5 个模块都需要相同的 lodash 函数,我们需要将其导出 5 次。这有助于保持范围清晰,同时使模块更轻、更可重用。导入
命名导入
我们首先导入了辅助模块。此处使用命名导入,现在,有许多方法可以导出它们:
将所有内容导出为对象的属性或方式
导入 * ashfrom'./helpers';
然后使用
constdisplayTotal = h.formatPrice(5000);
或者将所有内容直接导出到当前模块的范围
导入 * 来自'./助手';
constdisplayTotal = addTax(1000);
我不推荐这些样式,因为它们没有足够的清晰度,并且会使代码无法维护
或分组选择所需的导出
import{couponCodes,discountPrice}from'./helpers';
持续折扣 = 折扣价格(500,0.33);导入
默认导入
如果您考虑一下,我们还从 people.js 导入了一个名字字段,这是模块中唯一需要导入的部分。
默认导入可以以任何名称导出 - 您不需要知道导入的变量、函数或类的名称。
导入名字来自'./人';
或
从“./人”导入名称;
或
进口大象来自“./人”;
这些可以导出名字数组
您也可以像这样导出默认导入
导入 * 作为填充物从'./人'
consttheNames = stuff.default
从 npm 导入模块
我们使用的很多模块都来自 npm。无论你需要像jQuery这样的完整库,像lodash这样的纯实用程序库,还是像提供Ajax请求的超级代理这样的库,我们都可以使用npm安装它。
npm install jquery --save
npm install lodash --save
npm 安装超级代理 --保存
或一次性完成:
npmijquery lodash superagent -S
一旦这样的包存在于 node_modules/ 目录中,我们就可以将它们导出到我们的代码中。默认情况下,Babel 将 ES6 导出的句子编译到 CommonJS 中。因此,只需使用可以解析模块句子的打包工具(webpack 或 browserify),您就可以使用 node_modules/ 目录。我们只需要包含模块的名称来提取句子。其他打包工具可能需要插件或配置才能从 node_modules/ 目录导出。
导入整个库或插件
import$from'jquery';
那么正常使用就可以了$('.
cta').on('click',function(){
警报(“你点击了它!
});
上面的代码之所以有效,是因为 jQuery 是以 CommonJS 模式导入的,并且 Babel 翻译了 ES6 的导入语句以适应 jQuery 的 CommonJS 导出(语句)。
让我们再试一次超级代理。与jQuery一样,超级代理对整个库使用CommonJS规范的默认导入,因此我们可以随心所欲地命名它 - 通常称为request。
导出模块
来自“超级代理”的导入请求;
那就用吧!
请求
动漫函数动画在jQuery中的用法
定义和用法
animate() 方法执行 CSS 属性集的自定义动画,在指定或默认的时间内将属性从一个属性值更改为另一个属性值,因为属性值是逐渐变化的,所以产生了所谓的动漫效果。
模式参数
$(selector).animate(styles,speed,easing,callback)
风格:
样式用于设置对象属性值的目标值,即要创建的属性值的状态或大小。格式需要用字典格式编写,即一个属性对应一个属性值,如果同时设置多个属性值,则需要用冒号连接。如果属性值是数字,则可以保留没有单位,例如{“width”:100},如果要添加属性值,则用冒号将属性值括起来,例如{“width”: “200px”}
Animate 可以操作很多属性,并且它不能操作颜色jquery回调函数,例如对象背景颜色、字体颜色等,如果要操作颜色,则需要导出官方的 JS 文件。下载链接如下,读者可以自己下载并导出到自己的程序中。
下载后,您可以像这样导出它:
速度
速度是
rate和速度有多快的意思,即对象属性值从当前状态到你设置的另一个状态的变化时间,同时支持数值型和字符串型,数字类型可以直接写,不用冒号,单位是微秒。字符串是固定值“快”、“诺梅尔”、“慢”,如果不写,默认值为“正常”。
宽松“linear”表示
匀速,即一个对象属性的值在固定时间内从当前值变为另一个值,默认的“swing”参数表示曲线运动模式,先逐渐移动,然后加速,最后减速
回调回调是一个回弹函数,
表示动画执行后要调用的函数,使用此回弹函数,
我们可以实现动画来回运行,即在 Rebound 函数上将 Object 属性值设置为初始状态,然后在循环计时器的帮助下完成jquery回调函数,下面会给大家一个动漫代码,就是用这些思路实现的。
法典:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>13-jQuery中的动画</title>
<style>
.box {
width: 200px;
height: 200px;
background-color: green;
text-align: center;
line-height: 200px;
margin: 0 auto;
}
</style>
<script src="./js/jquery-1.12.4.min.js"></script>
<script src="./js/jquery.color.js"></script>
<script>
$(function () {
var $div = $('.box');
// 动画函数
/*
第一个参数: {} 动画属性 css属性
第二个参数: 动画持续时间 毫秒
第三个参数: swing linear 默认不传就是用 swing 可以实现不同的过度效果
第四个参数: 动画执行完成后的回调函数
*/
// 封装成函数
var oChange = function () {
// 更改标签内文字
$div.html('life is short');
$div.animate({
'width': '100%',
'background-color': 'red',
'font-size': '80px',
'color': 'pink',
'border-radius': '2000px',
}, 2000, 'swing', function () {
// 更改标签内文字
$div.html('you need python');
$div.animate({
'width': 200,
'background-color': 'green',
'font-size': '16px',
'color': 'red',
'border-radius': '0px',
}, 2000, 'swing');
});
}
// 第一个参数要是一个函数
setInterval(oChange, 4000);
})
</script>
</head>
<body>
<div class="box">life is short
</div>
</body>
</html>
发表评论