목차
Background
도구 라이브러리 준비
함수 구현/src/index.js
새 예제 코드 폴더/example
테스트 함수
Packaging
Install Rollup
babel 설치
설치 모듈
commonjs와 호환
번들 압축
完整配置
发包前的准备
准备一个简单清晰的readme.md
修改package.json
웹 프론트엔드 JS 튜토리얼 npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.

npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.

Dec 08, 2022 pm 08:26 PM
nodejs​ node npm

2202년인데 아직도 npm 패키지 출시 방법을 모르시는 분들 계시나요? 다음 기사에서는 npm을 처음부터 만들고 게시하는 전체 과정을 공유하겠습니다. 도움이 되기를 바랍니다.

npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.

Background

기사가 4월에 게시되었습니다. 오셔서 프로젝트의 axios 패키지를 업그레이드하고 반복적인 요청에 작별을 고하세요 정기적인 요청과 자동 요청을 지원하는 axios의 보조 패키지가 도입되었습니다. 요청을 정의하고 동일한 요청을 동시에 가로채기(이 글을 읽지 않으셨다면 3분 정도 시간을 내어 대략적으로 이해하시는 것을 권장합니다). 마침 최근에 크로스 프레임워크 구성 요소 라이브러리를 작성하려고 준비 중입니다(작업량이 매우 과중하고 세 명의 프런트 엔드 친구가 여가 시간에 작업하고 있습니다. 구성 요소 라이브러리가 끝난 후 모든 사람과 공유할 것입니다). 완료되었으므로 계속 지켜봐 주시기 바랍니다.) 어제 저는 여유 시간을 활용하여 이전에 작성한 axios 패키지를 npm 패키지로 제거하여 코드 재사용을 용이하게 하는 방법을 생각했습니다. 지역 사회에 환원하면서 배웠습니다.

이 기사를 읽으면 다음과 같은 이점을 얻을 수 있습니다.

  • npm을 처음부터 만들고 게시하는 전체 프로세스. [추천 관련 튜토리얼: nodejs 비디오 튜토리얼, 프로그래밍 교육]

  • 지속적으로 반복되고 간단하며 실용적인 Axios 요청 중복 제거 도구 라이브러리입니다.

도구 라이브러리 준비

package.json을 포함한 새 프로젝트 만들기

{
    "name": "drrq",
    "type": "module",
    "version": "1.0.0"
}
로그인 후 복사

함수 구현/src/index.js

npm i qs axios

핵심 아이디어는 요청된 URL과 매개변수를 키로 사용하는 것입니다. 요청 Queue를 기록하기 위해 반복 요청이 발생하면 후속 요청이 중단되고 이전 요청의 결과가 반환될 때 후속 요청과 공유됩니다.

import qs from "qs";
import axios from "axios";

let pending = []; //用于存储每个ajax请求的取消函数和ajax标识
let task = {}; //用于存储每个ajax请求的处理函数,通过请求结果调用,以ajax标识为key

//请求开始前推入pending
const pushPending = (item) => {
    pending.push(item);
};
//请求完成后取消该请求,从列表删除
const removePending = (key) => {
    for (let p in pending) {
        if (pending[p].key === key) {
            //当前请求在列表中存在时
            pending[p].cancelToken(); //执行取消操作
            pending.splice(p, 1); //把这条记录从列表中移除
        }
    }
};
//请求前判断是否已存在该请求
const existInPending = (key) => {
    return pending.some((e) => e.key === key);
};

// 创建task
const createTask = (key, resolve) => {
    let callback = (response) => {
        resolve(response.data);
    };
    if (!task[key]) task[key] = [];
    task[key].push(callback);
};
// 处理task
const handleTask = (key, response) => {
    for (let i = 0; task[key] && i < task[key].length; i++) {
        task[key][i](response);
    }
    task[key] = undefined;
};

const getHeaders = { &#39;Content-Type&#39;: &#39;application/json&#39; };
const postHeaders = { &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39; };
const fileHeaders = { &#39;Content-Type&#39;: &#39;multipart/form-data&#39; };

const request = (method, url, params, headers, preventRepeat = true, uploadFile = false) => {
    let key = url + &#39;?&#39; + qs.stringify(params);
    return new Promise((resolve, reject) => {
        const instance = axios.create({
            baseURL: url,
            headers,
            timeout: 30 * 1000,
        });

        instance.interceptors.request.use(
            (config) => {
                if (preventRepeat) {
                    config.cancelToken = new axios.CancelToken((cancelToken) => {
                        // 判断是否存在请求中的当前请求 如果有取消当前请求
                        if (existInPending(key)) {
                            cancelToken();
                        } else {
                            pushPending({ key, cancelToken });
                        }
                    });
                }
                return config;
            },
            (err) => {
                return Promise.reject(err);
            }
        );

        instance.interceptors.response.use(
            (response) => {
                if (preventRepeat) {
                    removePending(key);
                }
                return response;
            },
            (error) => {
                return Promise.reject(error);
            }
        );

        // 请求执行前加入task
        createTask(key, resolve);

        instance(Object.assign({}, { method }, method === &#39;post&#39; || method === &#39;put&#39; ? { data: !uploadFile ? qs.stringify(params) : params } : { params }))
            .then((response) => {
                // 处理task
                handleTask(key, response);
            })
            .catch(() => {});
    });
};

export const get = (url, data = {}, preventRepeat = true) => {
    return request(&#39;get&#39;, url, data, getHeaders, preventRepeat, false);
};
 export const post = (url, data = {}, preventRepeat = true) => {
     return request(&#39;post&#39;, url, data, postHeaders, preventRepeat, false);
 };
 export const file = (url, data = {}, preventRepeat = true) => {
     return request(&#39;post&#39;, url, data, fileHeaders, preventRepeat, true);
 };
export default { request, get, post, file };
로그인 후 복사

새 예제 코드 폴더/example

예제 입구 index.js

import { exampleRequestGet } from &#39;./api.js&#39;;
const example = async () => {
    let res = await exampleRequestGet();
    console.log(&#39;请求成功 &#39;);
};
example();
로그인 후 복사

api list api.js

import { request } from &#39;./request.js&#39;;
// 示例请求Get
export const exampleRequestGet = (data) => request(&#39;get&#39;, &#39;/xxxx&#39;, data);

// 示例请求Post
export const exampleRequestPost = (data) => request(&#39;post&#39;, &#39;/xxxx&#39;, data);

// 示例请求Post 不去重
export const exampleRequestPost2 = (data) => request(&#39;post&#39;, &#39;/xxxx&#39;, data, false);

// 示例请求Post 不去重
export const exampleRequestFile = (data) => request(&#39;file&#39;, &#39;/xxxx&#39;, data, false);
로그인 후 복사

전역 요청 캡슐화 request.js

import drrq from &#39;../src/index.js&#39;;
const baseURL = &#39;https://xxx&#39;;

// 处理请求数据  (拼接url,data添加token等) 请根据实际情况调整
const paramsHandler = (url, data) => {
    url = baseURL + url;
    data.token = &#39;xxxx&#39;;
    return { url, data };
};

// 处理全局接口返回的全局处理相关逻辑  请根据实际情况调整
const resHandler = (res) => {
    // TODO 未授权跳转登录,状态码异常报错等
    return res;
};

export const request = async (method, _url, _data = {}, preventRepeat = true) => {
    let { url, data } = paramsHandler(_url, _data);
    let res = null;
    if (method == &#39;get&#39; || method == &#39;GET&#39; || method == &#39;Get&#39;) {
        res = await drrq.get(url, data, preventRepeat);
    }
    if (method == &#39;post&#39; || method == &#39;POST&#39; || method == &#39;Post&#39;) {
        res = await drrq.post(url, data, preventRepeat);
    }
    if (method == &#39;file&#39; || method == &#39;FILE&#39; || method == &#39;file&#39;) {
        res = await drrq.file(url, data, preventRepeat);
    }
    return resHandler(res);
};
로그인 후 복사

테스트 함수

코드 작성 후 검증이 필요합니다 함수가 정상인가요? package.json에

    "scripts": {
        "test": "node example"
    },
로그인 후 복사

를 추가하고 npm run test

npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.

를 실행해 보세요. 함수가 정상이고 도구 라이브러리가 준비되어 있습니다.

(eslint, 예쁜 독자는 상황에 따라 선택 가능)

Packaging

일반 프로젝트 패키징은 webpack을 사용하고, 도구 라이브러리 패키징은 Rollup을 사용합니다.

Install Rollup

다음 명령을 통해 설치Rollup:

npm install --save-dev rollup
로그인 후 복사

구성 파일 만들기

루트 디렉터리에 새 파일인 Rollup.config.js를 만듭니다

export default {
  input: "src/index.js",
  output: {
    file: "dist/drrp.js",
    format: "esm",
    name: &#39;drrp&#39;
  }
};
로그인 후 복사
  • input - 패키징할 파일
  • output.file - 출력 파일(이 매개변수가 없으면 콘솔로 직접 출력)
  • output.format - Rollup으로 출력되는 파일 형식

babel 설치

개발에 es6 구문을 사용하려면 babel을 사용하여 코드를 es5로 컴파일해야 합니다. 롤업의 모듈 메커니즘은 ES6 모듈이므로 다른 es6 구문은 컴파일되지 않습니다.

설치 모듈

rollup-plugin-babel은 롤업과 바벨을 완벽하게 결합합니다.

npm install --save-dev rollup-plugin-babel@latest
npm install --save-dev @babel/core 
npm install --save-dev @babel/preset-env
로그인 후 복사

루트 디렉터리에 .babelrc 만들기

{
    "presets": [
      [
        "@babel/preset-env",
        {
          "modules": false
        }
      ]
    ]
}
로그인 후 복사

commonjs와 호환

rollup은 롤업에서 commonjs 표준 패키지를 쉽게 참조할 수 있도록 rollup-plugin-commonjs 플러그인을 제공합니다. 이 플러그인의 기능은 commonjs 모듈을 es6 모듈로 변환하는 것입니다.

rollup-plugin-commonjs는 일반적으로 종속 모듈 경로를 확인하는 데 사용되는 rollup-plugin-node-resolve와 함께 사용됩니다.

모듈 설치

npm install --save-dev rollup-plugin-commonjs rollup-plugin-node-resolve
로그인 후 복사

번들 압축

UglifyJS 추가 주석 제거, 변수 이름 단축, 코드 재구성을 통해 번들 크기를 크게 줄일 수 있습니다. 이렇게 하면 코드가 어느 정도 줄어들지만 읽기 쉬워집니다. 네트워크 통신에 효율적입니다.

플러그인 설치

다음 명령을 사용하여 rollup-plugin-uglify를 설치하세요.

npm install --save-dev rollup-plugin-uglify
로그인 후 복사

完整配置

rollup.config.js 最终配置如下

import resolve from &#39;rollup-plugin-node-resolve&#39;;
import commonjs from &#39;rollup-plugin-commonjs&#39;;
import babel from &#39;rollup-plugin-babel&#39;;
import { uglify } from &#39;rollup-plugin-uglify&#39;;
import json from &#39;@rollup/plugin-json&#39;

const paths = {
    input: {
        root:  &#39;src/index.js&#39;,
    },
    output: {
        root:  &#39;dist/&#39;,
    },
};

const fileName = `drrq.js`;

export default {
    input: `${paths.input.root}`,
    output: {
        file: `${paths.output.root}${fileName}`,
        format: &#39;esm&#39;,
        name: &#39;drrq&#39;,
    },
    plugins: [
        json(),
        resolve(),
        commonjs(),
        babel({
            exclude: &#39;node_modules/**&#39;,
            runtimeHelpers: true,
        }),
        uglify(),
    ],
};
로그인 후 복사

在package.json中加上

"scripts": {
    "build": "rollup -c"
},
로그인 후 복사

即可执行npm run build将/src/index.js打包为/dist/drrq.js

发包前的准备

准备npm账号,通过npm login或npm adduser。这里有一个坑,终端内连接不上npm源,需要在上网工具内复制终端代理命令后到终端执行才能正常连接。

npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.

准备一个简单清晰的readme.md

npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.

修改package.json

完整的package.json如下

{
    "name": "drrq",
    "private": false,
    "version": "1.3.5",
    "main": "/dist/drrq.js",
    "repository": "https://gitee.com/yuanying-11/drrq.git",
    "author": "it_yuanying",
    "license": "MIT",
    "description": "能自动取消重复请求的axios封装",
    "type": "module",
    "keywords": [
        "取消重复请求",
    ],
    "dependencies": {
        "axios": "^1.2.0",
        "qs": "^6.11.0"
    },
    "scripts": {
        "test": "node example",
        "build": "rollup -c"
    },
    "devDependencies": {
       ...
    }
}
로그인 후 복사
  • name 包名称 一定不能与npm已有的包名重复,想一个简单易记的
  • private 是否为私有
  • version 版本
  • main 入口文件位置
  • repository git仓库地址
  • author 作者
  • license 协议
  • description 描述
  • keywords 关键词,便于检索

每个 npm 包都需要一个版本,以便开发人员在安全地更新包版本的同时不会破坏其余的代码。npm 使用的版本系统被叫做 SemVer,是 Semantic Versioning 的缩写。

不要过分担心理解不了相较复杂的版本名称,下面是他们对基本版本命名的总结: 给定版本号 MAJOR.MINOR.PATCH,增量规则如下:

  • MAJOR 版本号的变更说明新版本产生了不兼容低版本的 API 等,

  • MINOR 版本号的变更说明你在以向后兼容的方式添加功能,接下来

  • PATCH 版本号的变更说明你在新版本中做了向后兼容的 bug 修复。

表示预发布和构建元数据的附加标签可作为 MAJOR.MINOR.PATCH 格式的扩展。

最后,执行npm publish就搞定啦

npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.

npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.

本文的完整代码已开源至gitee.com/yuanying-11… ,感兴趣的读者欢迎fork和star!

转载地址:https://juejin.cn/post/7172240485778456606

更多node相关知识,请访问:nodejs 教程

위 내용은 npm 패키지를 처음부터 생성하고 게시하는 방법을 단계별로 안내합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

npm React 설치 시 오류가 발생하면 어떻게 해야 하나요? npm React 설치 시 오류가 발생하면 어떻게 해야 하나요? Dec 27, 2022 am 11:25 AM

npm 반응 설치 오류에 대한 해결 방법: 1. 프로젝트에서 "package.json" 파일을 열고 종속성 개체를 찾습니다. 2. "react.json"을 "devDependency"로 이동합니다. 3. 터미널에서 "npm audit"를 실행합니다. 생산'을 통해 경고를 수정합니다.

nvm에서 노드를 삭제하는 방법 nvm에서 노드를 삭제하는 방법 Dec 29, 2022 am 10:07 AM

nvm을 사용하여 노드를 삭제하는 방법: 1. "nvm-setup.zip"을 다운로드하여 C 드라이브에 설치합니다. 2. "nvm -v" 명령을 통해 환경 변수를 구성하고 버전 번호를 확인합니다. install" 명령 노드 설치; 4. "nvm uninstall" 명령을 통해 설치된 노드를 삭제합니다.

Express를 사용하여 노드 프로젝트에서 파일 업로드를 처리하는 방법 Express를 사용하여 노드 프로젝트에서 파일 업로드를 처리하는 방법 Mar 28, 2023 pm 07:28 PM

파일 업로드를 처리하는 방법은 무엇입니까? 다음 글에서는 Express를 사용하여 노드 프로젝트에서 파일 업로드를 처리하는 방법을 소개하겠습니다. 도움이 되길 바랍니다.

Node의 프로세스 관리 도구 'pm2”에 대한 심층 분석 Node의 프로세스 관리 도구 'pm2”에 대한 심층 분석 Apr 03, 2023 pm 06:02 PM

이 기사에서는 Node의 프로세스 관리 도구인 "pm2"를 공유하고 pm2가 필요한 이유, pm2 설치 및 사용 방법에 대해 설명합니다. 모두에게 도움이 되기를 바랍니다!

PI 노드 교육 : PI 노드 란 무엇입니까? Pi 노드를 설치하고 설정하는 방법은 무엇입니까? PI 노드 교육 : PI 노드 란 무엇입니까? Pi 노드를 설치하고 설정하는 방법은 무엇입니까? Mar 05, 2025 pm 05:57 PM

Pinetwork 노드에 대한 자세한 설명 및 설치 안내서이 기사에서는 Pinetwork Ecosystem을 자세히 소개합니다. Pi 노드, Pinetwork 생태계의 주요 역할을 수행하고 설치 및 구성을위한 전체 단계를 제공합니다. Pinetwork 블록 체인 테스트 네트워크가 출시 된 후, PI 노드는 다가오는 주요 네트워크 릴리스를 준비하여 테스트에 적극적으로 참여하는 많은 개척자들의 중요한 부분이되었습니다. 아직 Pinetwork를 모른다면 Picoin이 무엇인지 참조하십시오. 리스팅 가격은 얼마입니까? PI 사용, 광업 및 보안 분석. Pinetwork 란 무엇입니까? Pinetwork 프로젝트는 2019 년에 시작되었으며 독점적 인 Cryptocurrency Pi Coin을 소유하고 있습니다. 이 프로젝트는 모든 사람이 참여할 수있는 사람을 만드는 것을 목표로합니다.

노드가 npm 명령을 사용할 수 없으면 어떻게 해야 합니까? 노드가 npm 명령을 사용할 수 없으면 어떻게 해야 합니까? Feb 08, 2023 am 10:09 AM

노드가 npm 명령을 사용할 수 없는 이유는 환경 변수가 올바르게 구성되지 않았기 때문입니다. 해결 방법은 다음과 같습니다. 1. "시스템 속성"을 엽니다. 2. "환경 변수" -> "시스템 변수"를 찾은 다음 환경을 편집합니다. 3. nodejs 폴더의 위치를 ​​찾습니다. 4. "확인"을 클릭합니다.

pkg를 사용하여 Node.js 프로젝트를 실행 파일로 패키징하는 방법에 대해 이야기해 보겠습니다. pkg를 사용하여 Node.js 프로젝트를 실행 파일로 패키징하는 방법에 대해 이야기해 보겠습니다. Dec 02, 2022 pm 09:06 PM

nodejs 실행 파일을 pkg로 패키징하는 방법은 무엇입니까? 다음 기사에서는 pkg를 사용하여 Node 프로젝트를 실행 파일로 패키징하는 방법을 소개합니다. 도움이 되기를 바랍니다.

npm node gyp가 실패하는 경우 수행할 작업 npm node gyp가 실패하는 경우 수행할 작업 Dec 29, 2022 pm 02:42 PM

"node-gyp.js"와 "Node.js"의 버전이 일치하지 않아 npm node gyp가 실패했습니다. 해결 방법: 1. "npm 캐시 clean -f"를 통해 노드 캐시를 지웁니다. 2. "npm install - g n" n 모듈을 설치합니다. 3. "n v12.21.0" 명령을 통해 "node v12.21.0" 버전을 설치합니다.

See all articles