preface

Hello, I’m Pys. This is my first time to write an article, and I also want to record this process. I believe there are many friends who have not touched or built NPM components from 0 to 1, so I want to record my process of building. There are still many unclear and unknown places in the process. Please help to point out the mistakes and problems in the article (hand clenching fist).

I believe you have used NPM, there are a variety of packages. In our work, we have a lot of code duplicate CV, can we write one and publish it? React and WebPack react can be used to create a simple version

Note: WebPack is flexible, so you can configure your own functions or write component libraries that conform to your company’s business logic. It is also easy to integrate third-party libraries, such as ANTD. If you just want to develop a kit like LoDash, use the Rollup package.

Between you and me, this is also a very important interview question

start

1. Create a folder and initialize it

npm init or yarn init
Copy the code

A package.json file is generated with some configuration items, some of which are common here

{"name": "@panyushan/study", // NPM package name: "1.0.0", // version" main": "Lib /index.js", // entry file "license": "ISC", // license" description":" this package is used for learning ", // description of the package "author":"panyushan", // author" files": [" lib / *. Js "], / / project contains the file name of an array "keywords" : [" study ", "webpack", "react"], / / keywords, search for "repository" : {/ / warehouse address "type" of the project: "Git", "url" : "https://github.com/panyushan2019/-panyushan-study"}, "scripts" : {/ / execute the script "start" : "webpack serve --open --config ./config/webpack.dev.js", "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --config ./config/webpack.prod.js" }, "devDependencies": { }, "dependencies": { } }Copy the code

2. Create SRC and create index.js under SRC

index.js import React from "react"; Import {Button} from 'antd' const MyButton = () => {return <Button> test Button </Button>} export default MyButton;Copy the code

NPM install antd react react-dom webpack webpack-cli or yarn add antd react react-dom webpack webpack-cli

Note: The WebPack version is V5 + and the React version is V17 +. The configuration and usage of different versions vary. For version problems, see the official website

Webpack configuration

First of all, we must debug our code locally and make sure it works before we can package it for distribution. The next step is to extract the common configuration (merge using Webpack-Merge) so that we can configure and modify it uniformly, so we need to create three different configuration files.

Webpack.dev.js // Development environment webpack.prod.js // Production environment webpack.base.js // Common configurationCopy the code

1. Install plug-ins such as Babel and Loader

npm install @babel/cli @babel/core @babel/preset-env @babel/preset-react babel-loader css-loader html-webpack-plugin style-loader webpack-dev-server less less-loader
or
yarn add @babel/cli @babel/core @babel/preset-env @babel/preset-react babel-loader css-loader html-webpack-plugin style-loader webpack-dev-server less less-loader

Copy the code

Configure the. Babelrc file in the project root directory

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}
Copy the code

If you need to install loader configurations such as LESS, SASS, and TS, see the official website

2. Webpack.base.js configuration

const path = require("path"); module.exports = { module: { rules: [ { test: /\.(js|jsx)$/, use: "babel-loader", exclude: /node_modules/ }, { test: /\.tsx?$/, use: "ts-loader", exclude: /node_modules/ }, { test: /\.less$/, use: [ { loader: "style-loader" }, { loader: "css-loader", options: { modules: { mode: "local", localIdentName: "[local]__[hash:base64:5]", }, } }, { loader: "less-loader" } ] }, { test: /\.css$/i, use: ["style-loader", "css-loader"] }, { test: /\.(png|svg|jpg|jpeg|gif)$/i, type: "asset/resource" }, { test: /\.(woff|woff2|eot|ttf|otf)$/i, type: "asset/resource" } ] }, resolve: { alias: { "@": path.resolve(__dirname, ".. /src/") }, extensions: [".js", ".jsx", ".ts", ".tsx",'css','less'] } };Copy the code

3, webpack. Dev. Js

const path = require("path"); const { merge } = require("webpack-merge"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const base = require("./webpack.base.js"); module.exports = merge(base, { mode: "development", entry: { index: "./example/app.js" }, devtool: "inline-source-map", devServer: { static: path.resolve(__dirname, ".. /example") }, plugins: [ new HtmlWebpackPlugin({ title: "Development", template: path.join(__dirname, "../example/index.html"), filename: "index.html" }) ], output: { filename: "bundle.js", path: path.resolve(__dirname, ".. /example") } });Copy the code

4, webpack. Prod. Js

const path = require("path"); const { merge } = require("webpack-merge"); const common = require("./webpack.base.js"); module.exports = merge(common, { entry: { index: "./index.js" }, mode: "production", externals: { react: ReactDOM:'react-dom', antd:'antd'}, output: {filename: "[name].js", library: {name: "MyButton", type: "umd", export: 'default', }, path: path.resolve(__dirname, ".. /lib"), clean: true } });Copy the code

The relevant usage syntax can be referred to the official website without too much narration here (this article is mainly about how to build, rather than the use of API).

Note: The development environment and the production environment package different entry and output, please pay attention to the distinction

The development environment

1. Create the example folder in the root directory, create index.html and app.js, and import and mount your own components as styles

import React from "react"; import ReactDOM from "react-dom"; import MyButton from '.. /index.js'; function App() { return <MyButton />; } ReactDOM.render(<App />, document.getElementById("app"));Copy the code

Create script in package.json (don’t get tired of typing –config –open on terminal)

"scripts": {
    "start": "webpack serve --open --config ./config/webpack.dev.js"
  },
Copy the code

At this point our development environment is ok, you can debug your code and encapsulate reusable high quality components

The production environment

Create production environment script scripts in package.json

"build": "webpack --config ./config/webpack.prod.js"
Copy the code

You think this is the end?

First of all, you can’t predict whether your production package will work properly through NPM install, in case of direct submission of the release, users will find a bug in the face

Production environment testing

2. Use NPM link or YARN Link

  • Start by typing in the terminal under your component project directoryNPM link (this will help us simulate the status of the package after it is installed, it will do a shortcut mapping in the system, so that the local package can be used as if it had been installed)
  • It is then used in another empty project root terminal that can be created using scaffoldingnpm link [package-name]yarn link [package-name]
  • The above[package-name]ispackage.jsonIn thename, which is the name of the package
  • And finally in the test project(Projects created through scaffolding)Running start

This way our component library is fully developed

Published to the NPM

There are some pits waiting for you for the first time

  • First of all, you should have an NPM account, if you don’t go to the official website to register one
  • Input at terminalnpm login, and then enter the account password and email, you can usenpm whoamiTo see if you are logged in
  • Execute at terminalnpm publishAnd that’s it

1, In the test project start run error

Error : Invalid hook call . HoOkS can only be called inside of the bOdy ofa function cOmponent . This COuld happen for one of the following reasons : 1. You might have mismatching versions of React and the renderer ( such as React DOM )2. You might be breaking the Rules  of HoOKS 3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem .Copy the code

According to the official tip from React, there are multiple versions of React. This is because library A calls LIBRARY B during link, and B uses NPM link debugging, which will cause the dependency of React to appear twice. Therefore, it is necessary to link to React under A in B and restart the project. Connect the react link component library to the debug library. There is also a simple and violent way to do this: simply delete the react library from node_modules

2, NPM publish error (the following may occur, please check according to the error information)

  • NPM login is not used
  • The mirror source is not switched(If you are taobao mirror source, need to switch back)
  • Duplicate package names already exist(Change the name in package.json or use scope)
If you use @[package-name]/[package-name] as the package name you need to publish --access=publicCopy the code
  • NPM mailbox is not validated(I encountered this problem, because NPM will send an email for you to verify when registering. I didn't verify at that time, and it was invalid when I looked for it again. I just need to log in to NPM to verify again.)
  • No permission, usenpm adduserJust add

Think of these for the time being, and I will supplement them later

conclusion