preface
When the mainstream component libraries in the market cannot meet our business needs, it is necessary for us to develop a set of component libraries belonging to our team. Here is a simple component to describe the development and release of Vue3.0 + TS based components from NPM repository (see Element-Plus)
The environment
The versions of the environment used in this article are listed here
- Vue 3.0
- Vue/cli 4.5.9
- NodeJs 14.15.1
- NPM 6.14.8
> vue --version@ vue/cli 4.5.9
> npm -v
6.14.8
> node -v
v14.15.1
Copy the code
steps
1. Create projects
Create a VuE3 project using vue-CLI, assuming the project name is nandit-vue-vant
> vue create nandit-vue-vant
Copy the code
Select Manually Select Features and press Enter to go to the next step
Check Choose Vue Version, Babel, TypeScript, and CSS pre-processors and press Enter to go to the next step
-
Choose a version of vue.js that you want to start the project with select 3.x (Preview)
-
Use class-style component syntax? Type n
-
Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Enter y
-
Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default) Select Sass/SCSS (with Dart-sass)
-
Where do you prefer placing config for Babel, ESLint, etc.? Select In Dedicated Config Files
-
Save this as a preset for future projects? Enter y and press Enter to save the template
Finally, press Enter and wait for the project to complete
The directory structure is shown in the figure
2. Plan directories
├ ─ the build// Edit the package script directory to store the script files│ ├─ ├.config.js ├─ docs// Document directory, used to generate vuePress document pages│ ├─.Vuepress │ ├─ Guide │ ├─.MD ├─ examples// Change the SRC directory to examples for examples│ ├─ App.vue │ ├─ Main// Add packages directory for writing and storing components such as buttons│ ├─ Button │ ├─ Index// Add typings directory for.d.ts files, move shims-vue.d.ts to this directory│ ├─ Shims-├.d.Bass Exercises ─.nPMIgnore// Add the.npmignore configuration file├ ─ vue. Config. Js// Add vue. Config. js configuration file
Copy the code
Change the SRC directory to examples, delete assets and Components, and remove component references from app. vue.
The adjusted directory structure is shown in the figure
3. Project configuration
3.1 the vue. Config. Js
The vue.config.js configuration file is added to adapt to the replanned project directory
const path = require('path')
module.exports = {
// Modify the pages entry
pages: {
index: {
entry: "examples/main.ts"./ / the entry
template: "public/index.html"./ / template
filename: "index.html" // Output file}},// Extend the WebPack configuration
chainWebpack: (config) = > {
// Add a ~ to the Packages directory for easy use in the sample code
config.resolve.alias
.set('~', path.resolve('packages'))}}Copy the code
3.2 .npmignore
The.npmignore configuration file is added. Components are published in NPM. Only compiled distribution directories (e.g. Lib), package.json, readme. md are required to be published, so we need to set the directory and files to be ignored
Idea.vscode build/ docs/ examples/ packages/ public/ node_modules/ typings/ tsconfig.json tslint.json vue.config.js .gitignore .browserslistrc *.mapCopy the code
3.3 tsconfig. Json
Modify the path in tsconfig.json
"paths": {
"@ / *": [
"src/*"]}Copy the code
Instead of
"paths": {
"~ / *": [
"packages/*"]}Copy the code
Modify the path of include
"include": [
"src/**/*.ts"."src/**/*.tsx"."src/**/*.vue"."tests/**/*.ts"."tests/**/*.tsx"
]
Copy the code
Instead of
"include": [
"examples/**/*.ts"."examples/**/*.tsx"."examples/**/*.vue"."packages/**/*.ts"."packages/**/*.tsx"."packages/**/*.vue"."typings/**/*.ts"."tests/**/*.ts"."tests/**/*.tsx"
]
Copy the code
3.4 package. Json
Modify the fields published to NPM in package.json
name
: package name, which is unique. Search for the name on the NPM website, or change the name if it exists.version
: Version number. The version number must be changed each time you release to NPM. The version number cannot be the same as the historical version number.description
: describe.main
: entry file, this field should point to our final compiled package file.typings
: types file required by the TS component.keyword
: keyword, separated by Spaces from the final search term.author
: Author Informationprivate
: Private or not, you need to change it to false to publish to NPMlicense
: Open source protocol
Reference Settings:
{
"name": "nandit-vue-vant"."version": "0.1.0 from"."private": false."description": "Vue3 + Vant based front-end component library"."main": "lib/index.min.js"."module": "lib/index.esm.js"."typings": "lib/index.d.ts"."keyword": "vue3 vant"."license": "MIT"."author": {
"name": "yourname"."email": "[email protected]"}}Copy the code
Added compile and publish commands to scripts of package.json
"scripts": {
"build": "yarn build:clean && yarn build:lib && yarn build:esm-bundle && rimraf lib/demo.html"."build:clean": "rimraf lib"."build:lib": "vue-cli-service build --target lib --name index --dest lib packages/index.ts"."build:esm-bundle": "rollup --config ./build/rollup.config.js"
}
Copy the code
Build :lib is packaged in VUe-CLI umD mode, and build: ESM-bundle is packaged in ROLLup ES mode.
--target
: Build target, default to application mode. Instead oflib
Enable library mode.--name
: Output file name--dest
: Output directory, defaultdist
. tolib
[entry]
: Entry file path. The default value issrc/App.vue
. Here we specify compilepackages/
Component library directory.
Here is a complete package.json reference example
{
"name": "nandit-vue-vant"."version": "0.1.0 from"."private": false."description": "Vue3 + Vant based front-end component library"."main": "lib/index.min.js"."module": "lib/index.esm.js"."typings": "lib/index.d.ts"."keyword": "vue3 vant"."license": "MIT"."author": {
"name": "jiuage"."email": "[email protected]"
},
"scripts": {
"serve": "vue-cli-service serve"."docs:dev": "vuepress dev docs"."docs:build": "vuepress build docs"."build": "yarn build:clean && yarn build:lib && yarn build:esm-bundle && rimraf lib/demo.html"."build:clean": "rimraf lib"."build:lib": "vue-cli-service build --target lib --name index --dest lib packages/index.ts"."build:esm-bundle": "rollup --config ./build/rollup.config.js"
},
"dependencies": {
"core-js": "^ 3.6.5." "."vue": "^ 3.0.0"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^ 13.0.5"."@vue/cli-plugin-babel": "~ 4.5.0." "."@vue/cli-plugin-typescript": "~ 4.5.0." "."@vue/cli-service": "~ 4.5.0." "."@vue/compiler-sfc": "^ 3.0.0"."rollup": "^ 2.58.0"."rollup-plugin-terser": "^ 7.0.2"."rollup-plugin-typescript2": "^ 0.30.0"."rollup-plugin-vue": "^ 6.0.0"."sass": "^ 1.26.5"."sass-loader": "^ 8.0.2." "."typescript": "~ 4.1.5." "}}Copy the code
3.5 a rollup. Config. Js
Added rollup.config.js, rollup package script
// import vue from 'rollup-plugin-vue'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import path from 'path'
// import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import typescript from 'rollup-plugin-typescript2'
import pkg from '.. /package.json'
const deps = Object.keys(pkg.dependencies)
// eslint-disable-next-line @typescript-eslint/no-var-requires
const vue = require('rollup-plugin-vue')
export default[{input: path.resolve(__dirname, '.. /packages/index.ts'),
output: [{format: 'es'.file: pkg.module,
}
],
plugins: [
terser(),
nodeResolve(),
// commonjs(),
vue({
target: 'browser'.css: false.exposeFilename: false,
}),
typescript({
tsconfigOverride: {
compilerOptions: {
declaration: true,},'include': [
'packages/**/*'.'typings/shims-vue.d.ts',].'exclude': [
'node_modules'.'packages/**/__tests__/*',]},abortOnError: false,})],external(id) {
return /^vue/.test(id)
|| deps.some(k= > new RegExp(A '^' + k).test(id))
},
},
]
Copy the code
4. Develop components
The following uses the Button component as the development example. Create the index.ts file and the Button folder under the Packages directory, and create the index.ts and SRC /button.vue under the Button, as shown in the figure
button.vue
<template>
<button class="nd-btn">
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: "nd-button"
})
</script>
<style scoped>
</style>
Copy the code
Button /index.ts, an entry file for a single component. In other projects you can use import {NdButton} from ‘nandit-vue-vant’ to reference a single component
import { App } from 'vue'
import Button from './src/button.vue'
// Define the install method with App as an argument
Button.install = (app: App): void= > {
app.component(Button.name, Button)
}
export default Button
Copy the code
Index. ts acts as an entry file to the component library. You can import the entire component library in main.ts of other projects, as shown below
import { App } from 'vue'
import NdButton from './button'
// List of all components
const components = [ NdButton ]
// Define the install method with App as an argument
const install = (app: App): void= > {
// Iterate over registered components
components.map((component) = > app.component(component.name, component))
}
export {
NdButton
}
export default {
install
}
Copy the code
Now that we have a simple Button component, we need to extend the other components by following the structure of the button and adding them to the components list in the index.ts file.
5. Write examples
After the components are developed, we test them locally and release them to the NPM repository if there are no problems. Reference our component library in the sample entry main.ts
import { createApp } from 'vue'
import App from './App.vue'
import NanditVue from '~/index' // Here ~ is the packages path configured in tsconfig.json and vue.config.js
const app = createApp(App)
app.use(NanditVue)
app.mount('#app')
Copy the code
App.vue deletes the HelloWorld component initialized by the project
<template> <div> Component example </div> <div>{{count}}</div> < nd-button@click ="handleClick"> button </nd-button> </template> <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ name: 'App', components: { }, data() { return { count: 0 } }, methods: { handleClick() { this.count ++ } } }); </script> <style lang="scss"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>Copy the code
Start the project and test it out
> yarn serve
Copy the code
6. Publish components
Once the component is developed and tested, it can be published to the NPM repository for use by other projects, starting with the compile library command to generate the lib directory
> yarn build
Copy the code
6.1 Release to NPM official website
6.1.1 Registering an NPM Account
Go to the official website to register an NPM account. If you have already registered, skip this step
6.1.2 Logging In to the NPM Account
Log in to the NPM account in the terminal command window of the project
> npm login
Username:
Password:
Email:(this IS public)
Copy the code
Enter your account, password, and email address registered with NPM
Also 6.1.3 release
Make sure registry is registry.npmjs.org
> npm config get registry
Copy the code
If not, modify Registry first
> npm config set registry=https://registry.npmjs.org
Copy the code
And then execute the command
> npm publish
Copy the code
To delete published components (it is not recommended to delete published components), run the following command (plus –force forcible deletion) :
> npm unpublish --force
Copy the code
Delete packages for the specified version, such as nandit-vue-vant version 0.1.0
>NPM unpublish [email protected]
Copy the code
If a component package with the same name has been deleted within 24 hours, the release will fail, prompting
npm ERR! code E403
npm ERR! 403 403 Forbidden - PUT https://registry.npmjs.org/nandit-vue-vant - nandit-vue-vant cannot be republished until 24 hours have passed.
npm ERR! 403 In most cases, you or one of your dependencies are requesting
npm ERR! 403 a package version that is forbidden by your security policy.
npm ERR! A complete log of this run can be found in:
npm ERR! D:\tools\nodejs\node_cache\_logs\2021-10-18T09_58_58_933Z-debug.log
Copy the code
Only publish under a different name or after 24 hours, so do not delete published components (in case a project is already referenced)
6.2 Publishing to NPM Private server
6.2.1 Nexus builds NPM private server
Set up NPM private server using Nexus (here using Nexus2) and assign publishing accounts. Please refer to another article “Set up NPM private server using Nexus2” for details.
6.2.2 Modifying the NPM Registry
Registry corresponds to the path of the NPM group of nexus
> npm config set registry=http://nexus.xx.com/nexus/content/groups/npm-group
Copy the code
6.2.3 Configuring advertising Accounts
Modify.npmrc file (C:\Users\ username \. NPMRC), add email, always-auth, _auth at the end of the file
registry=http://nexus.xx.com/nexus/content/groups/npm-group
[email protected]
always-auth=true
_auth=dGVzdDp0ZXN0MTIz
Copy the code
Description:
_auth=dGVzdDp0ZXN0MTIz is the base64 encoding of the release account: password (such as test:test123), which can be done online in the rookie tool
Note:
NPM private server built by Nexus2 needs to be published in configuration. NPMRC mode. If you use NPM login mode, error 401 will occur, which is very troublesome.
6.2.4 release
After configuring NPM Registry and publishing account information, execute NPM publish –registry nexus.xx.com/nexus/conte… Registry is a Hosted type repository on the NPM private server
> npm publish --registry http://nexus.xx.com/nexus/content/repositories/npm-hosted/
Copy the code
You can also configure publishConfig in package.json
"publishConfig": {
"registry": "http://nexus.xx.com/nexus/content/repositories/npm-hosted/"
}
Copy the code
Note:
registry
Need tohosted
Type,Can’t bepublic
registry
The address ends with a slash (/
)Don’t omit- The NPM private server library built by Nexus2 does not support the @scope publishing mode. For example, @vue/vue-form can only be used as the component publishing name. Otherwise, an error 400 will be reported
- The NPM private server library built by Nexus2 does not support unpublish
7. Test
Create another test project, VUe-Demo
7.1 check the registry
> npm config get registry
Copy the code
The value is generally set to registry.npmjs.org. If the NPM private server is installed by nexus, set it to the public address of the private server, for example, nexus.xx.com/nexus/conte…
7.2 test the install
To test whether the NPM private server can properly install dependencies on the agent library, select a vue project, delete the node_modules directory, and install again
>Yarn // Or use yarn install; Or NPM i.
Copy the code
If you can install vue, element-UI and core-js, you can use the NPM private server library
Then test the components we publish
>Yarn add nandit-vue-vant // Or use NPM i-s nandit-vue-vant
Copy the code
See if package.json and node_modules have nandit-vue-vant data and packages, then reference components in main.ts and app. vue (similar to the code in the example), start the project, and the test passes, This will make our component library available to other projects.
The last
Gitee project source code: Nandit-vue-vant
There are deficiencies in writing, please god not hesitate to give advice, thank you! Welcome to explore VUE!