翻译自: Using jQuery plugins with npm
上周我们讨论了 如何发布jQuery的插件到npm,快速而原始的方式 。由于快速和原始,我们的意思是,你可以简单地发布你的模块到npm–没有任何修改–人们就可以使用它。但是一些插件需要做额外的工作,并添加一点点代码,使其可以更容易通过npm基础工具使用。
在这篇文章中,我们将向你展示如何使用快速而原始的方式发布jQuery插件…也就是说,插件无需使用package.json主导文件或者设置一个全局变量,不管他们是否直接在浏览器中使用或者被像Browserify这样的工具捆绑。
在接下来的文章中,我们将向你展示如何更新你的插件来使用npm特有的功能,这使得开发人员更容易使用你的模块(对于你,当你在项目中用你自己的插件上)。 我们还将向您展示如何使之与Node,CommonJS的模块系统结合工作,并充分利用模块化,使你的插件更易于维护,更容易。
这种类型的插件,我们不导出 Node兼容模块 (使用CommonJS的模块格式)并且不希望使用这样的模块工作。相反,它只是期望一个jQuery对象(在全局范围内)使用该插件一起工作。
然而,即使一个插件确实知道如何使用Node兼容的CommonJS模块工作,你仍然可以使用我们在这里描述的方法,所以你不必担心搞清楚的区别。我们将在接下来的文章中阐述差异。
我们将开发一个简单的网页,其中使用 tipso 提示插件。你可以在 GitHub 上找到这个demo的最终代码。
我们将讨论多种措施。所有使用npm处理前端的资源的不同方法各有优点和缺点。我们希望能帮助你挑选最适合你的团队的开发工作流程的策略。在接下来的文章中,我们将先从最简单的工作流程,并从这里开始建立一个更清洁,更易于维护的工作流程。我们将在本文和以后的文章中讨论你应该考虑的权衡。
我们将在这篇文章中探讨这两种方法:
1.直接包括脚本文件;
2.用Browserify打包文件;
如果你有不同的做法可以评论或在 Twitter上@npmjs
对于这两种方法,我们需要建立一个项目。
1.创建一个目录
mkdir demo cd demo
2.添加一个 package.json
文件,其内容如下
{ "name": "demo", "version": "1.0.0" }
3.安装tipso包npm install –save tipso
--save
标记将其作为依赖添加到您的 package.json
文件,在你实际的工作项目中,这是很有用的,它可以更容易地更新你的依赖,并且如果您共享该项目,其他人很容易下载依赖模块。
这种方法看起来很熟悉,工作起来也是最简单的,因为它不需要任何额外的工具。你只要添加script标记到你的HTML,src使用.js文件的完整路径就可以了。
1.在根目录创建一个 index.html
文件。
2.添加下面的代码到 body
中。
<span class="title-tipso tipso_style" title="This is a loaded TIPSO!">Roll over to see the tip</span>
3.从CDN添加jQyuer。任何CDN都可以。
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
4.直接创建依赖关系树。
npm dedupe
因为我们在package.json中宣告我们所有的依赖性,所以我们并不真的需要做到这一点,但它是一个很好的做法。
5.添加tipso包的脚本
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
6.添加一个 script.js
脚本文件,使用tipso添加工具提示。
jQuery(function(){ jQuery('.title-tipso').tipso(); });
7.添加tipso的CSS
<link rel="stylesheet" href="node_modules/tipso/src/tipso.css" />
8.在浏览器中打开index.html,鼠标在文本上移动。您应该看到提示弹出一个工具提示。
最终文件类似这样:
<!doctype html> <html> <head> <title>npm and jQuery demo</title> <link rel="stylesheet" href="node_modules/tipso/src/tipso.css" /> </head> <body> <span class="title-tipso tipso_style" title="This is a loaded TIPSO!">Roll over to see the tip</span> <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> <script src="node_modules/tipso/src/tipso.js"></script> <script src="script.js"></script> </body> </html>
这个方法有一些缺点。
1.这种方法可维护性很差。 tipso对jQuery的依赖没有在任何地方定义,除非在开发者的脑子里。如果一个新的开发者接手维护这个项目,或者,如果你6个月后回来维护这个代码,当你需要重新调整网站上的另一部分功能时,不会很明显的表面哪些脚本需要添加。
2.这种方法效率也不高,因为它会产生大量的资源文件请求数。这里文件里有4个请求——script.js,tipso JS,tipso CSS和jQuery(尽管这是从一个CDN的到来,所以很可能是已经缓存)。在这个演示中单独处理每个文件的效率不那么明显,它只有几个文件,但是如果是一个更大的项目呢?
3.你的 node_modules
目录结构可能改变。由于在 index.html
中路径是硬编码的,如果你运行NPM更新或目录移动,您的应用程序将被破坏。这是不太可能发生在这样一个简单的应用中,但如果是一个复杂的项目的话那就不好说了。对于这个问题有解决方法,但是不在这里。
我们将不能够解决问题3,直到我们在接下来的文章中对插件本身作出改进,但我们可以通过使用Browserify工具修复问题1和2,这带来了一些其他的好处。
Browserify是一个工具,它使得后端和前端包更容易的使用,然后将所有的JavaScript打包成一个单一的文件,该文件可以包含到你的HTML中。(愚人码头注:Browserify本身不是模块管理器,只是让服务器端的CommonJS格式的模块可以运行在浏览器端。这意味着通过它,我们可以使用Node.js的npm模块管理器。所以,实际上,它等于间接为浏览器提供了npm的功能。)
例如,用Browserify可以使用 ngraph.generators 和 ngraph.vivasvg 创建一个爆炸点的动画。
除了使你的前端代码更容易地使用npm上127,000+ 的包,Browserify也使得你的团队更容易的模块化方式来开发,从而提高了代码的结构,使得它更容易维护。在接下来的文章中你会看到这个功能。
很多人没有意识到这一点,但即使你正在使用一个不兼容CommonJS的jQuery插件,你仍然可以使用Browserify。
构建项目时,你使用的Browserify是一个命令行工具。当你运行你的应用程序它并没有加载。这意味着,它应在全局下安装,不作为项目的依赖。npm install -g browserify
如果你得到一个错误,说EACCES,看看我们的文档上的 fixing permissions ,或者使用sudo运行命令。
首先,我们要打包正在使用JavaScript。
1.去除 index.html
中现有的 script
和 link
标签 ,并增加一个 script
标签引用 bundle.js
:
<!doctype html> <html> <head> <title>npm and jQuery demo</title> </head> <body> <span class="title-tipso tipso_style" title="This is a loaded TIPSO!">Roll over to see the tip</span> <script src="./bundle.js"></script> </body> </html>
bundle.js
文件是Browserify为我们自动生成的。它将是包括所有的JavaScript的包,使用这种方式确保依赖关系能正确传递给依赖于它们的模块。
2.添加的jQuery的依赖。这样可以很容易地 require
其他的 .js
文件。
npm install --save jquery
注意:您可以继续使用script标记来引用jQuery。出于依赖处理的一致性,我们宣告它为依赖(并在下一步骤中引用它),但你可能要一个更具性能优势CDN jQuery。
3.创建一个 entry.js
文件。
global.jQuery = require('jquery'); require('tipso'); jQuery(function(){ jQuery('.title-tipso').tipso(); });
这将是Browserify启动的进入点。这里它会寻找依赖性,并按照依赖关系树知道需要什么样的代码包含到 bundle.js
中。
和在 index.html
中之前的脚本一样。不同的是这一次,不包括jQuery和tipso作为单独的script标记,我们使用Node的 require
功能,让Browserify知道,我们依赖他们。
当浏览器加载时,tipso需要依赖全局的jQuery对象。然而,在Node.js中,我们使用 var
声明的变量是本地模块,而不是全局性的。为了使tipso的依赖,我们需要公开jQuery为一个全局的,因此,我们将其附加到Browserify提供的 global
对象上。
4.告诉browserify在那里可以找到tipso。要做到这一点,添加一个 browser
键到你的 package.json
中。
"browser": { "tipso": "./node_modules/tipso/src/tipso.js" }
查看上下文. 如果在tipso的 package.json
文件中 main
文件指向 tipso.js
文件,我们不会需要做这一点。我们将在接下来的文章中介绍。
5.运行browserify来创建 bundle.js
browserify entry.js --debug > bundle.js
我们使用 --debug
标记来为打包文件添加source maps。这将使它更容易在浏览器的控制台进行调试。
6.加载 index.html
,然后鼠标移动到文本。你会看到文本弹出,但它不会有很好的泡泡轮廓。这是因为我们还没有将CSS添加回来。
处理前端资源的最佳实践,如CSS文件,仍然在发展中。社区提出了多种解决方案,但没有一个是明显的赢家。通过不同的前端生态系统的项目的问题的讨论,我们将持续关注更好的支持,找出最好的策略给大家,但现在没有完善的办法做到这一点。
我们已经找到了最简单的方法是使用 parcelify ,但你也可能会发现对你而言更好的不同方法。
1.全局下安装parcelify
npm install -g parcelify
2.告诉parcelify在哪里可以找到你所需要的CSS。要做到这一点,添加一个 style
键到你的 package.json
中
"style": [ "./node_modules/tipso/src/tipso.css" ]
查看上下文.
另一个步骤,我们可以通过改变tipso包消除这个,我们将在接下来的文章中看到。
3.运行parcelify来创建 bundle.css
parcelify entry.js -c bundle.css
4.为 bundle.css
添加一个 link
元素到 index.html
中
<link rel="stylesheet" href="bundle.css" />
5.刷新index.html,然后鼠标移动到文本。泡泡轮廓的CSS已经恢复。
在第一种方法中,我们使用了CDN的jQuery源代码。您可能已经注意到,第二种方式没有这么做。相反,它将jQuery打包到 bundle.js
文件中。这意味着, bundle.js
是比较大的文件。
但是,这并不是必须这样做。您可以使用一个叫做 browserify-shim 的工具仍然使用CDN的jQuery。
虽然我们不会涵盖在这里使用,但你可以找到更多关于browserify-shim的 README 。
在这篇文章中,你学会了如何以快速而原始的方式来使用已发布到npm的jQuery插件——在这种方式中,没有使用npm的特殊功能或CommonJS模块。
第一种方法是类似于大多数开发者目前的做法,直接引用脚本,并且跟踪依赖关系——该脚本依赖于哪些其他脚本——基本在开发者自己的脑子里。这种方法也使得产生了更多的请求,这使得网页加载变慢和硬编码的文件名,这意味着,如果你在目录中移动、更新你的库代码和文件,这些硬编码的引用可能会错误。
第二种方法中,使用Browserify打包依赖,通过使用 require
函数,显式依赖将需要的代码包括进来。这使得一个新开发者(或者在6个月)更容易接手维护项目(了解在应用程序中哪些脚本使用的其他部分)。Browserify还合并了JavaScript和CSS文件,如果你有多个脚本和CSS文件,这将有助于更快的加载页面。不幸的是,我们并没有摆脱硬编码文件名的问题。tipso的CSS和JS的路径需要在 package.json
中硬编码。
但是有一个方法可以解决最后一个问题。在接下来的文章中,你会看到,你如何使用npm的特殊功能提什自己的插件,使你的代码更加模块化。
就像我们之前说的,有很多的方式来前端的资源的工作。如果你有很好的工作和其他的解决方案,可以评论或在 Twitter上@npmjs 让我们知道。
翻译水平有限,如有错误欢迎评论拍砖或微博上@愚人码头