Development tool selection

  • The package used in the development front end, the main logic code only contains JS, so choose rollup as a package tool.
  • Webpack is suitable for development projects, projects will contain images/videos/CSS, VUE and other resources, more suitable to use Webpack.

The development process

  • Initialize the project to create a reasonable directory structure
  • Set the configuration of the.editorconfig vscode unified specification based on the editor
  • Configure esLint and Pretter to unify code styles
  • Configure Babel to handle new syntax-compatible types
  • Configure the verification hooks submitted by Git
  • Normalize commit code to git repository
  • Set up development and packaging scripts
  • Add unit test JEST and write test samples
  • Complete necessary package.json fields
  • Configure the appropriate NPM script
  • Local test developed NPM package, using YALC
  • Publish packages to NPM

Initialize the project

npm init -y

{
  "name": "sumfunctionmethod"."version": "1.0.0"."description": "Release NPM package, develop demo of whole process"."main": "src/index.js"."scripts": {
    "test": "npm run dev"
  },
  "author": "shenshuai89"."license": "ISC"
}
Copy the code

Creating a directory structure

├ ─ ─ the README, md// NPM package description, installation and usage├ ─ ─ examples// Use the test case├ ─ ─ package. Json// Project structure description├ ─ ─ scripts// Script files for existing development or packaging└ ─ ─ the SRC// Store project files└ ─ ─ index. JsCopy the code

Configure the rollup development environment

  • The configuration varies depending on the development environment
  • Set the corresponding NPM script
  • Output products of different specifications: UMD, UMD. min, CJS, ESM, IIFE (Global)

Create the rollup configuration file in the scripts directory

├ ─ ─ a rollup. Config. Base. Js// Base file├ ─ ─ a rollup. Config. Dev. Js// Configuration of the development environment└ ─ ─ a rollup. Config. Prod. Js// Production environment configuration
Copy the code

rollup.config.base.js

Install the following NPM packages
// npm install -D @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-alias @rollup/plugin-replace @rollup/plugin-eslint @rollup/plugin-babel rollup-plugin-terser rollup-plugin-clear @rollup/plugin-json
import { nodeResolve } from '@rollup/plugin-node-resolve' // Resolve modules in node_modules
import commonjs from '@rollup/plugin-commonjs' // cjs => esm
import alias from '@rollup/plugin-alias' // Alias and reslove functions
import replace from '@rollup/plugin-replace'
import eslint from '@rollup/plugin-eslint'
import { babel } from '@rollup/plugin-babel'
import { terser } from 'rollup-plugin-terser'
import clear from 'rollup-plugin-clear'
import json from '@rollup/plugin-json' // Support to import JSON files directly from source code, without affecting the following
import { name, version, author } from '.. /package.json'

const pkgName = 'sumfunctionmethods'
// Add the remarks to the package file
const banner =
'/ *! \n' +
` * ${name} v${version}\n` +
` * (c) 2022-The ${new Date().getFullYear()} ${author}\n` +
' * Released under the MIT License.\n' +
' */'

export default {
  input: 'src/index.js'.// Package multiple specification products at the same time
  output: [{file: `dist/${pkgName}.umd.js`.format: 'umd'.name: pkgName,
      banner
    },
    {
      file: `dist/${pkgName}.umd.min.js`.format: 'umd'.name: pkgName,
      banner,
      plugins: [terser()]
    },
    {
      file: `dist/${pkgName}.cjs.js`.format: 'cjs'.name: pkgName,
      banner,
      plugins: [terser()]
    },
    {
      file: `dist/${pkgName}.esm.js`.format: 'es'.name: pkgName,
      banner,
      plugins: [terser()]
    },
    {
      file: `dist/${pkgName}.js`.format: 'iife'.name: pkgName,
      banner,
      plugins: [terser()]
    }
  ],
  // Note the order in which plugins are used
  plugins: [
    json(),
    clear({
      targets: ['dist']
    }),
    alias(),
    replace({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
      preventAssignment: true
    }),
    nodeResolve(),
    commonjs({
      include: 'node_modules/**'
    }),
    eslint({
      throwOnError: true.// Throw an exception and prevent packaging
      include: ['src/**'].exclude: ['node_modules/**']
    }),
    babel({ babelHelpers: 'bundled'}})]Copy the code

rollup.config.dev.js

// npm install -D rollup-plugin-serve rollup-plugin-livereload
import baseConfig from './rollup.config.base'
import serve from 'rollup-plugin-serve'
import livereload from 'rollup-plugin-livereload'

export default {
  ...baseConfig,
  plugins: [
    ...baseConfig.plugins,
    serve({
      port: 8080.contentBase: ['dist'.'examples/brower'].openPage: 'index.html',
    }),
    livereload({
      watch: 'examples/brower',}})]Copy the code

rollup.config.prod.js

// npm install -D rollup-plugin-filesize
import baseConfig from './rollup.config.base'
import filesize from 'rollup-plugin-filesize'

export default {
  ...baseConfig,
  plugins: [
    ...baseConfig.plugins,
    filesize()
  ]
}
Copy the code

Configure Babel parsing compatibility

Install depends on NPM I -d @babel/ core@babel /preset-env to add the file.babelrc.js

module.exports = {
  presets: [['@babel/preset-env', {
      // Rollupjs handles modules, so set it to false
      modules: false}]],plugins: []}Copy the code

Set esLint and Pretter to a uniform code style

Eslint verifies that code conforms to defined specifications

  • Eslint-plugin-vue: esLint plugin for vue.js (find vUE syntax errors, find incorrect directives, find offending style guides)
  • Eslint-plugin-prettier: Run A prettier ESLint rule so that prettier has higher priority and ESLint has lower priority
  • Eslint-config-prettier: Invalidate all ESLint rules that conflict with The Prettier rule and use Prettier to check code
  • @babel/eslint-parser: This parser allows validation of all Babel codes using ESLint
npm i -D eslint 

// Generate the configuration file,.eslintrc.js
npx eslint --init 
 
// Use the standard specification
npm install --save-dev eslint-plugin-import eslint-plugin-node eslint-plugin-prettier eslint-config-prettier @babel/eslint-parser

/ /. Eslintrc. Js configuration
module.exports = {
  root: true.env: {
    browser: true.es2021: true.node: true.jest: true,},extends: [
    'eslint:recommended'.// eslint
    'plugin:prettier/recommended'.// plugin-prettier
    'plugin:vue/vue3-recommended'.// plugin-vue].parserOptions: {
    parser: '@babel/eslint-parser'./ / the parser
    ecmaVersion: 'latest'.sourceType: 'module',},// Rules: {// You can also set a prettier verification rule
  // 'prettier/prettier': 'error', // Runs Prettier as an ESLint rule and reports differences
  / /},
  rules: {
    'space-before-function-paren': ['error'.'never'].semi: 0.// Do not end with a semicolon}},//.eslintignore configuration to prevent validation of packaged products
dist
node_modules
Copy the code

You can then add a run script to package.json

"scripts": {
    "lint": "eslint src"."fix": "eslint src --fix",}Copy the code

Pretter formatting code conforms to defined specifications

The installation package

npm install -D eslint-plugin-prettier prettier eslint-config-prettier
Copy the code

Adding a Configuration File

{
  "singleQuote": true."semi": false."bracketSpacing": true."htmlWhitespaceSensitivity": "ignore"."endOfLine": "auto"."trailingComma": "all"."tabWidth": 2 
}
Copy the code

Use the lint – staged

To validate code submitted to staging, Lint-staged is a tool for running Linter on Git staging files. Installation and configuration code quality tools Lint-staged can be configured for special handling of certain types of files, such as ESLint and Prettier

// Install dependencies
yarn add -D lint-staged
Copy the code
// Add the script and configuration to package.json
"scripts": {
    "lint-staged": "lint-staged",},"lint-staged": {
    // Match all the js files in the staging area and execute the command
  "src/*.{js}": [
    "prettier --write"."eslint --cache --fix"."git add"]}Copy the code

Configure the verification hooks submitted by Git

  • Husky: Trigger hooks when git commits
  • Commitlint: Performs normative validation of submitted content

Husky validates pre-commit and commit-msg hooks.

/ / install husky
yarn add husky -D
npx husky-init // Initialize the husky configuration and add the. Husky configuration file in the root directory. Initialize the pre-commit configuration
npx husky add .husky/commit-msg // Add an hooks, commit- MSG
Copy the code
  • Add NPM Run Lint-staged to pre-commit
  • Add NPM run commitlint in commit-msg

Install commitlint

// Add dependency files
yarn add @commitlint/config-conventional @commitlint/cli -D
// Add the configuration file commitlint.config.js
module.exports = { extends: ['@commitlint/config-conventional']};// Basic Settings
Copy the code

You can also customize validation rules for commitlint.config.js

module.exports = { 
  extends: ['@commitlint/config-conventional'].// Check rules
  rules: {
    'type-enum': [
      2.'always'['feat'.// New feature
        'fix'./ / repair the bug
        'docs'.// Documentation
        'style'.// Format (changes that do not affect code execution)
        'refactor'.// Refactoring (i.e. not new features, not code changes to fix bugs)
        'perf'.// Performance improvements (code changes to improve performance)
        'test'./ / test
        'chore'.// Do not modify SRC or other changes to the test file
        'revert'.// Commit before retreat
        'build' // Changes to the build process or helper tools (webpack, etc.)]],'type-case': [0].'type-empty': [0].'scope-empty': [0].'scope-case': [0].'subject-full-stop': [0.'never'].'subject-case': [0.'never'].'header-max-length': [0.'always'.72]}}Copy the code

Do git normalized commits using Commitizen

For novice commitlint users unfamiliar with the commit specification, you can add the Commitizen tool to manually generate the normalized COMMIT because of the added CommitLint validation.

Commitizen is a tool for formatting commit messages. introduce

// Tool installation
yarn add -D commitizen
Copy the code

Configuration commands

"script": {
    "commit": "git-cz"
}
Copy the code

Installation Rule package

npx commitizen init cz-conventional-changelog --yarn --dev --exact
Copy the code

The submission rule using CZ-Conventional – Changelog can be defined in the package

"config": {
    "commitizen": {
        "path": "cz-conventional-changelog"}}Copy the code

You can also create a separate.czrc file

{
  "path": "cz-conventional-changelog"
}
Copy the code

In the future, you can use NPM Run Commit, which uses the git-cz rules.

Custom Commitizen rules

  1. The first way is to modify config directly in the package
    "config": {
        "commitizen": {
            "path": "cz-conventional-changelog"."type": {
                "test": {
                    "description": "Testing custom Commitizen rules"."title": "Test custom Commitizen"}}}}Copy the code
  2. Use the CZ-Customizable tool
    • Install dependencies
    yarn add cz-customizable -D
    Copy the code
    • Add custom Commitizen to package.json usinggit-czRun the git commit command
    "config": {
        "commitizen": {
            "path": "./node_modules/cz-customizable"}}Copy the code
    • .cz-config.js, created in the root directory, to customize the commit prompt content
    module.exports = {
        types: [{value: 'feat'.name: 'Feat: New Feature' },
            { value: 'fix'.name: 'fix: fix' },
            { value: 'docs'.name: 'docs: Document changes' },
            { value: 'style'.name: 'style: code format (changes that do not affect code execution)' },
            {
            value: 'refactor'.name: 'refactor: refactoring (neither adding features nor fixing bugs)'
            },
            { value: 'perf'.name: 'PERF: Performance Tuning' },
            { value: 'test'.name: 'test: add test ' },
            { value: 'chore'.name: 'chore: Changes to the Build process or accessories' },
            { value: 'revert'.name: 'revert:   回退' },
            { value: 'build'.name: 'build: package'}].// Message step
        messages: {
            type: 'Please select submission type :'.// scope: 'Please enter the file modification scope (optional):',
            // used if allowCustomScopes is true
            customScope: 'Please enter modification scope (optional):'.subject: 'Please briefly describe submission (required):'.body: 'Please enter a detailed description (optional, to be optimized to remove, skip):'.// breaking: 'List any BREAKING CHANGES (optional):\n',
            footer: 'Please enter the issue to close :'.confirmCommit: 'Confirm submission using the above information? (y/n/e/h)'
        },
        allowCustomScopes: true.// allowBreakingChanges: ['feat', 'fix'],
        skipQuestions: ['body'.'footer'].// limit subject length, commitlint defaults to 72
        subjectLimit: 72
        }
    Copy the code

Add the JEST test tool

  • Use JEST for unit testing
  • Configure the JEST environment for ESLint
  • – Jest does not support es Module
  • Create [name].test.js under __test__ (name is the same as the filename in the source)
// Install jest dependencies
npm i -D jest
// enable support for 'es module'
npm i -D rollup-jest 

Copy the code

Set in package.json

"scripts": {"test": "jest"."test:c": "jest --coverage",},"jest": {
    "preset": "rollup-jest"
}
Copy the code

Run the NPM run test command

Run NPM run test:c to check test coverage

Complete necessary package.json fields

  • Version: version better
  • Main: the main entrance
  • The module: CJS entrance
  • Exports: Provides many types of imports
  • Unpkg: CDN address
  • Jsdelivr: CDN address
  • Files: Files included when the library is published
  • Keywords: keywords
  • Homepage: making the readme
  • Repository: repository address
  • Bugs: bug report
  • Dependencies: Library dependencies file
  • DevDependencies: Library to which development depends

Main Module Exports

Main is the main entry file for NPM packages, and when importing a package, it is actually the address file that main points to. Main is commonJS compliant and uses module.exports. Module is an ESM specification that uses import/export as the front-end specification.

If you use import to import the library, the file that initially matches module will be used instead of the file pointed to by main.

The rollup packaging tool provides a variety of packaging formats that can be set in Output.

// rollup.config.js
export default{... .output: {
    file: 'bundle.js'.format: 'iife'.// It can be AMD, CJS, ESM, IIFE, UMD, system
    name: 'MyBundle'}};Copy the code
  • Amd – Asynchronous module definition for module loaders like RequireJS
  • CJS — CommonJS, for Node and Browserify/Webpack
  • Esm – Saves the package as an ES module file, which can be passed in modern browsers
  • Iife – an auto-executing feature, suitable as
  • Umd – Common module definition, amd, CJS and IIFE all in one
  • System-systemjs loader format

Files Specifies the content of the package to be published

In the development process, there are many project files, including SRC, script, examples, dist and so on. When NPM sends a package, the actual content of the package can be set in the package.json files field. You only need to send the package with the post-construction resource dist(if necessary), and it is better not to send the source file, so that the size of the package to be downloaded during the installation can be greatly reduced.

Distinction between devDependencies and Dependencies

For day-to-day business development, there is little difference between the two, as packages for both configurations are downloaded when NPM Install or YARN is executed.

For library development, there will be a difference.

Install NPM install React to install dependencies in the React project. Install NPM install React to install dependencies in the React project. In devDependencies, you only need to download the dependencies for development.

Homepage Repository bugs

  • Homepage: Sets the git address, such as github.com/shenshuai89…
  • Repository: Sets the repository address
  • Bugs: Sets the submission address of bugs

Packages developed using yALC native tests

The final step in publishing packages to NPMJS is to do your own multi-environment testing locally. Try to make sure there are no low-level bugs. There are two common methods:

  • npm link
  • Using the YALC tool is more convenient. The underlying principle is NPM Link

NMP link using

// Run the following command in the directory where the library is currently created to create a soft link for the current library project to the local root node_modules
npm link

// Go to the directory and run the following command
npm link sumfunctionmethod
Copy the code

This allows you to normally use and test your custom libraries in your local directory. The front end can use Vite + VUe3 to build a project to test the use of ESM. Node’s require syntax allows you to create a project using the Express framework.

Yalc tools

Using this tool, you can debug in real time synchronously with the libraries you wrote. Yalc can simulate publishing NPM packages locally, storing published resources in a global store. Yalc adds packages to projects that need to be referenced. The package.json dependency table contains an additional file:.yalc/… This is the fLIE: soft link created by YALC. A yalc.lock is also created in the project root directory to ensure consistency of referenced resources. After the test, you need to delete the YALC package before it can be used normally.

// NPM:
npm i yalc -g

// Yarn:
yarn global add yalc

// Publish dependencies in the root directory of your library project
yalc publish
Copy the code
  • yalc publishPublishing depends on the local repository. This command only sends packets and does not actively push them.
  • You can use the push command when you have a newly modified package that needs to be published and pushedyalc pushQuickly update all dependencies.
  • Even if a push is not performed, it can be performed in the project being usedyalc updateThe command to update

Push command

// yalc publish --push
yalc push 
Copy the code

Add the dependent

In test items that need to be imported into the repository

// Add the yalc.lock file to the project. The package.json package name will have a project starting with file:.yalc/
yalc add [name]

You can also use XX@version to lock the version number
yalc add [name@version]
Copy the code

Lock the version to avoid the impact caused by the local push of new packages

  • –dev: Add dependencies to dependency
  • –pure: Does not affect package.json files
  • –link: import dependent packages using link mode.yalc add [name] --link
  • –workspace (OR-w) : Add dependencies to the workspace: protocol, monorepo repository

Update the rely on

All dependencies are found and updated according to yalc.lock.

yalc update
// or
yalc update [name]
Copy the code

Use this command to update dependencies separately within a use project when publish does not actively perform push.

Remove reliance on

yalc remove [name]
// or
yalc remove --all
Copy the code

Publish a package

  • First sign up for NPM Login. Unable to log in, mostly because taobao’s image is used in daily development, and NRM is needed to switch to the NPM address
    • nrm use npm
  • NPM publish publish project
  • Update package, including major, minor, and Patch updates

After the package is updated, the package needs to be sent again. NPM Version can control the version for upgrade

// You can configure scripts in package.json
"scripts": {"major": "npm version major -m 'build: update major'".// Update only large versions
    "minor": "npm version minor -m 'build: update minor'".// Update only the current version
    "patch": "npm version patch -m 'build: update patch'".// Update only minor versions
    "pub": "npm run build && npm publish --access=public"./ / release
    "pub:major": "npm run major && npm publish --access=public".// Release after update
    "pub:minor": "npm run minor && npm publish --access=public".// Release after update
    "pub:patch": "npm run patch && npm publish --access=public" // Release after update
}
Copy the code

Github address for the library

The address of the NPMJS