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
- 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
- Use the CZ-Customizable tool
- Install dependencies
yarn add cz-customizable -D Copy the code
- Add custom Commitizen to package.json using
git-cz
Run 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 publish
Publishing 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 pushed
yalc push
Quickly update all dependencies. - Even if a push is not performed, it can be performed in the project being used
yalc update
The 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