| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> JavaScript知识库 -> 模块化与包管理工具 -> 正文阅读 |
|
[JavaScript知识库]模块化与包管理工具 |
作者:more-toolbox-new |
## 模块化基本介绍 ### 模块 模块是对功能相似的函数或属性的封装。例如: ??? ?fs 模块中封装了一系列文件操作的函数。例如:fs.readFile()、fs.writeFile() ??? ?path 模块中封装了一系列路径处理的函数。例如:path.join(),path.basename() 模块的好处:提高了函数的复用性! ### 什么是模块化 一个js文件可以引入其他的js文件,能使用引入的js文件的中的变量、数据,这种特性就称为模块化。 nodejs是支持模块化的。 ### es6之前js没有模块化的功能 提问:在浏览器中,我们写代码时, ```bash 对于如上的代码结构, 问:如何能让index.js中的getData去使用tool.js中的doSomething()函数?? 答:通过index.html过渡。在index.html中,先引入tool.js,再引入index.js 问:为什么不能直接让index.js来直接使用tool.js的函数,而要通过index.html来统一管理呢? 答:原因很简单:es5中不**支持模块化** ### 不支持模块化有什么问题? ![image-20210910212221146](asset/image-20210910212221146.png) 变量污染,代码无法维护 ## 模块化的发展 ### 历程 - es6之前 ? es5不支持模块化,为了让支持模块化,我们一般会借用第三方库来实现: ? - sea.js. https://www.zhangxinxu.com/sp/seajs/ - es6之后 ? - es6原生语法也支持模块化(并不表示浏览器也**直接**支持模块化 --- 需要单独设置一下) ### 体验 演示性的学习,让大家了解几种模块化的写法 - nodejs的模块化 参考: https://www.zhihu.com/question/20342350 ## 模块化规范 ### 目标 了解模块化规范 ### 概念 概念:拆分模块和组合模块时,**所遵守的规则**,就叫做模块化规范。 例如:在 Node.js 中,导入其它模块时,统一使用 require() 函数。 ![image-20210910214120759](asset/image-20210910214120759.png) ### 常见的模块化规范 - CommonJS 规范:nodejs中遵守的就是commonjs规范。 - ES6 模块化规范:(前后端通用的模块化规范;Node.js、Vue、React 中都能使用!) - CMD 和 AMD 模块化规范(较少使用): CMD--sea.js, ?AMD-require.js ### 学习模块化规范的好处 知道怎么导入并使用别人的模块 知道怎么封装模块给别人使用 ## 用commonJS规范来自定义模块 复习:nodejs的三种模块 - 核心(内置) ### 目标 理解自定义模块的应用场景,掌握在nodejs中定义,导出模块 ### 使用场景 类比于js自定义函数,自定义模块的使用场景是: - 代码需要在项目重用 ### 遵守commonJS规范 在Node.js 中定义模块,要遵守 CommonJS 的模块化规范。CommonJS 规范中主要规定了以下 3 项内容: ①导入其它模块时,统一使用 require() 函数。 ②每个 .js 文件,都是一个独立的模块,模块内的成员都是私有的。 ③在每个 JS 模块中,使用 module.exports 向外共享成员。 ### 示例 ![image-20210910214711244](asset/image-20210910214711244.png) 自定义模块的特点: ①使用 require('自定义模块的路径') 即可导入自定义模块; ②自定义模块内的变量、函数等都是私有的,默认无法被外界访问到; ### 小结 步骤: 1. 定义模块 ## 自定义模块的要点 1. 不要用特殊的文件名 - ?一般会用模块名给它命名。类比于核心模块,例如,你的模块叫myModule,则这个js文件最好叫myModule.js 2. 导入模块的路径是相对路径 4. 记得**导出** - module.exports 是固定写法,一般放在文件的最末尾,也只用一次。 <img src="asset/1575035153257.png" alt="1575035153257" style="zoom:50%;" /> ## 随堂练习 1. 完成自定义模块部分的代码 ```javascript ? const diff = Date.now() - t.getTime() // 相隔多少毫秒 // const str = relativeTime('2021-09-09') //? ## 拓展:导出模块的两种方式(难点,不是重点) 在阅读其它人的代码时,可能会遇到这两种不同的写法。所以我们还是有必要了解一下的。 ### 导出模块有两种方式 [参考](https://nodejs.org/api/modules.html#modules_exports_shortcut) - exports ```javascript // 导出,两种方法任意都可以 // 方法二: // 方法二(变形) ### 两个对象的关系 初始exports和module.exports是指向同一块内存区域,其内容都是一个空对象 exports是module.exports的别名,即: ```javascript 所以下面两种写法的效果是一样的: ?``` ?``` - 在定义模块时: ? 如果直接给exports对象赋值(例如:exports={a:1,b:2}),此时,exports就不会再指向module.exports,而转而指向这个新对象,此时,exports与module.exports不是同一个对象。 ### 在引入某模块时:以该模块代码中`module.exports`指向的内容为准。 ### 图示 ![image-20210324142039663](asset/image-20210324142039663.png) ![image-20210324142213492](asset/image-20210324142213492.png) ![image-20210324142348206](asset/image-20210324142348206.png) ![image-20210324142532461](asset/image-20210324142532461.png) ### 结论 在导出模块过程中,建议只用一种方式(建议直接使用module.exports) ### 练习 [第1 题]() ``` 使用模块。请问,如下代码中会输出什么结果? ``` [第2 题]() ``` 使用模块。请问,如下代码中会输出什么结果? ``` [第3 题]() ``` 使用模块。请问,如下代码中会输出什么结果? ``` [第4 题]() ``` 使用模块。请问,如下代码中会输出什么结果? ``` [第5 题]() ``` 使用模块。请问,如下代码中会输出什么结果? ``` [第6 题]() ``` 使用模块。请问,如下代码中会输出什么结果? ``` ## require的加载机制 require背后的事情 在我们使用一个模块时,我们会使用require命令来加载这个模块。以加载一个自定义模块为例,require(文件名)的效果是: 1. 执行这个文件中的代码 以如下代码为例: ```javascript 在index.js中使用模块 ```javascript //这里的obj对象就是moudule1.js中的module.exports对象 ### require加载规则 如何确定require(文件名) 中,模块的位置! - `require` 优先加载**缓存**中的模块。同一个模块第一次require之后,就会缓存一份,下一次require时就直接从缓存中去取。 - 如果是加载**核心模块**,直接从内存中加载,并缓存 ? - 加载核心模块的格式是 `const xxx = require("模块名")` 。不能写相对路径! - 如果是**相对路径**,则根据路径加载**自定义模块**,并缓存 ? - 以`require('./main')`为例( 省略扩展名的情况) - 如果不是自定义模块,也不是核心模块,则加载**第三方模块**,以`require('XXX')`为例: ? - node 会去本级 node_modules 目录下的xxx文件夹中找,找到就缓存。找的规则如下: ? ? ①查找第三方模块文件夹xxx下的 package.json 文件 ## npm和包和模块 ### npm - `npm` 全称 `Node Package Manager`(node 包管理器),它的诞生是为了解决 Node 中第三方包共享的问题。 当我们谈到npm时,我们在说两个东西:? - 命令行工具。这个工具在安装node时,已经自动安装过了。 ### npm集中管理包 问:在浏览器中是如何使用第三方的工具库,例如:jQuery, bootStrap,echarts.js.... 答:从各自的官网上下载。 问:有没有一个想法:在一个地方下载所有的库(模块.....) 答:通过npm去下载。 **npm网站**上去下载我们的需要的代码时,它们是以"**包**"这种结构放在npm网站上的。先来了解下包和模块的关系。 <img src="asset/模块与包的关系.png" alt="模块与包的关系" style="zoom:50%;" /> - nodejs中一个模块就是一个单独的js文件 ### 小结 npm指两个内容:npm工具,npm网站。 npm网站上放置很多第三模块,它们是以包的格式存在的。 ## npm下载使用包 ### 目标 掌握下载包的格式和步骤 ### 分成三步 - 初始化项目。**npm init** 如果之前已经初始化,则可以省略。 > 保持联网的状态哈 ### 第一步:初始化项目 这里提到的项目并不是某个具体的功能,只是要创建一个空文件夹即可(注意,不要起中文名字哈)。 进入到项目所在的**根目录**下,**启动小黑窗**(按下shift键,点击右键,在弹出的菜单中选择 “在此处打开命令行”) 输入如下命令: ```javascript init命令用来在根目录下生成一个package.json文件,这个文件中记录了我们当前项目的基本信息,它是一切工作的开始。 ### 第二步:安装包 > npm 这个超市上有好的代码,我们想下载来用 ------ ?安装包 生成了package.json文件之后,我们就可以来安装第三方包了。在npm官网中,有上百万个包,供我们使用(你需要在npm网上注册帐号,登陆上去,才可以看到如下的数据,如果只是下载安装包,则并不需要注册)。 <img src="asset/1562724829170-1575039940084.png" alt="1562724829170" style="zoom:50%;" /> 根据我们遇到的实际问题,我们来引入相应的包来解决它们。例如,我们在开发一个项目,其中涉及一些对日期时间的处理可以安装dayjs包。 #### 安装day.js包 day.js是一个专门用来处理日期时间的一个包。网站:https://dayjs.fenxianglu.cn/ ``` ### 第三步:使用包 当我们已经下载好一个包之后,就可以像使用**核心模块**一样去使用它。 格式是:`const 常量名 = require('包名')`? 这个格式与引入核心模块的格式是一样的。 ```javascript ### 小结 npm i 包之前,要有package.json文件。 ## npm init 命令 在某个目录下开启小黑窗,输入如下命令: ``` 它会启动一个交互式的程序,让你填入一些关于本项目的信息,最后生成一个**package.json文件**。 如果你希望直接采用默认信息,可以使用: ```javascript 说明: - 这个命令只需要运行一次,它的目的仅仅是生成一个package.json文件。 ## package.json文件 它一般是由npm init命令创建出来的,它的整体内容是一个json字符串,用来对当前**项目进行整体描述**。其中最外层可以看作是一个js的对象(每一个属性名都加了"",这就是一个典型的json标记)。这个文件中有非常多的内容,我们目前学习如下几个: - name: 表示这个项目的名字。如是它是一个第三方包的话,它就决定了我们在require()时应该要写什么内容。 - version:版本号 - keywords:关键字 - author: 作者 - descrption: 描述 其它可参考 1.http://javascript.ruanyifeng.com/nodejs/packagejson.html 2.http://caibaojian.com/npm/files/package.json.html ## node_modules文件夹 ### 作用 在使用npm install 命令时,会从npm网站下载对应的包到这个文件夹中,这个文件夹中保存着我们从npm中下载来的第三方包。 <img src="asset/node_modules.jpg" style="zoom:50%;" /> ### 执行逻辑 当键入`npm install XXX`之后(这里假设这个XXX包是存在的,也没有出现任何的网络错误): 1. 如果有package.json ? ?(1) 修改package.json文件。根据开发依赖和生产依赖的不同,决定把这句记录在加在devDependencies或者是dependencies列表中。 ? ?(2) 修改node_modules文件夹 ? ?1. 如果有node_modules文件夹,则直接在下面新建名为XXX的文件夹,并从npm中下来这个包。如果这个包还有其它的依赖,则也会下载下来。 2. 如果没有package.json。会给一个警告信息。 说明: - 建议先用init命令创建package.json之后,再去install ## npm镜像-让下包更快 ### 目标 理解镜像的作用,会通过命令来配置镜像 ### 什么是镜像 镜像:副本,拷贝。 默认情况下,从npm官方下载,网速比较慢;我们可以去它的镜像网站上来下载。 ### 如何设置镜像 ```bash ### 图示 ![image-20210911002104752](asset/image-20210911002104752.png) ## 包的分类 ![image-20210910232809786](asset/image-20210910232809786.png) ## 安装全局包和项目包 我们通过`npm install` 命令来安装包,简单说就是把包从npm的官网(或者是指定的镜像源)下载到我们自己的电脑中。那具体这个包下载到哪里了,还是有一点讲究的。 分成两类: - 全局安装: 包被安装到了系统目录(一般在系统盘的node_modules中)。 ? - 命令:`npm install -g 包名` 或者 ?`npm install 包名 -g` ? - 辅助提示: ? ? - ``` - 项目安装(或者叫本地安装),包安装在当前项目的根目录下(与package.json同级)的node_modules中。 ? - ??? ?命令:`npm install 包名` ### 全局包与项目包的区别 - 全局安装的包一般可提供直接执行的命令。我们通过对一些工具类的包采用这种方式安装,如: ? gulp, nodemon, live-server, nrm等。 - 本地安装的包是与具体的项目有关的, 我们需要在开发过程中使用这些具体的功能。 一个经验法则: - 要用到该包的**命令执行任务**的就需要**全局安装**。 ## 全局安装nrm包 ### 目标 理解nrm的功能,会使用它来调整npm镜像 ### 作用 [nrm](https://www.npmjs.com/package/nrm) 这个工具是帮助我们切换npm镜像源的。 之前是: ```bash 使用nrm之后,就可以简化上面的命令。 ### 步骤 共三步 ```javascript // 第二步:列出所有的源信息 // 第三步:根据需要切换源? // 接下来,正常安装你需要的包 > 如果nrm ls不能用,请看这里: ## 开发依赖包和生产依赖包(了解) 在本地安装包时,表示我们这个项目要用到这个包,换句话说,我们这个项目要想成功运行,要依赖于这些个包。 但在,具体在项目进行的哪一阶段依赖于这些包呢?也有具体的差异。 ### 理解 举个生活中建房子的场景: 在建房子时,我们依赖: - 辅助工具:尺子,水平仪,脚手架 在住房子时,我们依赖: - 原材料:钢筋,水泥 在房子进入到了使用阶段时,我们就不再需要尺子,水平仪,脚手架等这些个辅助工具了。我们买一所房子时,也不应该支付巨型脚手架的费用。 ?在开发前端项目的过程中也存在类似的问题:我们的开发过程和使用过程是分开的,开发项目时需要用到的包可能在使用项目时就不需要用到了。 假设有这么两个包: - gulp-htmlmin。这个工具是用来把html代码进行压缩的(去掉空格,换行等),我们需要在开发时使用它,而项目一旦上线,我们就不再需要它了。,因此将它归类为"**开发依赖**"。 ![1562728491126](asset/1562728491126.png) > 这个差异就表现在,我们在打包项目时,就不需要打包“开发依赖”的包,这样减少成本。 ### 操作 这两种依赖关系,在具体操作的过程中,有如下区别 1. 保存到开发依赖(devDependencies) ```javascript 通过这种方式安装的包出会现在package.json文件中的`devDependencies`字段中。 2. 保存到生产依赖(dependencies):? ```javascript ``` ### 技巧 - 加了-D : ?开发依赖,这就表示这个工具包只在开发项目时候要用,项目开发完成就不需要 什么包加上-D,什么包不要加?------- 看文档 ## 案例:npm包从创建到发布 <img src="asset/image-20200213171733854.png" alt="image-20200213171733854" ?/> > 背景 ### npm项目初始化 在本地磁盘上创建一个空项目,取文件夹名为`myNpm`。注意请先去npm网官去确定一下,这个项目名是否已经被占用了。(如果这个名字已经被占用了,则你是无法向npm上上传的)。 检查方式 ```bash > 很确定地告诉你,myNpm这个包已经被别人占用了,你需要去自己用另一个名字哈。
命令来创建一个package.json文件,对你项目myNpm信息进行设置。 ### 完成功能开发 ![image-20210324175557637](asset/image-20210324175557637.png) 正常开发,完成你的代码。在默认情况下,index.js是这个项目的入口文件。 下面是一个最简单的示例:? ``` ? const diff = Date.now() - t.getTime() // 相隔多少毫秒 const formatDate = (dateTime) => { // 通过module.exports来导出模块 ### 切换当前npm镜像源到官网 由于我们需要把包上传到npm上,所以要先确保当前的npm源是npmjs.org。与之相关的命令有如下两条。 (1)查看当前的npm的registry配置. ```bash # 如果不是,可以通过如下命令来设置 (2)或者使用nrm工具来设置: ![image-20210324175741385](asset/image-20210324175741385.png) ### 连接npm ``` 这个命令需要输入三个信息以供连接上npmjs: - 用户名 > ?如果你已经不是第一次连接了,这一步是可以省略的。 ![image-20200212230007960](asset/image-20200212230007960.png) 你也可以通过如下命令检查自己是否连接成功了。 ```bash 如果成功了,则可以进行最后一步了:publish? 如果想退出: ```bash ### ?把包上传到npm ``` 如果成功: ```bash 出错的可能是: - 这个包名被别人先用了。 ```.npmignore 如果没有报错,则表示一切ok,你可以用你的帐号密码登陆npm,去查看你名下的package是否有了myNpm ### 下载使用 通过`npm install 包名`即可来安装包。 然后,告诉你的小伙伴们去下载使用吧。 ### 删除包 ```cpp 如果你的包没有什么用处,建议删除掉,以节约公共资源。 ### 更新包 1. 修改代码,保存。 ## 总结:npm包的问题 ### 为什么要把自己的代码上传到npm上? - 优秀的代码供所有人复用 ### 优秀的代码从哪里来? - 自己写的,同事写的,总结别人.... ### 把代码上传到npm上去,有格式要求吗? 有,必须要是**包**的格式 ### 包是什么格式? 格式: - 一定要有 ? package.json这个文件。 它就是用来对包进行整体说明。(name, ?version, description, author, dependencies, ......). `npm init --yes` - 有自己的代码文件。这个代码文件要在package.json中的main中声明。 ? <img src="asset/image-20210325084219839.png" alt="image-20210325084219839" style="zoom:33%;" /> ### 在上传到npm之前,我们需要切换镜像吗? 需要,我们必须要把代码上传到npm的官网。虽然我们上传是传到npm官网,但是,它会自动同步(例如:每隔15分钟就会通过其它镜像最新的包的信息)给其它的镜像 --- taobao, cnpm.....? ### 在上传时,需要登陆吗? 需要,在命令行中登陆。 `npm adduser` ?这一个操作只需要做一次 ### 在上传时,对包名有约定吗? 有。 1. 不能与现有包重名;2. 包名只能是小写字母+数字+中划线 ### 上传的命令是什么? 是 `npm publish ` ### 上传出错的可能性有? 1. 你的帐号还没有通过验证 (在你登记的邮箱里,会收到一封邮件,要去点击确认)。 qq邮箱好像不支持在手机中操作, 建议在pc中浏览器里进行操作。 ### 如何对包进行版本更新? 1. 更新代码,准备重新发布 3. npm publish ### 如何去下载包 命令:`npm i 包名`? 1. 在另一个项目中去下载包 2. 为了提升下载速度,我们会切换镜像到taobao。 ## 作业1 全局安装i5ting_toc 包 i5ting_toc 是一个可以把 md 文档转为 html 页面的小工具。 官方文档地址为:https://www.npmjs.com/package/i5ting_toc 。 ## 作业2 全局安装nodemon包 ### 作用 **它能帮我们自动检测到我们的代码的修改,并自动重新运行我们的代码** 我们每次修改了代码,要想代码生效都需要运行。 这有点麻烦哈。 有没有一个工具会自动检测到我们的修改并自动重新运行我们的代码呢?有,它叫nodemon。[地址](https://www.npmjs.com/package/nodemon) ### 安装 步骤: 在任意位置 打开一个小黑窗,输入如下命令 ```bash 回车。 此操作`需要联网`,根据网络速度所耗时间不同。如果这个命令执行完成并没有报错,就是说明安装成功了。 对上面的命令说明如下: - npm是一个工具,用来管理node代码中要使用的第三方模块。它是随着node的安装而自动安装的:如果你安装node,则npm也已经安装过了,你可以直接使用。 - -g 表示全局安装。它也可以写在nodemon后面。即`npm install nodemon -g`。 ?? ### 使用nodemon 等待安装成功之后,使用方法也非常简单:在命令中,`使用nodemon来代替node`。 例如,原来是: ```bash 现在是: ``` 它的好处在于会自动监听server.js这个文件的变化,如果变化了,就会重新自动再去运行。相当于是: ```bash 说明: - 它是一个第三方的包(其它程序员写的工具) - 之前的node server.js还是可以用的。 ?? ## 附:npm 常用命令 - 查看 ? ```bash - 升级 npm ? ```bash - 初始化 `package.json` ? ```bash - 安装第三方包 ? ```javascript - 删除已安装的包? ? ```bash - 设置npm的register ? 如果你不想用 `nrm` ,下面这个原生的命令也可以切换镜像源(从哪里下载包)。 ? ```bash [参考](https://www.npmjs.cn/getting-started/what-is-npm/ ) |
|
JavaScript知识库 最新文章 |
ES6的相关知识点 |
react 函数式组件 & react其他一些总结 |
Vue基础超详细 |
前端JS也可以连点成线(Vue中运用 AntVG6) |
Vue事件处理的基本使用 |
Vue后台项目的记录 (一) |
前后端分离vue跨域,devServer配置proxy代理 |
TypeScript |
初识vuex |
vue项目安装包指令收集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 22:59:12- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |