😶 NPM 是隨同 NodeJS 一起安裝的 javascript 包管理工具,能解決 NodeJS 代碼部署上的很多問題
發佈前的準備
註冊一個 npm 賬號
初始化項目
這裏用的是webpack-simple
,可以理解爲精簡版的vue-cli
。
如果沒有全局安裝 vue 的話,需要先安裝
cnpm i -g @vue/cli-init
然後再初始化 vue 項目,我們要寫的是一個簡單的 vue 組件,不需要依賴那麼多而龐大的配置,所以,這裏我們用簡介版本的 webapck 配置模板
vue init webpack-simple 項目名(最好去npm官網搜一下,防止重複)
創建之後的基本目錄
創建 vue 插件併發布
創建組件文件夾
舉個例子:封裝一個返回頂部的小組件
既然是封裝組件,那我們在 src 下面創建一個 plugins 文件放我們的插件,但是考慮到萬一要寫很多個的情況,當前組件的相關文件下創建一個 returnTop 文件夾,下面創建 returnTop.vue 和 index.js 先,結構變成下面這樣:
切換到當前根目錄,安裝依賴,啓動項目
cnpm install
cnpm run dev
編寫組件代碼
示例代碼
returnTop.vue
<template>
<div class="right-return-top">
<div class="return-top" @click="returnTop" v-show="topShow">
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAAHdbkFIAAAACXBIWXMAAAsSAAALEgHS3X78AAADGUlEQVR4nO2aT2vTYBzHv0/S9aKw7rJz34E5mP6zrRmOjeFgKozBcFAZwkAc6sHrttNgUBBPA5HNi5eBsJPX1k1XT9p3UF/B+g4iadI2ydI0T9P0SfX3hZDmeZI8n9/3efL8acJ0XYefJN/cICckHEfLGR3zCWB+BqjWWSfNYHBsT/O6/diZuaSamW/KvZPCRzEBH5wnPMnp2Ck5y3SE+TiruH2ZAOTQIkKXMM03WM4onYoz5K48m/4BE6kdxOEGCc/UBVXHLQmd7bYM6/cBDmv77lMjrsaNvI7t4u/RbrCaNdDmANzBbnnwTW6MDsam3W3rDzOp3vHLku55XpBec5ioJY6hIYVV6AgIYOoBvLvDQTK6ySQDZhgc+6TkTvPsOr005U/BRl7BVsG3ux6m0RxYzSpIsl+uKmji+EKJFmBBtRc8hy+Ndi/PmMCZbaCJaj04yKBxZuC2pKa4r/HZqCsmAOEA1AgJgAAIgACmaFasqftIsL3+NMxrdmz9PrL+mw0gGoymvBFuFtqo3EuJAVjPG1PyWQDXeF4cGWI0gLVct/A/Vso1XpRGguAHWMl2C2/i8480gGc9iNdlbgg+gMVMv/CzK3P1c/r91AHx9j4XRHAATVV6hZ83nEuvD5d2iHc8AHxLqQdq2jf/VenGCxhamhEAARAAAQyT8J5QtITXgGiRATFgECoyIAYMQkUGxIBBqMiAGDAIFd9L+6DS1DQY0pAZIBs2W3vZtpdcx55pjmtbOKy1xo0ajQFABcDemO95ACDQlxA8orVADBiESqwBm4U0tgqh/t4OKzGPwHpegYQaZDZrdXBNyEzDx8t2gKvHqskasJZTIFuBe48CphHHFxMzYjIGrGT7gfeHQTNYGY8gsxPXMGjmvf8WuRHRGrCYMQOXbIF3gzu7cga3XaxAwolrHtCExDRU65EZEY0BxqsUZqtxyRb4ecM/mJ1SBbLNiO61Rxxfw3EouhZgfOYnsxpktDq1+PUnXy3ulk0jJPYJ1XolGkiaCNFEiAyIAYNQkQExYBAqMiAGDEJFBsSAQaj+bwMA/AVQMPelPAquSAAAAABJRU5ErkJggg=="
/>
</div>
</div>
</template>
<script>
export default {
name: "ToolReturnTop", //決定引用組件的名稱
data() {
return {
scroll: 0,
topShow: false,
};
},
mounted() {
window.addEventListener("scroll", this.scrolls);
},
methods: {
returnTop() {
window.scroll(0, 0);
},
scrolls() {
this.scroll =
document.documentElement &&
document.documentElement.scrollTop + document.body.scrollTop;
if (this.scroll > window.innerHeight / 2) {
this.topShow = true;
} else {
this.topShow = false;
}
},
},
};
</script>
<style scoped>
/* 返回頂部 */
.right-return-top {
position: fixed;
left: 0;
right: 0;
bottom: 20px;
z-index: 9;
margin: auto;
}
/* .return-top {
width: 0.63rem;
height: 0.63rem;
z-index: 9;
margin: 0 auto;
background-color: #f9f9f9;
box-shadow: 0 0.01rem 0.05rem 0 rgba(0, 0, 0, 0.2) !important;
-webkit-box-shadow: 0 0.01rem 0.05rem 0 rgba(0, 0, 0, 0.2) !important;
border-radius: 1rem;
} */
.return-top {
width: 40px;
height: 40px;
z-index: 9;
margin: 0 auto;
background-color: #f9f9f9;
box-shadow: 0 0.01rem 0.05rem 0 rgba(0, 0, 0, 0.2) !important;
-webkit-box-shadow: 0 0.01rem 0.05rem 0 rgba(0, 0, 0, 0.2) !important;
border-radius: 1rem;
-webkit-animation: show 350ms ease-out forwards 1;
animation: show 350ms ease-out forwards 1;
}
.return-top img {
width: 100%;
height: 100%;
}
@-webkit-keyframes show {
0% {
-webkit-transform: rotate(0deg);
}
25% {
opacity: 0.5;
-webkit-transform: rotate(-3deg) translateY(-0.2rem);
}
75% {
-webkit-transform: rotate(3deg);
}
100% {
opacity: 0.9;
-webkit-transform: rotate(0deg);
}
}
@keyframes show {
0% {
transform: rotate(0deg);
}
25% {
opacity: 0.5;
transform: rotate(-3deg) translateY(-0.2rem);
}
75% {
transform: rotate(3deg);
}
100% {
opacity: 0.9;
transform: rotate(0deg);
}
}
</style>
編輯 returTop/index.js 文件,目的:將該組件作爲 Vue 插件
// sumFunction 插件對應組件的名字
import returnTop from "./returnTop";
// Vue.js 的插件應當有一個公開方法 install 。第一個參數是 Vue 構造器,第二個參數是一個可選的選項對象
// 此處注意,組件需要添加name屬性,代表註冊的組件名稱,也可以修改成其他的
returnTop.install = (Vue) => Vue.component(returnTop.name, returnTop); //註冊組件
// 標籤的方式引入
//const install = function(Vue, opts = {}) {
// Vue.component(sumFunction.name, sumFunction);
//}
/* 支持使用標籤的方式引入 Vue是全局變量時,自動install */
//if (typeof window !== 'undefined' && window.Vue) {
// install(window.Vue);
//}
export default returnTop;
此處需要注意的是 install。 Vue 的插件必須提供一個公開方法 install,該方法會在你使用該插件,也就是 Vue.use(yourPlugin)時被調用。這樣也就給 Vue 全局注入了你的所有的組件。
在src目錄下創建index.js文件,用來統一管理組件
import Vue from 'vue';
import ReturnTop from './plugins/returnTop/index.js';//返回頂部
// ...如果還有的話繼續添加
const components = [
ReturnTop,
]
//循環遍歷註冊組件,就可以向其他ui組件庫那樣,使用Vue.use()來全局使用
const install = function (Vue, opts = {}) {
components.map(component => {
Vue.component(component.name, component);
})
}
/* 支持使用標籤的方式引入 */
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
export default {
install,
ReturnTop, //在這裏多寫一次可以單獨調用,例如:Vue.use(vueutils.ReturnTop)
}
修改 package.json
{
"name": "km-vue-utils",
"description": "vue常用工具合集",
"version": "0.0.1",
"author": "SuperKM",
"license": "MIT", // 開源協議
// 採用commonJs入口文件,如果不配置,我們在其他項目中就不用import XX from XX來引用了,只能以包名作爲起點來指定相對的路徑
"main": "dist/index.js",
"jsnext:main": "src/index.js", // 採用es6模塊化入口
"private": false, // 因爲組件包是公用的,所以private爲false
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
// 指定代碼所在的倉庫地址
"repository": {
"type": "git",
"url": "https://github.com/superliebe/vueTools.git"
},
// 提交bug的地址
"bugs": {
"url": "https://github.com/superliebe/vueTools/issues"
},
// 項目官網的url
"homepage": "https://github.com/superliebe/vueTools",
"keywords": [
"vue",
"component",
"tools",
"superkm"
], // 指定關鍵字
"dependencies": {
"vue": "^2.5.11"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {
...
}
}
修改.gitignore
因爲要用 dist 文件夾,所以在.gitignore 文件中把 dist/去掉。
修改 webpack.config.js
// 原
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
}
...
}
// 新
const NODE_ENV = process.env.NODE_ENV
module.exports = {
entry: NODE_ENV == 'development' ? './src/main.js' : './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'index.js',
libraryTarget: 'umd', // 指定輸出格式
umdNamedDefine: true // 會對 UMD 的構建過程中的 AMD 模塊進行命名。否則就使用匿名的 define
}
...
}
❗ 發佈 npm 之前必須做兩件事情。
❤️ - 必須 npm run build 打包一下。
❤️ - 必須 修改 package.json 中的版本號。
發佈包到 npm
- 已經註冊過 npm 賬號,首先登陸,登陸過一次之後,就可以直接發佈
npm login --registry http://registry.npmjs.org
//適用於使用了淘寶鏡像加速的
//或者
npm login //未採用鏡像加速過
輸入賬號-密碼-郵箱後,提示 Logged in as *** on http://registry.npmjs.org/. 就是登陸成功了
- 然後直接發佈
npm publish --registry http://registry.npmjs.org
發佈成功後提示,前往自己的 npm 庫中就可以查看到剛剛發佈的 npm 包
npm 庫中
- 如果想刪除發佈的包
npm unpublish km-vuetools --force --registry http://registry.npmjs.org
npm 發佈中常見錯誤
- 409 Conflict
npm login 或者 npm adduser 時 輸入完賬號密碼郵箱後 提示 E409 Conflict 報錯 一般因爲淘寶鏡像的原因
解決方案,直接 registry 鏡像源
npm login --registry http://registry.npmjs.org
- npm ERR! 403
可能是包名已經存在,或者是郵箱未認證
使用自己發佈的包
使用 cnpm 安裝依賴
cnpm i km-vue-utils -S
在 main.js 文件 或者想要引入的文件導入
import utils from "km-vue-utils";
Vue.use(utils);
在想要引用的.vue 文件中直接寫
<!-- 該名稱由封裝組件中的name屬性決定 -->
<tool-return-top></tool-return-top>
<!--
如果想引用組件中包含的方法,給Vue.prototype屬性
Vue.prototype.$utils = utils;
在需要調用的地方直接寫
this.$utils.方法文件.方法名;
-->
😜😜😜