草庐IT

如何手写一个js工具库?同时发布到npm上

oldCode 2023-03-28 原文

自从工作以来,写项目的时候经常需要手写一些方法和引入一些js库

JS基础又十分重要,于是就萌生出自己创建一个JS工具库并发布到npm上的想法

于是就创建了一个名为learnjts的项目,在空余时间也写了几个工具函数,后续还会再继续增加...

这篇文章就是一篇实战文章,我把自己创建项目,发布到npm,以及遇到的问题和解决方案全都记录了下来,如果你也想创建一个自己的js工具库,可以根据这篇文章一步一步的尝试一下

github项目地址

npm项目地址

创建项目

打开命令窗口,创建一个项目文件

mkdir learnjts  // 创建了一个名为 learnjts 的文件夹

cd learnjts  // 进入此文件夹

然后初始化项目

npm init

我们可以看到:让我们给项目起一个名字,括号内是默认文件夹的名字,不用修改,回车就可以

还会弹出来许多的参数,我们可以写上,也可以一路回车,一直到最后,就会生成一个package.json文件夹

如果要修改可以直接在这里修改

创建一个src文件夹,里面放一些js文件,可以写工具方法,再在根目录下创建一个index.js作为入口文件

写工具方法

项目骨架已经建好了,接下来我们开始写工具方法

第一个工具方法,我写了一个数据类型的判断方法

先在src文件夹下面建一个getDataType.js

function getDataType(target){
    let type = typeof target
    // 判断是否是复杂数据类型
    if(type === 'object'){
        return Object.prototype.toString.call(target).replace(/^[object (\S+)]$/, '$1').toLowerCase();
    }else{
        // 基础数据类型直接返回
        return type
    }
}
//导出这个方法
export default getDataType

然后在index.js文件里导入 getDataType方法,并且验证是否能够使用

然后就会发现,报错了

从报错信息我们可以看到是 import出错了

解决方案:给package.js添加一个属性

"type":"module",

此时再运行一下可以看到,能够正常运行了

以后我们在src目录下肯定会增加很多工具函数,所以可以吧index.js当成一个入口,所有的工具函数都可以从这里导出出去

import getDataType from './src/getDataType.js'

export {
    getDataType,
}

注册npm账号

要想自己的工具库别人也能够使用,需要把它发到npm上 npm官网

此时就需要注册一个npm账号了

注册npm需要有一个邮箱,任何邮箱都可以,能接收到验证码就可以,注册时会收到验证码

开始发布

当你注册好npm账号后,你就可以去项目中准备 发布 了

设置npm源

但是在发布之前,需要检查一下npm源,如果是其他源,就会发布失败,此时你需要把它设置为npm源

在项目终端里输入npm config get registry,可以查看当前源

npm config get registry

可以看到此时我的源是npm源,可以发布,如果是淘宝源呢?

就需要设置npm源

npm config set registry https://registry.npmjs.org/

登录npm账号

因为我们是第一次发布包,所以需要在终端登录我们的npm用户,输入我们的用户名,和密码和邮箱

在终端输入

npm adduser

需要注意的是,我们输入密码时,不会再终端上显示出来,输入完直接按回车就好

接着开始让你输入npm的邮箱号,再次按回车时,会给你的邮箱发一个验证码,你需要把这个验证码再输入上

发布到npm上

登录好后,开始发布,在终端输入

npm publish

发布的时候,有可能就会报错:提示信息就会问你:你没有登录对账号吧?

其实真正的错误原因:是因为你的项目名称和npm上的项目重名了

在起名字的时候,你可以去npm上搜一下

嘿嘿_ 这个其实是我之前写好的,只是为了给大家演示,又从零搭建又写了一遍

如果没有搜到,则说明你可以使用这个名字

如果你重名了,你就在package.js里面改名吧

此时再次发布,就可以看到,发布成功了

回到npm,点击自己的头像,再点击Profile,就可以看到自己的npm库了

使用自己的工具库

新建一个项目,再建一个js文件

在终端输入npm install learnjts

npm install learnjts

安装成功可以看到我们的项目里多了几个文件

在index.js文件里引入工具函数

有可能还会报 import 引入错误,解决方案和上面一样

此时可以看到可以正常打印出来数据类型,则说明

添加eslint 和 单元测试

添加一个README.md文档,来介绍自己的工具库

添加 eslint

既然写都写了,肯定要最好最全面的配置呀,所以我决定添加eslint

两种安装方式,一般选择第二种在当前项目安装

//方式一.全局安装
npm i -g eslint

//方式二.当前项目安装
npm i -D eslint

使用命令配置并生成一个.eslintrc文件

npm init @eslint/config

命令行会有一些简单的配置,生成如下内容

module.exports = {
    "env": {
        "browser": true,
        "node": true,
        "es2021": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "rules": {
    }
}

配置一下规则,可以在env里添加node,es6等

module.exports = {
    "env": {
        "browser": true,
        "node": true,
        "es6": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "rules": {
        "space-before-function-paren": 0,  // 函数定义时括号前面要不要有空格
        "semi": 0,  // 语句可以不需要分号结尾
        "eqeqeq": 1, // 必须使用全等
    
    }
}

可以在rules配置一些语法规则

module.exports = {
    
    "rules": {
        /* 
            "off" -> 0 关闭规则
            "warn" -> 1 开启警告规则
            "error" -> 2 开启错误规则
        */
        "space-before-function-paren": 0,  // 函数定义时括号前面要不要有空格
        "semi": 0,  // 语句可以不需要分号结尾
        "eqeqeq": 2, // 必须使用全等
    
    }
}

此时再回到 getDataType.js文件中去就会发现,没有使用全等的地方爆红了,修改后恢复到正常

添加单元测试jest

单元测试的执行通常需要测试规范、断言、mock、覆盖率工具等支持

jest 是用来创建、执行和构建测试用例的 JavaScript 测试库,自身包含了 驱动、断言库、mock 、代码覆盖率等多种功能

安装

npm i --save-dev jest

把 jest 安装到项目后,在 package.json 添加配置

"scripts": {
  "test": "jest"
}

这样就可以使用命令 npm test 执行测试代码了

创建一个test/getDataType.test.js 文件来测试getDataType方法

import getDataType from '../src/getDataType.js';

test('getDataType(2)===number', () => {
  expect(getDataType(2)).toBe("number");
})

test('getDataType({a:1})===object', () => {
    expect(getDataType({a:1})).toBe("object");
})

此时你会发现,又有很多爆红

解决办法:在 「.eslintrc.cjs」 配置"jest": true

在jest原生测试框架中,无法使用es6的import export语法,只能使用commonJS语法,可以使用下面的方式解决

step1: 在项目根目录下添加.babelrc文件

{
  "env": {
    "test": {
      "plugins": ["@babel/plugin-transform-modules-commonjs"]
    }
  }
}

step2:安装ES6语法解析转换插件

npm install --save-dev @babel/plugin-transform-modules-commonjs

此时再运行

npm test

可以看到我们的单元测试,成功通过

可以在 「package.json」 里多加一个配置

"jest": {
    "collectCoverage": true
},

会生成一个 coverage 报告

更新

更新之前必须要修改一下版本号,否则就会报错更新失败

因为之前登录过了,所以直接输入npm publish就可以了

npm publish

再次到npm官网查看自己的库就可以看到,已经更新到1.0.1版本了,并且README文档已经显示出来了

在项目中引入最新包

在终端输入npm install learnjts@latest

npm install learnjts@latest

此时可以看到版本已经更到最新了

这就是我搭建一个自己的JS工具库的全部过程了,其中我遇到的问题和解决方案也都有讲解。但是毕竟经验不足,可能会有一些不对的地方或者局限性,仅供参考

learnjts工具库既然已经写出来了,其中也写了一些方法。下一步就准备使用vuepress2.x搭建一个文档,方便查阅和使用

learnjts项目源码和地址在这里☞
github项目地址 |
npm项目地址

有关如何手写一个js工具库?同时发布到npm上的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  9. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  10. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

随机推荐