我们已经对 npm 的工作原理以及如何使用它来安装包和运行命令有了很好的概述。现在让我们更进一步,看看下载和安装现有 npm 项目的样子,而不是从头开始创建一个项目。很可能,这将是你大部分时间都在做的事情。它比一个一个安装和配置所有单独的部分要容易得多。
这就是我们在本指南关于 npm 的最后一章中要介绍的内容,我将借鉴我在一个现实项目中的个人经验。
指南章节
- 这本指南适合谁?
- “npm”到底是什么意思?
- 命令行到底是什么?
- Node 到底是什么?
- 包管理器到底是什么?
- 如何安装 npm?
- 如何安装 npm 包?
- npm 命令到底是什么?
- 如何安装现有的 npm 项目? (您现在就在这里!)
这是一个现实的 npm 项目
我为这个项目选择的是我自己编写的 SvelteKit 静态博客入门。我认为它是一个很好的例子,因为它附带了许多预安装的包,非常适合演示目的。
这是我自己的一个真实项目,旨在为您(正如您从名字中可以猜到的那样)提供构建静态生成的博客网站的起点。(“静态生成”意味着我们的代码将被编译成 .html
文件,可以部署到网络上的任何地方。这是 “Jamstack” 构建网站方式中包含的几种方法之一。)
如果您不了解 SvelteKit,不用担心——这只是为了演示,我们不会编写任何您已经不知道的东西。也就是说,值得注意的是,SvelteKit 在幕后使用 Vite,它实际上是一个 npm 包,它使我们能够访问现代构建工具和超高速的开发服务器。
克隆项目
首先,我们需要“克隆”项目,这是一个花哨的词,指的是将项目复制到我们的系统中,以便我们可以在本地对其进行操作。有两种方法可以克隆现有项目。
如果您更喜欢使用浏览器中的可视化方式,请访问 GitHub 上的入门仓库,点击位于 GitHub UI 中的“代码”下拉菜单,然后选择“下载 ZIP”选项。
或者,如果您更喜欢使用命令行,请运行以下命令(只需确保您位于计算机上不介意添加新项目文件夹的位置,例如 cd /path/to/folder
)
npx degit https://github.com/josh-collinsworth/sveltekit-blog-starter.git sveltekit-blog-starter
您可能还记得 npx
允许我们运行 npm 包,而无需永久安装它们。degit
像 git clone
一样克隆项目,但没有其 Git 历史记录(实际上是“de-git”)。
无论您使用哪种方法,您都会获得一个全新的 sveltekit-blog-starter
文件夹。让我们在代码编辑器中打开它,打开终端,并运行 npm install
(或 npm i
)命令。
此时,您会看到有关漏洞的说明,就像我们在本指南的上一节中介绍的那样。它可能会显示类似于“发现 0 个漏洞”(如上图所示),但这个数字很可能大于 0。如果您确实看到了漏洞,请不要担心。您可以暂时忽略它,因为这不是我们打算用于生产环境的项目,其他人无法看到或使用它。(有关更多信息,请参阅上一章中关于 npm audit
的部分。)
启动服务器并进行更改
如果您要查看克隆项目中的 package.json
文件,您会看到启动开发服务器的命令
npm run dev
在终端中运行该命令,您应该会立即看到以下内容
在 VS Code 中,您可以按住 CMD 键,然后点击 http://localhost:3000
URL,也可以在浏览器中手动输入它。无论哪种方式,该网站都应该显示在浏览器中!
让我们花点时间欣赏一下这有多快和简单!没错,我们可能需要先安装一堆脚手架,但这只是一次性的前期成本。我们只需使用几个命令就可以在我们的机器上运行整个项目,并且我们可以在任何时候安装另一个现有项目!
我不会深入探讨这个特定项目的细节,因为它与学习 npm 无关,但它是一个很好的例子,因为它预配置了许多很酷的功能,我们可以轻松地进行更改,并在浏览器中立即看到更新。接下来,让我们看看其中的一些命令。
SvelteKit 需要 Node 14 或更高版本。如果您在本指南中安装了 npm,那么这对您来说不成问题。但是,如果您在开始之前已经安装了它,并且在尝试运行此项目时遇到了错误,那么值得快速运行 node -v
以确保。如果您需要升级,nvm 是您的朋友。
在保存时自动编译 Sass
您可以在 src/lib/assets/scss/
文件夹中找到项目的 Sass 文件。尝试直接打开 global.scss
文件。进行更改,保存它,您应该会看到更新自动(并且几乎立即)显示在浏览器中。
进行内容更改
入门网站实际上使用仓库的 README.md
文件作为其主页。如果您打开 README.md
并开始进行更改(即使您不了解 Markdown,任何编辑都可以),您应该还会看到这些更改在您保存后立即显示出来,就像 Sass 在上一步中所做的那样
如果您愿意,您可以打开另一个页面,比如 src/routes/contact.svelte
文件,并更新 HTML 以查看它在保存后立即在浏览器中实时刷新。
您甚至可以复制 src/lib/posts/
中的 Markdown 文件之一,并进行编辑以查看它是否会自动显示在 /blog
页面上的文章列表中,如果您想进行到这一步。(只需确保为它指定一个唯一的标题。)
理解导入
关于 npm 项目有一件很重要的事情,我们在第四章中简要提到过,但还没有介绍:导入。如果没有触及这一点,本指南就不完整。基本思想是,我们可以——顾名思义——在代码中导入一个包,并立即使用它。
如何做到这一点?打开项目根目录下的 svelte.config.js
文件夹,您会看到顶部有一块 import
行,类似于这样
import adapter from '@sveltejs/adapter-static'
import { mdsvex } from 'mdsvex'
import preprocess from 'svelte-preprocess'
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
import rehypeSlug from 'rehype-slug'
每个 import
都是一个在此文件中使用的已安装包。每个包的实际功能现在并不重要;我只想提请大家注意 import
语法。这就是我们在实际代码文件中使用包的方式;我们告诉 JavaScript 导入什么以及从哪里导入。然后我们可以在代码中调用它。
这种语法称为“ES6 导入”,重要的是(明白了吗?!)要了解它是浏览器基于 JavaScript 和 Node JavaScript 都同意在未来使用的标准。
以前,Node JavaScript 使用(并且通常仍然使用)一种略有不同的语法,称为 CommonJS。如果您看到类似于这样的导入,那就是旧的 CommonJS 样式
const myPackage = require('package-name')
关于 ES6 样式的 import
需要了解的另一个关键点是:语法是特定于 npm 的,而不是语言标准。
说清楚:您可以在普通 JavaScript 中使用 import
。export
变量、函数、对象等,并将其import
以便在另一个文件中使用,这是语言的一种非常普通的功能。但是,要做到这一点,您需要提供一个相对路径,或者(在更现代的浏览器中)提供一个指向您要导入内容的 URL。仅仅使用一个包含包的 slug 的字符串(如我们这里看到的)是不合法的。
那么,为什么它在技术上不算是有效的代码,却仍然被使用呢?因为处理这种导入方式是 npm 为我们提供的便利功能之一。当我们告诉 npm 以字符串形式 `import somePackage from 'name'` 进行导入,且没有指定路径时,npm 会自动地在项目中已安装的包中查找我们需要的导入内容。这省去了我们输入繁琐的相对路径的麻烦,也让我们无需了解这些包在 `node_modules` 中错综复杂的目录结构。
这可能不言而喻,但由于这种语法并非有效代码,因此,除非你的 npm 项目包含某种打包器或编译器来处理导入和模块,并将它们转化为有效的浏览器代码,否则你将无法成功使用它。
构建最终网站
大多数类似的 npm 项目有两个主要目的:
- 帮助你开发网站或应用程序。
- 构建最终的生产版本。
SvelteKit 也不例外。当我们完成 (很棒的) 开发服务器设置并对更改感到满意后,我们可以运行以下命令:
npm run build
如果你的开发服务器仍在运行,你可以使用 Ctrl+C 停止它,或者打开一个新的终端选项卡。你无法在与开发进程运行相同的终端窗口中输入任何命令,因为它是一个活动的、持续的任务。
当我们运行 `build` 命令时,SvelteKit 会处理项目中的所有文件,并输出一个完全打包的、可部署的静态 HTML、CSS 和 JavaScript 文件集合,并且速度相当快。你可以将此文件集合上传到任何可以托管网站的地方。 **现代工具;传统的输出。**
构建命令完成后,你应该会在项目文件夹的根目录(即顶层)中看到一个新的 `build` 文件夹。如果你浏览它,你会注意到不再有 `.md`、`.svelte` 或任何其他无法被浏览器读取的文件。所有内容都已编译成纯 HTML、CSS 和 JavaScript,更不用说——如果你打开一个 JavaScript 或 CSS 文件——它们会被彻底压缩,以使文件大小尽可能地 **小**,以便在浏览器中以尽可能快的速度 **加载**。
如果你想查看编译后的站点在浏览器中的加载情况,可以在构建完成后运行 `npm run preview`。不同之处在于,内容将从最终的 `build` 文件夹中加载,而不是使用 `dev` 命令时使用预编译文件动态构建。除非你在 DevTools 中打开网络选项卡(或尝试更新某些内容),否则你 **不会看到** 任何区别,但你将看到最终的产品。
这是一个可选步骤,但我认为了解我们最终得到的编译文件数量(考虑到我们放入项目中的所有各种文件)以及最终捆绑包的大小(感谢此项目内置的惊人的构建工具)非常酷。(记录一下,这一切都是由 SvelteKit 和 Vite 完成的。)
现代部署实践
这是一个以后再讨论的话题,但现代部署通常不需要你运行 `build` 命令并自己上传文件(尽管这仍然是一种选择)。相反,一个主机(如 Netlify 或 Vercel **)** 会直接连接到项目的 GitHub 仓库,并且每当你将更改推送到仓库的主分支时,主机都会为你运行构建命令,并自动部署编译后的文件!
这是这个新时代的前端开发的众多非常好的功能之一。无需使用 FTP 或手动将文件拖放到任何地方;我们可以确信,每当我们推送代码时,所有内容都会自动构建和部署,无需我们做任何事情!
结束本 npm 指南
如果你读到这里,恭喜你!还有谢谢。恭喜你,因为这是一篇很长很长的文章。谢谢,因为……好吧,这是一篇很长很长的文章。
但你坚持读完了,希望你也学到了一些重要的东西。我在开头就说过,我的目标不是简洁,而是有效性。这意味着我们涵盖了很多内容。我们从对 npm 的简要概述 以及它在现代前端开发领域中的位置开始,然后 熟悉命令行。从那里,我们分解了术语 “Node” 和 “包管理器”,以便对 npm 是什么以及它做什么有一个准确的理解。一旦我们了解了包管理器在开发中所扮演的角色,我们就直接深入 npm,包括 如何安装它、如何将包添加到项目中、如何设置命令,以及最后如何进入一个使用 npm 的现有项目。
我希望我们在本 npm 指南中涵盖的所有内容至少能为你打开一扇门,让你可以进一步探索 npm 并在你准备好时提升技能。我经常需要重复某件事很多次,并尝试多种方法才能真正理解。所以,如果你现在仍然感到和之前一样困惑,那就花更多时间在这上面。反思你知道的和你学到的,然后回来——或者在你准备好时尝试一种新方法!
这篇长文非常值得一读!谢谢,Josh!
谢谢!——我通读了所有内容,并学到了很多原本应该早就知道的好东西 ;-)。你的详细程度以及你的偏离都恰到好处!
H.M.
这篇长文值得一读。感谢!
非常感谢你,Josh。这是我迄今为止读过的关于 npm 入门的最佳文章。这确实解答了我多年来的许多疑问。我肯定会与我的联系人和团队成员分享它。
写得很好!而且结构也很好。我感觉每个主题都建立在之前的主题上,非常自信,所以很容易理解。谢谢,Josh!
非常棒的指南,我很高兴我花时间阅读了它,感谢你的努力。
这非常有用,而且写得很好!
谢谢!我感觉我已经知道了这些内容的大部分,但重新回顾仍然很有价值。写得很好,直击要点。这是一个非常棒的资源,我将来一定会与其他人分享。
很棒的系列,我将与我的团队分享。我们都使用 `npm`,但了解一些幕后内容总是一件好事。
感谢你整理这些内容。这对于 Node 和 NPM 来说是一个很棒的入门,值得花时间阅读并尝试示例。
谢谢,Josh!你的写作风格非常独特,尤其是在“技术”指南和讲座的世界中,我读这段旅程读得很愉快。
自从我 14 年前最后一次接触开发以来,我一直努力理解所有新的网页设计工具。这篇文章非常有用。谢谢。
读完之后,我对 npm 工具和环境有了更好的了解,非常感谢您的辛勤工作和帮助我们。谢谢!
非常感谢您发布这篇文章。我之前尝试过其他教程,但它们没有解释任何东西,只是一系列看似随机的命令。这篇文章太棒了!
毫无疑问,这是我见过的关于 npm 的最佳入门教程。解释得非常清楚,我长期以来在这个主题上的一些问题都得到了解答。突然间一切都变得清晰多了!
感谢您的这篇文章,Josh,我非常感谢它。现在我对 npm 有了一些基本了解,我将尝试更深入地探索它。