likes
comments
collection
share

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

作者站长头像
站长
· 阅读数 22

npm 介绍

npm(全称为Node Package Manager)是 Node.js 的包管理器,它提供了一个方便的方法来安装、升级和删除 Node.js 的包或模块。npm 也可以用来管理前端包,因为现代前端应用一般都使用 Node.js 工具链来进行构建、测试和打包。npm 的优点是易于使用,它是一个强大的工具,让你可以快速地找到、安装和使用开源的 Node.js 包。

npm 打包发布流程

NPM是一个面向 Node.js 开发者的包管理工具,常用于发布、搜索、安装和管理 Node.js 模块。通常情况下,我们需要将自己编写的模块打包发布至 NPM 上,让其他开发者可以使用并管理这些模块。以下是将自己编写的模块打包发布的步骤:

1.在自己的项目根目录下创建一个 package.json 文件,可通过 npm init 命令自动创建。在 package.json 中填写项目的基本信息,如名称、版本、作者、依赖包等。

2.确保代码的可运行性并进行测试。可编写测试用例,并通过 npm test 命令进行测试。也可使用 JSHint、ESLint 等工具检查代码风格和语法错误。

3.编写 README.md 文件,简要描述模块的功能和使用方法。尽量使文档简明易懂,排版美观。

4.登录 NPM 账户,若没有账户则需要注册。使用 npm login 命令登陆,并输入账户信息。

5.将代码提交至 Git 仓库,并打上标签,以方便区分版本号、发布日期等信息。

6.运行 npm publish 命令即可将模块发布至 NPM 上。注意,第一次发布时需要等待官方审核通过后才能正式发布。发布成功后,其他开发者就可以使用 npm install 命令下载使用该模块了。

上述步骤为常用的打包发布流程,但实际情况可能因项目要求或其他因素而有所不同,建议根据具体情况进行调整和优化。

前置知识

模块化开发 发展历程

JavaScript的模块化开发在不断发展变迁中,以下是主要的几个发展历程:

  1. 最开始,JavaScript没有模块化支持,所有的代码都是写在一个大文件中。这种方式存在很多问题,代码难于维护、缺少封装性、命名冲突等等。

  2. 后来,出现了一些尝试解决这些问题的库和框架,例如AMD(Asynchronous Modules Definition)和CommonJS。AMD和CommonJS的区别在于,前者更适合浏览器端,后者则更适用于服务器端。

  3. 随着ES6(ECMAScript 2015)的发布,JavaScript天生支持了模块化开发。ES6模块提供了一个标准,不用再依赖第三方库或框架了,而且可以直接在浏览器端使用。

  4. 然而,在ES6发布后的一段时间内,浏览器的支持程度不足,所以使用ES6模块需要通过编译器(如Babel)转换为ES5代码方可使用。但这并不影响前端开发者对ES6模块愈加蓬勃的兴趣。

总的来说,JavaScript模块化的发展历程由无到有,经过了一系列的探索和尝试,现如今已经成为前端开发的重要标准之一。

按需加载问题

参考 www.rollupjs.com/guide/faqs

ES6 Tree Shaking 是一种用来优化 JavaScript 应用程序的技术,它可以帮助你减少应用程序的大小。在 Webpack、Rollup 等工具中,Tree Shaking 可以通过静态分析源码,找出没有被使用的代码,将其从最终生成的代码中删除,以此减少代码的体积。

Tree Shaking 技术依赖于 ES6 模块系统(import/export)中的静态解析特性。ES6 模块系统的特点是可以准确地判断模块的导入和导出语句,因此只要确定了一个模块没有被使用过,就可以安全地将它从构建结果中删除。

在使用 Tree Shaking 技术时,我们需要注意以下几点:

  1. 确保 ES6 模块化代码正确使用 import 和 export 语句;
  2. 避免使用动态导入(例如 require);
  3. 确保压缩代码时开启了 ES6 模块的支持。

通过 Tree Shaking 技术,可以减少应用程序的代码大小,使加载速度更快,提升应用的性能。

配置入口文件 使用 ES modules 模块方案

export {default as Button} from './components/Button'
export {default as TransMenu} from './components/Menu';

这段代码是一个 JavaScript 模块中的导出语句,使用了 ES6 模块化规范中的导出语法。

第一行代码,导出了一个名为 Button 的默认导出项,其值为 ./components/Button 模块的默认导出项。这里使用了 as 子句,用于重命名导出项。也就是说,当其他模块通过 import 语句导入该导出项时,可以使用 Button 来表示 ./components/Button 模块的默认导出项。

第二行代码,导出了一个名为 TransMenu 的默认导出项,其值为 ./components/Menu 模块的默认导出项。也是通过 as 子句来实现导出项的重命名。

这两行代码中的 default 关键字,表示导出了该模块的默认导出项。在导入该模块时,如果没有使用解构语法,那么默认导出项就是被导入的项。因此,其他模块可以通过下面的方式导入这两个导出项:

import { Button, TransMenu } from '这个模块的路径'

配置 tsconfig

在项目根目录下新建tsconfig.build.json 配置打包输出

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

{
  // Typescript编译器选项
  "compilerOptions": {
    // 编译产物输出目录
    "outDir": "dist",
    // 模块格式为ESNext
    "module": "esnext",
    // 目标ECMAScript版本为ES5
    "target": "es5",
    // 生成声明文件
    "declaration": true,
    // JSX语法支持
    "jsx": "react",
    // 模块解析策略为Node.js
    "moduleResolution": "Node",
    // 允许合成默认导入(import ... from 'module')形式
    "allowSyntheticDefaultImports": true,
  },
  // TypeScript编译器应该包含的目录
  "include": [
    "src"
  ],
  // TypeScript编译器应该排除的文件
  "exclude": [
    // 排除测试文件
    "src/**/*.test.tsx",
    // 排除Storybook文件
    "src/**/*.stories.tsx",
  ]
}

在package.json文件中scripts添加"build-ts":"tsc -p tsconfig.build.json"配置项

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

运行 npm run build-ts 命令进行打包输出

样式文件打包

在package.json文件中scripts添加"build-css":"node-sass ./src/styles/index.scss ./build/index.css",配置项 重置build 命令修改为npm run build-ts && npm run build-css npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

运行 npm run build 命令进行打包输出

rimraf 介绍 每次打包前删除打包后的文件夹,保证打包输出后为最新内容

www.npmjs.com/package/rim…

rimraf 是一个用来删除文件和文件夹的 Node.js 模块。该模块可以递归地删除指定目录下的所有文件和文件夹,与系统默认的 rm -rf 命令类似。

rimraf 的语法如下:

    rimraf <path>

其中 <path> 表示需要删除的目录或文件的路径。使用该命令需要先安装 rimraf 模块,在终端中执行以下命令:

    npm install rimraf -g

这样就可以全局使用 rimraf 命令。在 Node.js 中,也可以使用 require('rimraf') 来引入该模块,然后进行删除操作。 rimraf 是一个用来删除文件和文件夹的 Node.js 模块。该模块可以递归地删除指定目录下的所有文件和文件夹,与系统默认的 rm -rf 命令类似。 rimraf rimraf 的语法如下:

rimraf <path>

其中 <path> 表示需要删除的目录或文件的路径。使用该命令需要先安装 rimraf 模块,在终端中执行以下命令:

npm install rimraf -g

这样就可以全局使用 rimraf 命令。在 Node.js 中,也可以使用 require('rimraf') 来引入该模块,然后进行删除操作。

在package中配置使用在package.json文件中scripts添加"build-ts":"clean":"rimraf ./build"配置项 npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

本地测试组件库

npm link 介绍 npm link 命令用于将本地开发的 NPM 模块链接到全局环境中,从而可以在不离开项目目录的情况下,实时修改和测试该模块,而不需要频繁地推送到 NPM 并且重新安装。

具体来说,npm link 的作用是在全局环境下创建一个指向本地模块的软链接,这样全局安装的任何模块都可以访问到本地模块的最新代码变更,从而可以方便地对其进行自测和调试,而无需重新构建和发布模块。

使用 npm link 的流程如下:

  1. 进入开发的模块目录,执行以下命令将本地模块链接到全局安装目录:
 npm link
  1. 进入要使用该模块的项目目录,执行以下命令将全局安装目录中的本地模块链接到该项目的 node_modules 目录下:
 npm link <module-name>

其中 <module-name> 表示本地模块的名称,通常与该模块的 package.json 文件中定义的名称相同。

  1. 在项目中以通常的方式引入和使用该模块。

例如,在开发 my-module 模块的过程中,可以执行以下命令将该模块链接到全局环境中:

    cd path/to/my-module
    npm link

然后,在使用该模块的项目中(比如 my-app 项目)执行以下命令添加软链接:

    cd path/to/my-app
    npm link my-module

这样就可以在 my-app 项目中引入 my-module 模块并实时测试和修改其代码,而无需每次更新代码都重新打包和发布模块。

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现 配置package.json文件

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

在本地其他项目(wangzhatest)中使用

在wangzhatest根目录运行npm link wangzha-component 连接到本地项目组件库

修改wangzhatest项目根目录 package.json添加 本地组件库项目

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现 在项目中使用组件库

import {Button} from 'wangzha-component';
import 'wangzha-component/build/index.css'
export default function App() {
  return (
      <Button btnType='primary' size='large'>wangzha-component</Button>
  )
}

版本问题

npm link ../wangzhatest/node_modules/react

npm 打包发布开始

npm www.npmjs.com/signup

注册登录 npm 方式一:通过 npm 官网界面注册 方式二:通过命令行注册

备注:登录不成功切换为初始地址源 npm config set registry https://registry.npmjs.org/

npm 常用命令

  • npm whoami 检测是否登录
  • npm config ls 显示当前 npm 配置信息
  • npm adduser 注册成为 npm 用户
  • npm config set registry 链接地址 切换源地址
  • npm login 登录 npm
  • npm publish 发布

npm whoami 命令用于检查当前是否已登录 NPM,如果已登录,则会输出当前登录的用户名;如果未登录,则会提示需要先登录才能继续执行相关操作。

使用 npm whoami 的示例:

    $ npm whoami
    username

在终端中执行上述命令,如果已经登录了 NPM,则会显示输出当前的用户名。如果该命令未输出任何文本,则说明还未登录 NPM。

npm config ls 命令用于显示当前 npm 配置信息,其中包括当前使用的 registry 源等相关信息。可以通过该命令检查当前是否已切换至某个特定的 registry 源,以及在使用该源时的配置信息是什么。以下是一个示例:

    $ npm config ls
    cli configs
    registry = "https://registry.npmjs.org/"
    user-agent = "npm/7.16.0 node/v14.16.1 darwin x64"
    userconfig /Users/username/.npmrc
    

在终端中执行上述命令,会输出当前 npm 配置的详细信息,包括 registry 源等。

npm adduser 命令用于登录 NPM,以便能够发布和管理自己的模块。首次使用该命令时,系统会要求输入用户名、密码和邮箱等信息,以完成注册和登录操作。

在执行 npm adduser 命令后,会提示输入 NPM 用户名、密码和邮箱等信息,例如:

    $ npm adduser
    Username: username
    Password: 
    Email: (this IS public) username@example.com

输入完毕后,系统会将该用户信息与 NPM 注册服务进行身份验证,如果验证通过,则会创建并保存相应的用户账号信息,从而登录到 NPM。 要在命令行中登录 npm,可以使用 npm login 命令。在执行该命令时,系统会提示输入用户名、密码和邮箱等信息。

具体的流程如下:

  1. 在终端中执行以下命令以登录 NPM:
npm login
  1. 系统将提示输入 NPM 用户名、密码和邮箱等信息。按照提示逐一输入,并按下 Enter 键:
Username: your_username
Password: your_password
Email: your_email@example.com
  1. 登录成功后,系统会返回“Logged in as username on registry.npmjs.org/”的信息。

登录成功后,你就可以使用 npm 的其他命令来管理你的 npm 账户和发布包了。登录后,认证信息将被存储在~/.npmrc 文件中,你可以检查该文件来查看登录信息是否正确。

配置 package.json

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

{
  "name": "wangzha-component", //包的名字
  "version": "0.1.0",//包的版本号
  "private": false,//是否私有
  "description": "React component library",//包的描述信息
  "author": "conponent wangzha",//包的作者信息
  "main": "dist/index.js",//包的入口文件
  "nodule":"dist/index.js",//node模块的入口文件,指向的也是 dist 目录中的 index.js 文件
  "types":"dist/index.d.ts",//Typescript类型声明文件的路径,指向的是dist目录中的index.d.ts文件。
  "license": "MIT",//包的许可证,这里是MIT
  "keywords": [ //关键词数组,用于搜索
    "Component",
    "UI",
    "React"
  ],
  "homepage": "https://github.com/wsz190/wangzha-component",//包的主页地址,这里是
  "repository": {//包的代码仓库信息,类型为git,地址为
    "type":"git",
    "url":"https://github.com/wsz190/wangzha-component"
  },
  "files": [ //发布到npm时包含的文件列表,这里只包含dist目录中的文件。
    "dist"
  ],
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/classnames": "^2.3.1",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.30",
    "@types/react": "^18.2.6",
    "@types/react-dom": "^18.2.4",
    "classnames": "^2.3.2",
    "node-sass": "^7.0.3",
    "normalize.css": "^8.0.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start", //"start"命令用于启动React应用的开发服务器
    "clean":"rimraf ./dist",// "clean"命令用于移除"./dist"文件夹,确保项目构建的时候有一个干净的环境
    "build": "npm run clean && npm run build-ts && npm run build-css",// "build"命令用于构建React应用的生产版本,它会执行"clean"、"build-ts"和"build-css"这三个子命令
    "test": "react-scripts test",// "test"命令用于运行React应用的测试套件
    "eject": "react-scripts eject",// "eject"命令用于从"react-scripts"中弹出React应用,从而获得对配置和构建过程的全面控制
    "build-ts":"tsc -p tsconfig.build.json",// "build-ts"命令使用TypeScript编译器根据"tsconfig.build.json"配置文件编译"./src"目录中的文件
    "build-css":"node-sass ./src/styles/index.css ./build/index.css",// "build-css"命令使用Node.js的"node-sass"模块对"./src/styles/index.css"中的CSS文件进行预处理,并将其输出到"./build/index.css"中
    "storybook": "storybook dev -p 6006", // "storybook"命令用于在6006端口上启动Storybook开发服务器
    "build-storybook": "storybook build",// "build-storybook"命令用于构建Storybook静态文件以供部署
    "prepublish": "npm run build"// "prepublish"命令用于在发布npm包之前执行"build"命令
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest",
      "plugin:storybook/recommended"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@storybook/addon-essentials": "^7.0.12",
    "@storybook/addon-interactions": "^7.0.12",
    "@storybook/addon-links": "^7.0.12",
    "@storybook/blocks": "^7.0.12",
    "@storybook/preset-create-react-app": "^7.0.12",
    "@storybook/react": "^7.0.12",
    "@storybook/react-webpack5": "^7.0.12",
    "@storybook/testing-library": "^0.0.14-next.2",
    "babel-plugin-named-exports-order": "^0.0.2",
    "eslint-plugin-storybook": "^0.6.12",
    "prop-types": "^15.8.1",
    "storybook": "^7.0.12",
    "webpack": "^5.82.1"
  }
}

减少包体积

存在问题

当用户运行npm install命令时,package.json文件中的dependencies依赖都会被安装。将一些不必要的依赖项从dependencies移动到devDependencies可以减少打包后的代码体积,特别是对于开发环境中才需要使用的依赖项。

devDependencies中的依赖项只会在开发环境中使用,而dependencies中的依赖项则会在生产环境和开发环境中都被使用。因此,如果一个依赖项只在开发环境中被使用,就应该将其放在devDependencies中。

通常建议将不能直接为生产环境服务的依赖项(例如测试框架、构建工具)放入devDependencies中。但是,您还需要确保将运行时必需的依赖项放在dependencies中,使用户能够成功安装并运行您的应用程序。

peerDependencies

peerDependencies是指您的包与其他包的依赖关系。当您的包需要与其他包进行交互时,例如需要与特定的包进行插件扩展或者需要一个特定版本的包作为导出项目的工具链,那么您可以将这些包包含在peerDependencies中。

dependencies不同,peerDependencies并不会被安装在您的包中。而是会提醒用户安装相应版本的依赖包。当另一个开发者使用npm install安装您的包时,他们会收到一条警告信息,让他们知道必须安装指定版本的特定包,以确保您的包能够正常工作。

peerDependencies的格式与dependencies相似,但未包含版本信息。它们仅指定包名称和任何其他必需的关联数据。例如:

{
  "name": "my-package",
  "version": "1.0.0",
  
  "peerDependencies": {
    "react": "^16.0.0"
  }
  
}

在上面的例子中,my-package包依赖于React^16.0.0版本,用户安装时需要安装与此兼容的React包。通常,您将在发布插件或工具库时使用peerDependencies,以便其他开发人员与您的软件包进行交互时能够正确地安装依赖项。

git commit 前检查

eslint 配置

zh-hans.eslint.org/docs/latest…

eslint --ext是一个命令行选项,用于指定哪些文件扩展名应该被考虑为需要检查的源文件。默认情况下,eslint将检查.js文件。但有时您可能希望检查.jsx.ts.vue等其他文件扩展名。 以下是使用--ext选项将扩展名.jsx.tsx添加到eslint检查中的示例:

eslint --ext .js,.jsx,.tsx .

上面的命令将检查扩展名为.js.jsx.tsx的文件,并指定检查当前目录中所有文件。您还可以使用逗号分隔的扩展名指定多个扩展名,例如,.ts.tsx.js的组合:

eslint --ext .ts,.tsx,.js .

这将检查.ts.tsx.js扩展名的文件。 可以使用eslint --ext选项来指定任何文件扩展名,使eslint检查您认为需要检查的所有源文件。

"scripts": {
      "lint":"eslint --ext js,ts,tsx src --max-warnings 5",
}

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

这个命令是在package.json中的scripts部分定义的脚本,它使用eslint命令来检查在src文件夹中所有.js.ts.tsx文件的代码是否符合规则。--max-warnings 5选项表示,在代码检查期间允许最多出现五个警告信息。当运行npm run lint命令时,它将在您的项目中的所有源代码文件中执行eslint检查。

使用这种配置可以在开发过程中自动化检查代码,确保遵循一致的代码风格和最佳实践。如果出现任何违反规则的代码,则会向控制台输出相应的错误消息、警告信息和修复方法。这有助于提高代码质量和可读性,减少由于代码格式和规则的不一致性导致的问题。

注意,"lint":"eslint --ext js,ts,tsx src --max-warnings 5"只是一个示例,具体的配置可能会因项目需要而有所不同。

cross-env

cross-env是一个跨平台的环境变量设置工具,可以在不同的操作系统上设置环境变量,以便在项目构建和运行过程中使用。

由于不同的操作系统使用不同的命令和语法来设置环境变量,因此可能会出现在不同的操作系统上运行同一代码库时,环境变量为设置成功或者设置出错的情况。cross-env可以帮助你解决这个问题,因为它使用一种跨平台的方式来设置环境变量,在不同的操作系统上都可以顺利运行。

安装:

npm install --save-dev cross-env

以下是cross-env的一些用法示例:

{
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "start": "cross-env NODE_ENV=development nodemon server.js",
    "test": "cross-env NODE_ENV=test mocha ./test"
  }
}

在上面的示例中,cross-env用于设置NODE_ENV变量,该变量将在构建、启动和测试过程中使用。在build命令中,设置为production,在start命令中,设置为development,在test命令中,设置为test

这样做的好处是在不同的操作系统上运行项目时,环境变量能够正确地设置,并使其保持一致。

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

husky

建议:安装官方最新版本,按照官方安装步骤进行使用 github.com/typicode/hu…

  1. 安装 husky
npm install husky --save-dev

2.启用 Git 钩子

npx husky install

3.安装完成后启动 Git 钩子

npm pkg set scripts.prepare="husky install"

执行命令成功后 npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

  1. 创建钩子 要向钩子添加命令或创建一个新的钩子,请使用husky add <file> [cmd](不要忘记之前运行husky install)。
npx husky add .husky/pre-commit "npm test"
git add .husky/pre-commit
  1. 尝试提交
git commit -m "Keep calm and commit"

如果npm test命令失败,您的提交将自动中止。

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

CI CD

CI/CD是指"持续集成/持续交付"(Continuous Integration/Continuous Delivery)和"持续部署"(Continuous Deployment)。它是一种软件开发流程,旨在通过自动化来提高软件开发速度和质量。

持续集成是指在开发过程中,不断地将代码进行集成、编译、测试,以保持代码仓库处于可运行状态。通常,持续集成通过使用自动化工具来实现,这些工具可以在代码变更发生时自动执行构建和测试操作。

持续交付是指将已经通过了测试的代码,自动部署到生产环境或者一个可靠的预生产环境,以便测试人员、客户或其他人员检查其功能和性能。

持续部署是指通过自动化的方式将已通过测试的代码部署到生产环境,这样可以尽量减少人为干预,提高部署的速度和质量。

CI/CD可以帮助团队构建更好的软件,并尽可能快地将其推向市场。相较于传统的软件开发模式,CI/CD可以快速检测问题,并及时修复,保证软件交付的质量和稳定性。

npm打包发布 、自动测试 、commit提交验证、 自动发布构建实现

Travis

www.travis-ci.com/

Travis CI是一个在线的持续集成服务,可以与GitHub仓库进行集成,可以及时检测代码中的错误和问题,提高代码的质量和测试效率。通过Travis的集成,可以在代码被合并到主干之前进行持续集成和测试,并自动构建可部署的构建版本。

Travis CI可以对不同的编程语言和框架进行测试和构建,如Python、Java、Node.js、Ruby等。同时,它还支持多种持续集成的配置文件格式,如.travis.yml、.travis.json等,这些配置文件可以根据项目的需要进行自定义配置,以满足项目的需求。

使用Travis CI的好处是可以在代码提交时自动化地进行构建和测试,快速地发现和修复问题,提升了项目代码的质量。Travis CI还提供了实时的构建状态和构建日志,可以使开发者及时掌握构建的进度和问题,便于项目的管理和维护。

在项目根目录先新建.travis.yml文件

# Travis CI配置文件示例
# 指定使用Node.js作为构建环境
language: node_js
# 指定使用stable版本
node_js:
  - "stable"
# 缓存node_modules目录以加速构建
cache:
  directories:
    - node_modules
# 设置环境变量CI=true
env:
  - CI=true
# 执行npm run build-storybook命令来构建
script:
  - npm run build-storybook
# 部署到GitHub Pages上
deploy:
  provider: pages
  # 构建过程中不删除现有文件
  skip_cleanup: true
  # 在GitHub仓库的Settings页面中设置github_token环境变量,用于授权Travis CI访问你的GitHub仓库
  github_token: $github_token
  # 保留历史版本
  keep_history: true
  # 只有在master分支上进行部署操作
  on:
    branch: master

运行命令 git 提交命令