paint-brush
创建第一个 NPM 包的最简单方法经过@gmakarov
3,300 讀數
3,300 讀數

创建第一个 NPM 包的最简单方法

经过 German Makarov9m2023/12/15
Read on Terminal Reader

太長; 讀書

让我们来谈谈微捆绑。我发现它对于简单的库特别有效,因为您不必担心配置,可以让您专注于开发包。 以下是其功能的简短列表: 内置配置;您所要做的就是在 package.json 中添加一个“exports”字段 开箱即用的 TypeScript 支持,无需 tsconfig.json 多种输出格式(CJS、UMD 和 ESM) 内置 Terser 压缩
featured image - 创建第一个 NPM 包的最简单方法
German Makarov HackerNoon profile picture
0-item

本指南将引导您使用microbundle从开始到结束构建和发布 NPM 包的最简单过程。


让我们来谈谈microbundle 。我发现它对于简单的库特别有效,因为您不必担心配置,使您可以专注于开发包。


以下是其功能的简短列表:


  • 内置配置;您所要做的就是在package.json中添加一个“exports”字段
  • 开箱即用的 TypeScript 支持,无需tsconfig.json
  • 多种输出格式(CJS、UMD 和 ESM)
  • 内置 Terser 压缩


基本上, microbundle是构建在rollup.js之上的。如果您要构建的库比我在本文中提到的更复杂,您可以考虑使用纯rollup.js配置。

初始化你的包

作为示例,让我们创建一个简单的库来对两个数字求和,该库将仅导出一个函数sum


  1. 为项目创建一个文件夹,并使用默认值运行npm init生成package.json


  2. src文件夹中创建index.ts

     // src/index.ts export function sum(a: number, b: number) { return a + b; }
  3. 安装microbundle

    npm i -D microbundle


  4. 使用以下值更新package.json

     // package.json ... "type": "module", "source": "src/index.ts", // your source code "exports": { "types": "./dist/index.d.ts", // TypeScript declaration file "require": "./dist/index.cjs", // CommonJS entry point "default": "./dist/index.esm.js" // ES Module entry point }, "main": "./dist/index.cjs", // where to generate the CommonJS bundle "module": "./dist/index.esm.js", // where to generate the ESM bundle "unpkg": "./dist/index.umd.js", // where to generate the UMD bundle "types": "./dist/index.d.ts", // TypeScript declaration file for the package "scripts": { "build": "microbundle", // compiles "source" to "main", "module", "unpkg" "dev": "microbundle watch" // re-build when source files change } ...
  5. 运行构建脚本

    npm run build


    输出应准确包含我们在package.json中声明的文件

    输出

瞧,我们制作了第一个包。让我们看一下更复杂的场景。

将 React 添加到您的库中

如果你想将 React 添加到你的库中,你仍然可以使用它microbundle ,但是现在,你的构建命令应该如下所示:

 microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react --globals react/jsx-runtime=jsx


将命令添加到package.jsonbuild脚本中以方便将来:

 // package.json ... "scripts": { "build": "microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react --globals react/jsx-runtime=jsx" } ...

使用 Storybook 作为 UI 组件

在构建 UI 库时,您可能需要一个沙箱,您可以在其中开发、可视化组件并为文档提供演示组件。


故事书来了。它是一个沙箱,拥有自己方便的界面和捆绑器,您可以在其中轻松描述组件的各种状态。组件状态的每次捕获都称为“故事”。


这张图片取自他们的文档,显示了它的样子:

故事书

安装 Storybook 非常简单;只需在库中运行命令:

 npx storybook@latest init


此命令将安装 Storybook 所需的所有依赖项,添加要运行的脚本,并将 Storybook 构建到package.json中,使用默认配置创建文件夹.storybook ,并将一些故事示例添加到文件夹src/stories中。

将样式集成到您的库中

您可以通过以下两种方式之一添加样式:CSS 文件或 CSS-in-JS。 CSS 文件允许轻松自定义,但需要单独包含,而 CSS-in-JS 简化了样式,但增加了包大小。


  • CSS文件

    在src目录下创建一个CSS文件,并将其导入到根react组件文件中:

     // src/index.tsx import './styles.css'; export const MySuperComponent = () => { return ( <h1 className="title">Hi there!</h1> ) };


    那么,让我们再次运行构建命令。

     npm run build


    您导入的styles.css文件将在dist文件夹中创建:

    已创建文件

    伟大的!我们已经获得了具有必要样式的 CSS 文件。然而,这个解决方案有一点不便。包安装后需要单独添加CSS文件。


    因此,您的库的用户将需要使用 CSS 加载器(例如,webpack 的 CSS 加载器)来处理您的 CSS 文件,其用法如下所示:

     import { MySuperComponent } from 'my-super-library'; import 'my-super-library/dist/styles.css'; export const App = () => { return ( <MySuperComponent /> ); }


  • JS 中的 CSS

    您可以使用样式组件等库来实现此目的。它看起来像这样:

     import styled from 'styled-components'; const Title = styled.h1` font-size: 30px; font-weight: bold; `; export const MySuperComponent = () => { return ( <Title>Hi there!</Title> ) };

    使用此解决方案,用户无需导入 CSS 文件并为其项目添加特殊的加载器。安装库后,该组件将具有自己的样式。然而,这会增加包的大小,并使用户更难以使用 CSS 选择器自定义元素。


选择最适合您的选项。我更喜欢使用 CSS 文件,因为它允许用户使用 CSS 选择器自定义任何元素,不会影响包大小,并且工作速度更快。

开发详细的README.md文件

README.md文件提供有关您的库、如何安装它、它的基本用法以及它所具有的功能的信息。这通常是开发人员在遇到您的存储库或 NPM 包时阅读的第一个文件,因此它应该简洁且内容丰富。


我喜欢按以下顺序创建结构:

  1. 标题
  2. 超短封装说明
  3. 精美的统计徽章 ( shields.io )
  4. 如果您的库是 UI 组件,请包含屏幕截图或在 CodeSandbox 上提供演示链接
  5. 功能列表
  6. 安装指南
  7. 代码片段及用法
  8. 您的库接受配置的选项和道具


您可以参考我的包中的README.md文件示例,例如dot-path-valuereact-nested-dropdown ,以获取灵感。

导航依赖管理

这是一个重要的部分,因为如果你做错了,用户可能会面临版本冲突或其他问题,他们将不得不删除你的库。那么,让我们看一下依赖类型之间的主要区别。


  • “devDependency”仅用于开发,不会包含在您的捆绑包中。例如,如果您安装了microbundle软件包,而用户不需要使用该软件包,则将其保留在 devDependency 中,并且它不会出现在捆绑包中。


  • “依赖项”将与包一起安装。包含您的包在用户项目中运行所需的依赖项。请注意,某些依赖项(例如“react”)可能已安装在用户的项目中。包中存在重复的“react”可能会增加包的大小。这就是“peerDependency”派上用场的地方。


  • “peerDependency”是您的包使用但不会包含在您的包中的依赖项。您的包将利用用户在其项目中拥有的依赖项的版本。


    基本上,如果我们为其生态系统创建一个库,我们应该指定对等依赖关系。例如,如果您正在创建 React 组件,请将 React 设置为对等依赖项。如果开发带有日历的React组件,请添加React和日期计算库(例如date-fns)作为peerDependency。


    如果用户的项目中没有指定的对等依赖项, npm install命令将显示警告,但不会自动安装依赖项。


举一个小例子来说明它的外观:

 // package.json ... "dependencies": { // libraries which will be installed along with your library "clsx": "^1.2.1" // just library for className combining }, "peerDependencies": { // user should have these packages installed "react": "^16.8.0 || ^17.0.0 || ^18.0.0" // user should have react 16.8+ version }, "devDependencies": { // won't be in user's bundle, these libraries just for your developing needs "@types/react": "^18.2.33", "react": "^18.2.0", // in case if we are using storybook, we need actual react library to render our components there "microbundle": "^0.15.1", }, ...

将 GitHub 用于您的包

如果您要发布 NPM 包,则意味着它将可以公开访问(如果您有免费帐户)。要收集用户的反馈,您可以为原始代码创建 GitHub 存储库。人们可以在那里提出问题并与您就您的包裹进行沟通。您还可以描述您的发布并获得一些星星!


您当然可以跳过这一步,但它是开发人员文化不可或缺的一部分,并且可以为开源做出宝贵的贡献。

发布和维护包

在发布包之前,必须确保package.json文件配置正确。以下是需要遵循的一些重要步骤:


  1. 命名并尝试描述您的库的核心功能。例如:

     "name": "react-color-picker"


  2. 添加 GitHub 存储库信息(如果存在):

     ... "homepage": "https://github.com/{your_repository}", "repository": { "type": "git", "url": "https://github.com/{your_repository}" }, "bugs": { "url": "https://github.com/{your_repository}/issues" }, ...


  3. 配置files

     ... "files": [ "dist", ], ...

    安装库时,您应该指定将包含在node_modules中的文件。通常,包含dist文件夹就足够了。


  4. 添加keywords

    关键字是描述您的包的字符串数组,NPM 使用它们进行搜索和推荐。选择您预计人们在搜索时会使用的与您的包裹相关的词语。让我们为sum库创建关键字:

     ... "keywords": ["typescript", "math", "sum", "numbers", "arithmetic", "calculator", "calculation"] ...

    指定您的技术非常重要,因为用户经常搜索“数学打字稿库”或“反应日历选择器”等术语。


  5. 如果还没有,请创建一个NPM帐户,然后在终端中运行npm login ;按照提示验证您的帐户。默认情况下,你的包的版本是1.0.0 ;您可以在package.json文件中检查它。我建议将其更改为0.0.1


  6. 运行npm publish ,就完成了!以后若要更新版本,请使用命令npm version patch来增加版本,然后使用npm publish发布更新的包。

结论

正如您所看到的,创建您自己的库非常容易!本质上,这就是创建和维护包所需的全部内容。如果您难以使用microbundle限制您的库,我建议使用具有更具体配置的rollup.js


对于所有技能水平的开发人员来说,创建 NPM 包并为开源做出贡献都是一种有益且宝贵的经验。它允许您与社区分享您的代码,获得大量经验,并构建您的工作组合。