不知从什么时候开始,网上非常流行面试类的技术文章,讲述某次失败或者成功的面试过程以及面试中被问到的题目,这些文章中的题目大部分都是松散零碎,毫无关联的。可能这些文章会帮助你了解到你不曾掌握的点,但仅仅就是了解,真的掌握仅仅只靠面试题是不够,就好比平时学习不努力,靠考前做几套名校试卷,或者模拟套题是不够的。
虽然自己也未能免俗,收藏了一堆面试文章,但是还是更愿意看一些更有技术针对性的文章,甚至能自己写一篇。这是第一次写文,缘由是工作中的一个需求,多个项目需要共用一些组件,那么比较方便的做法就是将这些组件封成一个包,发布到 NPM 上。但是由于这些组件是公司自用,和公司业务紧密关联,不便于发布成公共包,虽然 NPM 现在也提供了私有包服务,但是由于某些不可抗拒的网络因素,即使付费可能也享受不到好的服务,所以考虑内部搭建一个 NPM 私有仓库。
这篇文章就是这次搭建私有仓库涉及到的相关知识,总结之后发现是一个比较完整知识链,所以分享给大家,水平不高,能力有限希望大家多担待,本文参考了一些内容,也尽量保证都是自己亲自验证过的,如果有错误或疏漏欢迎大家指正。
当我们现在用 JavaScript 大型单页应用以及服务端程序时,谁又能想到 JavaScript 这门语言在诞生之初目的只是为了替服务端完成一些输入验证操作。功能的复杂意味着代码量的提升,而模块化正是为了解决因此带来的维护困难,结构混乱,代码重复冗余等问题。很不幸的是在 ES6 之前,JavaScript 并不天然支持模块化编程。
不过虽然 JavaScript 不支持模块化编程,但是我们可以通过对象,命名空间,立即执行函数等方法实现"模块"的效果,具体的一些方法可以参考阮一峰的:Javascript 模块化编程(一):模块的写法。
这种情况直到 nodejs 出现,并参照 CommonJS 实现了模块功能才得到改善。
在 nodejs 中我们可以很方便的导出和引入模块:
// module.jsconst name = 'wang';const age = 18;function showName() {
console.log(wang);}function showAge() {
console.log(age);}module.exports = {
showName,
showAge};// page.jsconst module = require('./module.js');module.showName(); // wangmodule.showAge(); //18但是 CommonJS 规范不适用于浏览器环境,不说浏览器没有 require 方法,服务端文件 require 一个包只是读取本地的一个文件,而客户端则是网络加载,网络加载速度和硬盘读写速度差距可不是一星半点,这种写法总不能让客户端 require 时假死在那里,前端处理这种问题的方法首先想到应该就是通过异步加载回调来处理。
为了让浏览器支持模块化开发,于是出现了基于AMD规范的RequireJS和基于CMD规范的SeaJS
它们的区别主要是(参考知乎上 SeaJs 开发者玉伯的回答):
对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible。
CMD 推崇依赖就近,AMD 推崇依赖前置
写法如下:
// CMDdefine(function(require, exports, module) {
var a = require('./a');
a.doSomething();
var b = require('./b'); // 依赖可以就近书写
b.doSomething();});// AMD 默认推荐的是define(['./a', './b'], function(a, b) {
// 依赖必须一开始就写好
a.doSomething();
b.doSomething();});