Preface:

I’ve been doing development for a while, and I’ve been looking for packages published by others on Github to use in my own projects. But I have never understood the whole process of how to make the NPM package, publish it, and finally install and use it. Taking advantage of the recent launch of the project, I just have free time to do a demo.

The latest project is Vue+ Element-UI, or make your own UI framework.

Technical selection:

Since React 16.8, Function Component has been released as an alternative to Class Component, and NPM packages have been developed. Using typescript type checking can avoid many development errors. React 16.8 + typescript + WebPack.

Initialization:

Mkdir UnnamedUI // Create a new folder namedUI as yet unnamedcdUnnamedUI NPM init // version: 0.0.1 Generates package.json fileCopy the code

A good NPM project must have a canonical readme.md document, such as elemental-UI or Antd’s readme specification. For now, initialize a readme

touch README.mdCopy the code



The ESLint specification is also essential, especially for a large NPM project where multiple teams work together, and the code specification is the main thing to increase efficiency and reduce problems. Because our project uses typescript, we add some typescript rules.

touch .eslintrc.jsCopy the code

module.exports = {    root: true,    parser:  '@typescript-eslint/parser',    extends: [        'plugin:react/recommended'.'plugin:@typescript-eslint/recommended'], // Use the recommended React code to test the plugins: ['@typescript-eslint'],    env:{        browser: true,        node: true}, Settings: {// Automatically discover the React version and regulate the React code"react": {            "pragma": "React"."version": "detect"}}, parserOptions: {// Specifies that ESLint can parse JSX syntax"ecmaVersion": 2019,        "sourceType": 'module'."ecmaFeatures":{            jsx:true        }    },    rules: {        "@typescript-eslint/no-explicit-any": "off"."quotes"A: [2,"single"], // single quotes"no-console": 0, // can not use console"no-debugger": 2, // Disable debugger"no-var": 0, // Warning to var"semi": 0, // Semicolons are not mandatory"no-irregular-whitespace": 0, // Irregular whitespace is not allowed"no-trailing-spaces": 1, // Warning if there is a space at the end of a line"eol-last": 0, // The file ends with a single line break"no-unused-vars": [2, {"vars": "all"."args": "after-used"}], // Can not be visible after the unused variables or parameters"no-underscore-dangle": 0, // The identifier cannot start or end with an _"no-alert": 2, // Disable alert Confirm prompt"no-lone-blocks": 0, // Disallow unnecessary nesting blocks"no-class-assign": 2, // Disallow class assignment"no-cond-assign": 2, // Disallow assignment statements in conditional expressions"no-const-assign": 2, // Disallows modifying variables declared by const"no-delete-var"// The delete operator cannot be used on variables declared by var"no-dupe-keys": 2, // Do not allow duplicate keys when creating object literals"no-duplicate-case": 2, // in switchcaseLabels cannot be repeated"no-dupe-args": 2, // Function arguments cannot be repeated"no-empty": 2, // The contents of the block statement cannot be empty"no-func-assign": 2, // Disallow duplicate function declarations"no-invalid-this": 0, // Disallows invalid this, only for constructors, classes, object literals"no-redeclare": 2, // Disallow repeated declarations of variables"no-spaced-func": 2, // Function calls cannot have Spaces between function names and ()"no-this-before-super": 0, // This or super cannot be used before super() is called"no-undef": 2, // No undefined variables"no-use-before-define": 2, // Cannot be used until defined"camelcase": 0, // Enforce hump naming"jsx-quotes"A: [2,"prefer-double"], // enforce consistent use of double quotes in JSX attributes (jsx-quotes)"react/display-name": 0, // Prevent the displayName from being lost in the React component definition"react/forbid-prop-types": [2, {"forbid": ["any"}], // Disallow certain propTypes"react/jsx-boolean-value": 2, // Enforce Boolean attribute symbols in JSX"react/jsx-closing-bracket-location": 1, // Verify the close parenthesis position in JSX"react/jsx-curly-spacing": [2, {"when": "never"."children": true}], // Enforce or disallow Spaces inside curly braces in JSX attributes and expressions."react/jsx-indent-props": [2, 4], // Verify the indentation of props in JSX"react/jsx-key": 2, // Verify that JSX has the key property in an array or iterator"react/jsx-max-props-per-line": [1, {"maximum": 1}], // Limits the maximum number of props on a single line in JSX"react/jsx-no-bind": 0, // Arrow functions and are not allowed in JSXbind        "react/jsx-no-duplicate-props": 2, // To prevent duplicate props in JSX"react/jsx-no-literals": 0, // Prevent the use of unwrapped JSX strings"react/jsx-no-undef": 1, // Disallow undeclared variables in JSX"react/jsx-pascal-case": 0, // Enforce PascalCase for user-defined JSX components"react/jsx-sort-props": 2, // enhance props in alphabetical order"react/jsx-uses-react": 1, // Prevents reactions from being incorrectly marked as unused"react/jsx-uses-vars": 2, // Prevent variables used in JSX from being incorrectly marked as unused"react/no-danger": 0, // Prevent the use of dangerous JSX attributes"react/no-did-mount-set-state": 0, // prevent use in componentDidMountsetState        "react/no-did-update-set-state": 1, // prevents use in componentDidUpdatesetState        "react/no-direct-mutation-state": 2, // Prevent direct variation of this.state"react/no-multi-comp": 2, // Prevent multiple component definitions per file"react/no-set-state": 0, // prevent usesetState        "react/no-unknown-property": 2, // Prevent the use of unknown DOM attributes"react/prefer-es6-class": 2, // Enforce ES5 or ES6 classes for the React component"react/prop-types": 0, // Prevent missing props validation in the React component definition"react/react-in-jsx-scope": 2, // Prevent loss when using JSX React"react/self-closing-comp": 0, // Prevents additional closing tags for components without children"react/sort-comp": 2, // enforce component method order"no-extra-boolean-cast": 0, // Disallow unnecessary bool conversions"react/no-array-index-key": 0, // Prevents array keys from being indexed in array traversals"react/no-deprecated": 1, // Do not use deprecated methods"react/jsx-equals-spacing": 2, // Enforces or disallows Spaces around equals signs in JSX attributes"no-unreachable": 1, // No code that can't be executed"comma-dangle": 2, // Object literals cannot end with commas"no-mixed-spaces-and-tabs": 0, // Do not mix TAB and space"prefer-arrow-callback": 0, // prefer the arrow callback"arrow-parens": 0, // The arrow functions are enclosed in parentheses"arrow-spacing": 0 //=> before/after parentheses}}Copy the code

touch .gitigoreCopy the code

# Mac OS.DS_Store# IDE.idea.project.vscode# Npmnode_modulesnpm - debug. Logyarn - error. Logsrc/exports. TsxexportEntry. Jsonlib/components# folderdist# automatically updated directory, Yo-rc.jsondist. cache sh.sh.cache/tmppackage-lock.jsonCopy the code

Next, create a new tsconfig.json file that specifies the root file and compilation options typescript uses to compile the project.

touch tsconfig.jsonCopy the code



Install the necessary dependencies, and note that the types defines the react package declaration file.

npm install react react-dom @types/react @types/react-dom --saveCopy the code

npm install @types/styled-components @typescript-eslint/eslint-plugin @typescript-eslint/parser awesome-typescript-loader eslint eslint-loader eslint-plugin-react html-webpack-plugin styled-components source-map-loader typescript webpack webpack-cli --save-devCopy the code

The project uses gravitation-Components to encapsulate components to add styles, but as gravitation-Components do not have typescrpt declaration files, we have to declare them manually.

mkdir typings
cdTypings mkdir styled-components touch Styled -componentsdeclare module 'styled-components';Copy the code

Initialize the webPack entry file and initialize the first component, UnButton

touch index.html
mkdir src
cd src
touch index.tsx
touch Layout.tsx
mkdir components
cd components
mkdir UnButton
cd UnButton
touch index.tsxCopy the code

  • index.html
  • src
    • component
      • UnButton
        • index.tsx
    • index.tsx
    • Layout.tsx

The project structure looks like this.

index.html:



src/index.tsx



src/layout.tsx



src/components/UnButton/index.tsx



Finally, create the webpack.config.js file



Execute webpack-dev-server –mode=development –open

The page should pop up correctly, indicating that we have successfully developed a components component UnButton in typescript+ React and introduced it successfully in our test file layout.tsx.

Export and publish:

So the UI framework that we’re going to use is going to be

import { Button } from 'antd';Copy the code

So our package should be an entry file that exports all the components. Create a new exports.tsx folder under SRC

import UnButton from './components/UnButton'

export {  UnButton}Copy the code

Create a new webpack.export.js file in the root directory



Be sure to add the LibraryTarget option to Output because webPack is a closure and cannot be imported externally.

run

webpack --config webpack.config.js --mode=production

The lib folder is generated in the root directory, and that’s what we’re publishing.

Complete the package.json file



The main field is the entry file for the external import of our NPM package

Files defines the folder we publish

use

npm login

Log in to your NPM account

npm publish

Publish to the NPM repository

Finally, you can create a New React project

npm install unnamedui

We can happily use our own NPM package

Links:

Making the address