节点帮助

复制 npm(对开发者的运作方式)

发布 2024年九月29日
分享:

复制'NPM 包是一个功能强大的客户端工具,用于将机器学习模型集成到 React 应用程序中。 它允许开发人员轻松使用预训练模型,并直接在其应用程序中运行推理,而无需管理复杂的后端基础设施。 以下是您如何使用的概述复制NPM包在您的 React 项目中。 另外,我们将研究IronPDF一个用于生成 PDF 的库,将 PDF 生成和两个库结合创建一个可运行的应用程序。

Replicate 入门

复制是一个在线平台,通过简单的API提供对机器学习模型的访问。 它托管来自各个领域的模型,例如图像生成、文本分析等。 通过使用“replicate” NPM 包,开发人员可以将这些模型无缝集成到他们的应用程序中。

入门

安装

要在您的 React 应用程序中使用 `replicate`,首先需要安装. 您可以使用npm或yarn来完成:

npm install replicate
npm install replicate
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'npm install replicate
VB   C#

yarn add replicate
yarn add replicate
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'yarn add replicate
VB   C#

API密钥

您需要一个API密钥才能与Replicate API互动。 您可以通过在以下网站注册来获取此密钥:复制网站创建新的 API 令牌。

基本用法

以下是如何在 React 应用程序中使用 **replicate** 包的分步指南。

1. 导入包并初始化客户端

import Replicate from 'replicate';
const output = new Replicate({
  auth: 'YOUR_API_TOKEN'    
});
import Replicate from 'replicate';
const output = new Replicate({
  auth: 'YOUR_API_TOKEN'    
});
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'import Replicate from 'replicate'; const output = New Replicate({ auth: 'YOUR_API_TOKEN' });
VB   C#

2. 运行推理

假设您想使用模型从文本生成图像,只需几行代码即可获得如下结果:

const result = await replicate.run("stability-ai/stable-diffusion", {
  input: {
    prompt: "a futuristic cityscape"
  }
}); // identifier and prediction parameters
console.log(result);
const result = await replicate.run("stability-ai/stable-diffusion", {
  input: {
    prompt: "a futuristic cityscape"
  }
}); // identifier and prediction parameters
console.log(result);
const result = Await replicate.run("stability-ai/stable-diffusion", {
	input:= { prompt:= "a futuristic cityscape" }
}) ' identifier and prediction parameters
console.log(result)
VB   C#

示例应用程序

让我们创建一个简单的 React 应用程序,让用户根据文本提示生成图像,以演示节点复制的用法。

1. 设置新的 React 项目:

npx create-react-app replicate-example
cd replicate-example
npm install replicate
npx create-react-app replicate-example
cd replicate-example
npm install replicate
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'npx create-react-app replicate-example cd replicate-example npm install replicate
VB   C#

2. 创建图像生成组件:

import React, { useState } from 'react';
import Replicate from 'replicate';
const replicate = new Replicate({
  auth: 'YOUR_API_TOKEN'
});
const ImageGenerator = () => {
  const [prompt, setPrompt] = useState('');
  const [image, setImage] = useState(null);
  const generateImage = async () => {
    const result = await replicate.run("stability-ai/stable-diffusion", {
      input: { prompt }
    });
    setImage(result.output[0]);
  };
  return (
    <div>
      <h1>Image Generator</h1>
      <input
        type="text"
        value={prompt}
        onChange={(e) => setPrompt(e.target.value)} // const input
        placeholder="Enter a prompt"
      />
      <button onClick={generateImage}>Generate Image</button>
      {image && <img src={image} alt="Generated" />}// prediction object
    </div>
  );
};
export default ImageGenerator;
import React, { useState } from 'react';
import Replicate from 'replicate';
const replicate = new Replicate({
  auth: 'YOUR_API_TOKEN'
});
const ImageGenerator = () => {
  const [prompt, setPrompt] = useState('');
  const [image, setImage] = useState(null);
  const generateImage = async () => {
    const result = await replicate.run("stability-ai/stable-diffusion", {
      input: { prompt }
    });
    setImage(result.output[0]);
  };
  return (
    <div>
      <h1>Image Generator</h1>
      <input
        type="text"
        value={prompt}
        onChange={(e) => setPrompt(e.target.value)} // const input
        placeholder="Enter a prompt"
      />
      <button onClick={generateImage}>Generate Image</button>
      {image && <img src={image} alt="Generated" />}// prediction object
    </div>
  );
};
export default ImageGenerator;
'INSTANT VB TODO TASK: The following line could not be converted:
import React,
If True Then
	useState
End If
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'from 'react'; import Replicate from 'replicate'; const replicate = New Replicate({ auth: 'YOUR_API_TOKEN' }); const ImageGenerator = () => { const [prompt, setPrompt] = useState(''); const [image, setImage] = useState(Nothing); const generateImage = async() => { const result = await replicate.run("stability-ai/stable-diffusion", { input: { prompt } }); setImage(result.output[0]); }; Return(<div> <h1> Image Generator</h1> <input type="text" value={prompt} onChange={(e) => setPrompt(e.target.value)} placeholder="Enter a prompt" /> <button onClick={generateImage}> Generate Image</button> {image && <img src={image} alt="Generated" />} </div>); }; export default ImageGenerator;
VB   C#

3. 在您的应用程序中使用该组件:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import ImageGenerator from './ImageGenerator';
ReactDOM.render(
  <React.StrictMode>
    <App />
    <ImageGenerator />
  </React.StrictMode>,
  document.getElementById('root')
);
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import ImageGenerator from './ImageGenerator';
ReactDOM.render(
  <React.StrictMode>
    <App />
    <ImageGenerator />
  </React.StrictMode>,
  document.getElementById('root')
);
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import ImageGenerator from './ImageGenerator'; ReactDOM.render(<React.StrictMode> <App /> <ImageGenerator /> </React.StrictMode>, document.getElementById('root'));
VB   C#

处理错误

在使用 API 时,妥善处理错误是至关重要的。 您可以修改“generateImage”函数来捕获并显示错误:

const generateImage = async () => {
  try {
    const result = await replicate.run("stability-ai/stable-diffusion", {
      input: { prompt }
    });
    setImage(result.output[0]);
  } catch (error) {
    console.error("Error generating image:", error);
    alert("Failed to generate image. Please try again.");
  }
};
const generateImage = async () => {
  try {
    const result = await replicate.run("stability-ai/stable-diffusion", {
      input: { prompt }
    });
    setImage(result.output[0]);
  } catch (error) {
    console.error("Error generating image:", error);
    alert("Failed to generate image. Please try again.");
  }
};
const generateImage = Async Sub()
  Try
	const result = Await replicate.run("stability-ai/stable-diffusion", {
		input:= { prompt }
	})
	setImage(result.output(0))
  Catch e1 As [error]
	console.error("Error generating image:", [error])
	alert("Failed to generate image. Please try again.")
  End Try
End Sub
VB   C#

介绍IronPDF

IronPDF是一个多功能的npm软件包,旨在简化Node.js应用程序中的PDF生成。 它允许您从中创建PDF文档HTML 内容, 网址,或现有的 PDF 文件。 无论您需要生成发票、报告或其他类型的文档,IronPDF都通过其直观的界面使流程变得简单。应用程序接口和全面的功能集。

IronPDF 的主要功能

HTML 转换为 PDF

轻松地将HTML内容转换为PDF文档,完美适用于从网页内容生成动态PDF。

2. URL 转 PDF 转换

直接从URL创建PDF,使您能够捕获网页内容并以编程方式将其保存为PDF文件。

3. PDF 操作

合并轻松拆分和操作现有的PDF文档。 IronPDF提供追加页面、拆分文档的功能,创建PDF表单,以及更多。

PDF安全性

通过以下方式保护您的PDF文档:加密他们与密码或应用数字签名保护您的敏感文件免受未经授权的访问。

5. 高质量输出

生成高质量的PDF文档,准确渲染文本、图像和格式,确保生成的PDF保持与原始内容一致。

6. 跨平台兼容性

IronPDF 与 Windows、Linux 和 macOS 的兼容性使其适用于各种开发环境。

7. 简单集成

通过其npm包轻松将IronPDF集成到您的Node.js应用程序中。 完善的API简化了将PDF生成功能集成到您的项目中。

无论您是在开发 Web 应用程序、服务器端脚本还是命令行工具,IronPDF 都能让您高效且可靠地创建专业级 PDF 文档。

使用IronPDF生成PDF文档并使用Recharts NPM包

安装依赖项:首先,创建一个新的 Next.js 项目(如果你还没有)使用以下命令:参阅这里

npx create-next-app@latest replicate-pdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
npx create-next-app@latest replicate-pdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'npx create-@next-app@latest replicate-pdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
VB   C#

接下来,导航到你的项目目录:

cd replicate-pdf
cd replicate-pdf
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'cd replicate-pdf
VB   C#

安装所需的软件包:

yarn add @ironsoftware/ironpdf @ironsoftware/ironpdf-engine-windows-x64
yarn add replicate
yarn add @ironsoftware/ironpdf @ironsoftware/ironpdf-engine-windows-x64
yarn add replicate
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'yarn add @ironsoftware/ironpdf @ironsoftware/ironpdf-engine-windows-x64 yarn add replicate
VB   C#

创建PDF:现在,让我们用IronPDF创建一个生成PDF的简单示例。 在您的Next.js组件中(例如,pages/index.tsx)添加以下代码

PDF 生成 API:第一步是创建一个后端 API 来生成 PDF 文档。 由于IronPDF仅在服务器端运行,我们需要创建一个API,以便在用户想生成PDF时进行调用。 在路径 pages/api/pdf/route.js 中创建一个文件,并添加以下内容:

// pages/api/pdf.js
import { NextRequest, NextResponse } from 'next/server';
import {IronPdfGlobalConfig, PdfDocument} from "@ironsoftware/ironpdf";
// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "your key";
export const GET = async (req) => {
    const {searchParams} = new URL(req.url);
    const name = searchParams.get("url"); 
    try {
        const pdf = await PdfDocument.fromUrl(name);
        const data = await pdf.saveAsBuffer();
        console.error('data PDF:', data);
        return new NextResponse(data, {
            status: 200,
            headers: {
                "content-type": "application/pdf",
                "Content-Disposition": "attachment; filename=awesomeIron.pdf",
            },
        })
    } catch (error) {
        console.error('Error generating PDF:', error);
        return NextResponse.json({ detail: "error" }, { status: 500 });
    }
}
// pages/api/pdf.js
import { NextRequest, NextResponse } from 'next/server';
import {IronPdfGlobalConfig, PdfDocument} from "@ironsoftware/ironpdf";
// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "your key";
export const GET = async (req) => {
    const {searchParams} = new URL(req.url);
    const name = searchParams.get("url"); 
    try {
        const pdf = await PdfDocument.fromUrl(name);
        const data = await pdf.saveAsBuffer();
        console.error('data PDF:', data);
        return new NextResponse(data, {
            status: 200,
            headers: {
                "content-type": "application/pdf",
                "Content-Disposition": "attachment; filename=awesomeIron.pdf",
            },
        })
    } catch (error) {
        console.error('Error generating PDF:', error);
        return NextResponse.json({ detail: "error" }, { status: 500 });
    }
}
' pages/api/pdf.js
import
If True Then
	NextRequest, NextResponse
End If
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'from '@next/server'; import {IronPdfGlobalConfig, PdfDocument} from "@ironsoftware/ironpdf"; IronPdfGlobalConfig.getConfig().licenseKey = "your key"; export const @GET = async(req) => { const {searchParams} = New URL(req.url); const name = searchParams.@get("url"); try { const pdf = await PdfDocument.fromUrl(name); const data = await pdf.saveAsBuffer(); console.@error('data PDF:', data); Return New NextResponse(data, { status: 200, headers: { "content-type": "application/pdf", "Content-Disposition": "attachment; filename=awesomeIron.pdf"}}) } catch(@error) { console.@error('@Error generating PDF:', @error); Return NextResponse.json({ detail: "error" }, { status: 500 }); } }
VB   C#

IronPDF 需要许可证密钥,您可以从许可证页面并放置在上述代码中

将以下代码添加到 index.js

'use client';
import { useState, useEffect, useRef } from "react";
import Image from "next/image";
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
export default function Home() {
  const [prediction, setPrediction] = useState(null);
  const [error, setError] = useState(null);
  const promptInputRef = useRef(null);
  useEffect(() => {
    promptInputRef.current.focus();
  }, []);
  const handleSubmit = async (e) => {
    e.preventDefault();
    const response = await fetch("/api/predictions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        prompt: e.target.prompt.value,
      }),
    });
    let prediction = await response.json();
    if (response.status !== 201) {
      setError(prediction.detail);
      return;
    }
    setPrediction(prediction);
    while (
      prediction.status !== "succeeded" &&
      prediction.status !== "failed"
    ) {
      await sleep(1000);
      const response = await fetch(`/api/predictions/${prediction.id}`);
      prediction = await response.json();
      if (response.status !== 200) {
        setError(prediction.detail);
        return;
      }
      console.log({ prediction });
      setPrediction(prediction);
    }
  };
  const generatePdf = async () => {
    try {
      const response = await fetch("/api/pdf?url=" + prediction.output[prediction.output.length - 1]);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(new Blob([blob]));
      const link = document.createElement("a");
      link.href = url;
      link.setAttribute("download", "awesomeIron.pdf");
      document.body.appendChild(link);
      link.click();
      link.parentNode.removeChild(link);
    } catch (error) {
      console.error("Error generating PDF:", error);
    }
  }
  return (
    <div className="container max-w-2xl mx-auto p-5">
      <h1 className="py-6 text-center font-bold text-2xl">
        IronPDF An Awesome Library for PDFs
      </h1>
      <p>Enter prompt to generate an image, Then click </p>
      <form className="w-full flex" onSubmit={handleSubmit}>
        <input
          type="text"
          className="flex-grow"
          name="prompt"
          placeholder="Enter a prompt to display an image"
          ref={promptInputRef}
        />
        <button className="button" type="submit">
          Go!
        </button>
        <button className="pdfButton" type="button" onClick={generatePdf}>
          Generate PDF
        </button>
      </form>
      {error && <div>{error}</div>}
      {prediction && (
        <>
          {prediction.output && (
            <div className="image-wrapper mt-5">
              <Image
                fill
                src={prediction.output[prediction.output.length - 1]}
                alt="output"
                sizes="100vw"
              />
            </div>
          )}
          <p className="py-3 text-sm opacity-50">status: {prediction.status}</p>
        </>
      )}
    </div>
  );
}
'use client';
import { useState, useEffect, useRef } from "react";
import Image from "next/image";
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
export default function Home() {
  const [prediction, setPrediction] = useState(null);
  const [error, setError] = useState(null);
  const promptInputRef = useRef(null);
  useEffect(() => {
    promptInputRef.current.focus();
  }, []);
  const handleSubmit = async (e) => {
    e.preventDefault();
    const response = await fetch("/api/predictions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        prompt: e.target.prompt.value,
      }),
    });
    let prediction = await response.json();
    if (response.status !== 201) {
      setError(prediction.detail);
      return;
    }
    setPrediction(prediction);
    while (
      prediction.status !== "succeeded" &&
      prediction.status !== "failed"
    ) {
      await sleep(1000);
      const response = await fetch(`/api/predictions/${prediction.id}`);
      prediction = await response.json();
      if (response.status !== 200) {
        setError(prediction.detail);
        return;
      }
      console.log({ prediction });
      setPrediction(prediction);
    }
  };
  const generatePdf = async () => {
    try {
      const response = await fetch("/api/pdf?url=" + prediction.output[prediction.output.length - 1]);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(new Blob([blob]));
      const link = document.createElement("a");
      link.href = url;
      link.setAttribute("download", "awesomeIron.pdf");
      document.body.appendChild(link);
      link.click();
      link.parentNode.removeChild(link);
    } catch (error) {
      console.error("Error generating PDF:", error);
    }
  }
  return (
    <div className="container max-w-2xl mx-auto p-5">
      <h1 className="py-6 text-center font-bold text-2xl">
        IronPDF An Awesome Library for PDFs
      </h1>
      <p>Enter prompt to generate an image, Then click </p>
      <form className="w-full flex" onSubmit={handleSubmit}>
        <input
          type="text"
          className="flex-grow"
          name="prompt"
          placeholder="Enter a prompt to display an image"
          ref={promptInputRef}
        />
        <button className="button" type="submit">
          Go!
        </button>
        <button className="pdfButton" type="button" onClick={generatePdf}>
          Generate PDF
        </button>
      </form>
      {error && <div>{error}</div>}
      {prediction && (
        <>
          {prediction.output && (
            <div className="image-wrapper mt-5">
              <Image
                fill
                src={prediction.output[prediction.output.length - 1]}
                alt="output"
                sizes="100vw"
              />
            </div>
          )}
          <p className="py-3 text-sm opacity-50">status: {prediction.status}</p>
        </>
      )}
    </div>
  );
}
'INSTANT VB TODO TASK: The following line uses invalid syntax:
''use client'; import { useState, useEffect, useRef } from "react"; import Image from "next/image"; const sleep = (ms) => New Promise((r) => setTimeout(r, ms)); export default @function Home() { const [prediction, setPrediction] = useState(Nothing); const [@error, setError] = useState(Nothing); const promptInputRef = useRef(Nothing); useEffect(() => { promptInputRef.current.focus(); }, []); const handleSubmit = async(e) => { e.preventDefault(); const response = await fetch("/api/predictions", { method: "POST", headers: { "Content-Type": "application/json"}, body: JSON.stringify({ prompt: e.target.prompt.value})}); let prediction = await response.json(); if(response.status !== 201) { setError(prediction.detail); Return; } setPrediction(prediction); while (prediction.status !== "succeeded" && prediction.status !== "failed") { await sleep(1000); const response = await fetch(`/api/predictions/${prediction.id}`); prediction = await response.json(); if(response.status !== 200) { setError(prediction.detail); Return; } console.log({ prediction }); setPrediction(prediction); } }; const generatePdf = async() => { try { const response = await fetch("/api/pdf?url=" + prediction.output[prediction.output.length - 1]); const blob = await response.blob(); const url = window.URL.createObjectURL(New Blob([blob])); const link = document.createElement("a"); link.href = url; link.setAttribute("download", "awesomeIron.pdf"); document.body.appendChild(link); link.click(); link.parentNode.removeChild(link); } catch(@error) { console.@error("Error generating PDF:", @error); } } Return(<div className="container max-w-2xl mx-auto p-5"> <h1 className="py-6 text-center font-bold text-2xl"> IronPDF An Awesome Library for PDFs </h1> <p> Enter prompt @to generate an image, @Then click </p> <form className="w-full flex" onSubmit={handleSubmit}> <input type="text" className="flex-grow" name="prompt" placeholder="Enter a prompt to display an image" ref={promptInputRef} /> <button className="button" type="submit"> Go! </button> <button className="pdfButton" type="button" onClick={generatePdf}> Generate PDF </button> </form> {@error && <div>{@error}</div>} {prediction && (<> {prediction.output && (<div className="image-wrapper mt-5"> <Image fill src={prediction.output[prediction.output.length - 1]} alt="output" sizes="100vw" /> </div>)} <p className="py-3 text-sm opacity-50"> status: {prediction.status}</p> </>)} </div>); }
VB   C#

代码解释

1. 导入语句

代码开始时从外部库中导入必要的模块:从“react”导入的 'useState'、'useEffect' 和 'useRef':这些是 React Hooks,分别允许函数组件管理状态、处理副作用以及创建对 DOM 元素的引用。

“next/image” 中的 “Image”:这是 Next.js 提供的用于优化图像加载的组件。 "use client" 语句不是标准的 JavaScript 或 React 导入。 看起来特定于Next.js(React框架)并表明使用它的组件应在客户端呈现。它确保将该组件所需的JavaScript发送给客户端。

2. 组件功能

"Home" 组件被定义为默认导出。 在组件内部,有几个状态变量。(“预测”,“错误”)使用 'useState' 钩子管理。

参考('promptInputRef')是使用 'useRef' 钩子创建的。 在组件挂载时,使用 'useEffect' 钩子来聚焦 'promptInputRef'。

handleSubmit”函数是一个处理表单提交的异步函数。 它向API端点发送一个POST请求(/api/predictions)具有提示值。

响应经过处理,如果成功,'prediction' 状态会被更新。 然后,函数进入循环,定期检查预测状态,直到成功或失败。 “generatePdf” 方法从另一个 API 端点获取 PDF。(`/api/pdf`)基于“预测”状态的最后输出。

3. HTML标记

该组件返回一个带有一些样式的容器 div ('max-w-2xl', 'mx-auto', 'p-5'). 在容器内,有一个'

'元素,文本为“AwesomeIron”(可能是一个项目名称或标题).

总体而言,该代码似乎是一个 Next.js 应用程序的一部分,用于处理预测并根据用户输入生成 PDF。 “use client”语句是Next.js特有的,确保该组件在使用时进行客户端渲染。 如果您对代码的特定部分有任何具体问题

输出

复制 npm(如何为开发人员工作):图 1 - 这是您的 Next.js 应用程序使用 Replicate 和 IronPDF 的样子!

输入预测文本为“car”,然后下面的图像被预测

复制 npm(如何为开发人员服务): 图 2 - 在输入提示中,添加文本 car 进行预测,然后点击 Go 按钮。 使用 Replicate 预测和生成汽车图像。

然后点击生成 PDF 创建一个 PDF 文档。

使用IronPDF生成的输出PDF

复制 npm(开发者如何使用):图 3 - 接下来,您可以点击生成 PDF 按钮,使用 IronPDF 将此图像转换为 PDF。

IronPDF 许可证

IronPDFpage.

将许可证密钥放置在应用程序中,如下例所示:

import {IronPdfGlobalConfig, PdfDocument} from "@ironsoftware/ironpdf";
// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";
import {IronPdfGlobalConfig, PdfDocument} from "@ironsoftware/ironpdf";
// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

结论

[复制](https://www.npmjs.com/package/replicate)NPM 包为 React 应用程序提供了一个利用强大机器学习模型的便捷方式。 通过遵循本文中列出的步骤,您可以轻松地将图像生成功能集成到您的项目中。 这为创造创新和互动的用户体验开辟了广阔的可能性。

请记得探索可用的其他模型复制平台以进一步扩展您的应用程序功能。

以及,IronPDF是一个强大的PDF库,具有PDF生成和操作功能,以及能够呈现响应式图表即时在PDF中。 它使开发人员能够通过几行代码将功能丰富的图表包集成到应用程序中。 结合这两个库,开发人员可以使用现代AI技术,并以PDF的形式可靠地保存结果。

< 前一页
xml2js npm(开发人员如何使用)
下一步 >
toastify npm(它是如何为开发人员工作的)

准备开始了吗? 版本: 2024.11 刚刚发布

免费 npm 安装 查看许可证 >