npm
背景
早期,前端是通过网址共享代码的,比如你想使用Bootstrap,你需要进入它的网站下载相关代码,放入到自己项目中。假如一个项目中需要使用非常多的共享代码,你去每一个网站下载相关代码,这是非常麻烦的事情。
2009年,Isaaz用js开发了npm(node package manager)去管理这些代码。
思路:
npm就像gitHub一样拥有代码仓库的功能。程序员把相关代码提交到仓库上,其他人通过npm install下载代码,同时会在项目的package.json的文件中加入依赖的代码名称和版本。
在你与他人共享代码时,不需要共享下载好的依赖代码,只需要共享package.json文件,其他人执行npm install就可安装项目的相关依赖。
常用命令
npm init//初始化
npm install xxx //下载依赖
npm uninstall xxx //卸载依赖
什么是淘宝镜像源?
淘宝镜像是一个提供国内高速下载的镜像资源,并且每10分钟,就和官方同步一次数据。平时下载包的时候可以使用淘宝镜像,但是想要发布包就必须是使用官方的源。
切换镜像源
nrm ls//罗列镜像源
nrm use name //使用镜像源
nrm del name //删除镜像源
nrm add name xxx //添加镜像源 nrm add taobao https://registry.npm.taobao.org/
如何发布自己NPM包?
创建一个项目,新建index.js文件
//index.js
module.exports = {
name:'anzi',
desc:'my first npm project'
}
npm init
//package.json
{
"name": "anzi-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"moment": "^2.29.1"
}
}
创建一个npm账号:https://www.npmjs.com/
npm login //登入
npm publish //发布
其它项目中用npm i来直接安装模块,在node_modules 目录可以找到对应的包
webpack
webpack会从一个或多个入口构建依赖图,项目中所需的模块组合成一个或多个bundles。
优点
1.可选插件,打包优化2.支持CommonJS、AMD、ES6等多种模块类型3.支持对css,图片等资源打包4.等等
支持多种模块类型的原理
代码中引入前面的包,然后使用webpack进行打包,在dist中找到如下代码
(() => {
/************************************************************************/
//引入的模块,保证唯一,不会重复引入
var __webpack_modules__ = {
"./node_modules/anzi-demo/index.js": (module) => {
module.exports = {
name: "anzi",
desc: "my first npm project",
};
},
};
/************************************************************************/
//模块缓存,找模块中会先去这边读取
var __webpack_module_cache__ = {};
// moduleId是路径
// var __webpack_module_cache__ = {
// moduleId:cachedModule
// };
// cacheModule = {
// exports: {} //导出的内容
// }
/**
* 获取导出的内容
* @param {*} moduleId
* @returns
*/
function __webpack_require__(moduleId) {
var cachedModule = __webpack_module_cache__[moduleId];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
//新建,从__webpack_modules__获取内容放入__webpack_module_cache__中
var module = (__webpack_module_cache__[moduleId] = {
exports: {},
});
__webpack_modules__[moduleId](
module,
module.exports,
__webpack_require__
);
return module.exports;
}
/************************************************************************/
//get defalut module
(() => {
__webpack_require__.n = (module) => {
var getter =
module && module.__esModule
? /******/ () => module["default"]
: /******/ () => module;
__webpack_require__.d(getter, { a: getter });
return getter;
};
})();
(() => {
// 可以兼容commonJS和es6不同模块,获取值
__webpack_require__.d = (exports, definition) => {
for (var key in definition) {
if (
__webpack_require__.o(definition, key) &&
!__webpack_require__.o(exports, key)
) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key],
});
}
}
};
})();
(() => {
//是否又prop
__webpack_require__.o = (obj, prop) =>
Object.prototype.hasOwnProperty.call(obj, prop);
})();
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, {
value: "Module",
});
}
Object.defineProperty(exports, "__esModule", { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
//自执行函数
(() => {
"use strict";
__webpack_require__.r(__webpack_exports__);
//获取模块数据
var anzi_demo__WEBPACK_IMPORTED_MODULE_0__ =__webpack_require__(/*! anzi-demo */ "./node_modules/anzi-demo/index.js");
var anzi_demo__WEBPACK_IMPORTED_MODULE_0___default =/*#__PURE__*/ __webpack_require__.n(anzi_demo__WEBPACK_IMPORTED_MODULE_0__);
//具体代码
document
.getElementsByTagName("button")[0]
.addEventListener("click", function () {
console.log("anziDemo", anzi_demo__WEBPACK_IMPORTED_MODULE_0__.name);
});
})();
})();
以上是使用CommonJS模块导出,如果使用es6模块导出,我们看一下具体代码
//npm包 index.js
import {name} from './user.js';
export let desc = 'my first npm project'
export let getUser = function(){
return name;
}
//npm包 user.js
export let name = 'anzi';
var __webpack_modules__ = ({
"./node_modules/anzi-demo/index.js":
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "desc": () => (/* binding */ desc),
/* harmony export */ "getUser": () => (/* binding */ getUser)
/* harmony export */ });
/* harmony import */ var _user_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./user.js */ "./node_modules/anzi-demo/user.js");
let desc = 'my first npm project';
let getUser = function () {
return _user_js__WEBPACK_IMPORTED_MODULE_0__.name;
};
}),
"./node_modules/anzi-demo/user.js":
/*!****************************************!*\
!*** ./node_modules/anzi-demo/user.js ***!
\****************************************/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "name": () => (/* binding */ name)
/* harmony export */ });
let name = 'anzi';
})
});
....
我们会发现,它们不太的只是webpack_modules__,使用__webpack_require.d方法把导出的内容加入到对象cacheModule.exports中。