如何开发出更好的JavaScript模块
不少人都曾经在npm上发布过自己开发的JavaScript模块,而在使用一些模块的过程中,我经常产生“这个模块很有用,但如果能xxx就更好了”的想法。所以,本文将站在模块使用者的角度总结一下,如何能让模块变得更好用。
提供ES6模块的入口
webpack和rollup都支持对ES6模块做一些静态优化(例如TreeShaking和ScopeHoisting),它们都会优先读取package.json中的module字段作为ES6模块的入口,若没有module才会读取main字段作为CommonJS模块的入口。通常的做法是:使用ES6语法编写源码,然后用模块打包工具结合语法转换工具生成CommonJS模块和ES6模块,这样就可以同时提供main和module字段了。
提供TypeScript的类型声明文件
如果你的用户使用了TypeScript但你的模块没有提供声明文件,他们就不得不在项目中添加一段代码避免TypeScript的编译错误;另外,这样做并不只是对使用TypeScript的用户友好,因为大部分代码编辑器(Webstorm、VSCode等)都能识别TypeScript的类型声明,它们可以据此提供更精准的代码提示并在用户传入错误的参数个数或类型时给出提示。
最好的做法是使用TypeScript编写你的模块,编译时会自动生成类型声明。除此之外,你也可以参照文档手动维护一份声明文件。你可以在你的模块根目录下添加index.d.ts文件,或者在package.json中声明typings字段提供声明文件的位置。
让模块同时在Node.js与浏览器中运行
你可以通过检测是否有名为window的全局变量(例如!!typeofwindow)来判断模块当前是运行在Node.js还是浏览器中,然后使用不同的方式实现你的功能。
这种方法比较常见,但如果用户使用了模块打包工具,这样做会导致Node.js与浏览器的实现方式都会被包含在最终的输出文件中。针对这个问题,开源社区提出了在package.json中添加browser字段的提议,目前webpack和rollup都已经支持这个字段了。
browser字段有两种使用方式:
给browser字段提供一个文件路径作为在浏览器端使用时的模块入口,但需要注意的是,打包工具会优先使用browser字段指定的文件路径作为模块入口,所以你的module字段会被忽略,这会导致打包工具不会优化你的代码。详细信息请参考这个问题。
如果你只想替换其中一些文件,你可以声明一个对象。
举个例子,假设你的模块里有两个文件:http.js和xhr.js,第一个文件使用Node.js中的http模块发起请求,另一个使用浏览器中的XMLHTTPRequest实现了同样的功能。为了使用适当的文件,你的模块代码中应该始终require(‘./path/to/http.js'),并在package.json中声明:
{ "browser":{ "./path/to/http.js":"./path/to/xhr.js" } }
这样一来,当你的模块在打包工具中使用时,打包工具只会将xhr.js的代码包含在最终的输出文件中。
使用各种服务武装你的项目
大部分JavaScript项目都是开源的,而开源社区也提供了很多针对开源项目的免费服务,它们可以给你的项目提供更有力的帮助,这里列举几个比较常用的。
一个项目最常使用的服务就是持续集成了。持续集成服务能将测试、代码风格检测、打包等任务放在服务器上,并在你提交代码时自动运行,常用的有TravisCI、CircleCI和AppVeyor。TravisCI对开源项目免费,提供Linux与OSX运行环境;CircleCI对开源与私有项目都免费,但每个月有1500分钟的运行时间限制;AppVeyor提供Windows运行环境,同样对开源项目免费。
运行完测试之后,你还可以将测试覆盖率上传到Coveralls。这个服务能让你在线浏览代码的测试覆盖情况。
如果你想让你的模块在各个版本的各种浏览器、平台下得到充分的测试,你还可以使用SauceLabs和BrowserStack,它们都是对开源项目免费的,但需要发邮件申请。
最后,ShieldsIO提供了各种图标,这些图标能为你的项目提供很多额外信息,包括但不限于npm版本号、下载量、测试通过状态、测试覆盖率、文件大小、依赖是否过期等。
以上就是我们分享给大家的如何开发出好用的JavaScript模块的全部内容,大家如果还有任何不明白的地方可以在下方的留言区域讨论,感谢你对毛票票的支持。