前言
截止本文发布时——2020-08-13,作者也是刚学会npm如何发布自己的代码,期间走了很多弯路——即使网上有很多教程,具体原因在此略过,发表此文的初衷是希望帮助和我一样的初学者学会如何发布到npm,能力有限,有错误欢迎提出!
正文
作者技术栈为Vue、Typescript —— 均为初学,包管理工具为Yarn —— 不清楚的请百度
创建项目
- 全局安装Vue-cli脚手架
yarn global add @vue/cli
- 创建项目(具体流程略过)
vue create npm-demo
- 创建Loading组件
components
└─ Loading
index.ts
loading.vue
index.ts
//先引入loading组件
import LoadingComponent from './loading.vue'
const Loading: any = {}
Loading.install = function (Vue: any) {
// 生成一个Vue的子类 同时这个子类也就是组件
const ToastConstructor = Vue.extend(LoadingComponent)
// 生成一个该子类的实例
const instance = new ToastConstructor()
// 将这个实例挂载在我创建的div上
// 并将此div加入全局挂载点内部
instance.$mount(document.createElement('div'))
document.body.appendChild(instance.$el)
//注入vue的原型链
Vue.prototype.$loading = {
show() {
instance.show = true
},
close() {
instance.show = false
}
}
}
export default Loading
loading.vue
<template>
<div v-show="show" class="container">
<div class="loading"></div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class Loading extends Vue{
// ================= Data start =================
private show = false;
// ================= Data end =================
}
</script>
<style scoped>
.container {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.loading {
width: 100px;
height: 100px;
border-radius: 100%;
border: 5px #ffffff solid;
border-right-color: #87ceeb;
animation: loading 1s linear infinite;
}
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
在main.ts
中注册
import Loading from './components/Loading/index'
Vue.use(Loading)
在App.vue
中使用
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component({
components: {},
})
export default class App extends Vue {
private mounted(): void {
// 这里不用any会报错:Property '$loading' does not exist on type 'App'.
// 希望知道的大佬告知
(this as any).$loading.show();
}
}
</script>
yarn serve
运行下代码测试一下~
不出意外的话,应该能看到一个loading图标在转。
修改配置
上一节创建了一个项目和一个loading组件,本节开始打包前的配置
- 修改
package.json
在 scripts
字段下创建 lib
命令
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lib": "vue-cli-service build --target lib --name npm-demo --dest lib ./src/components/Loading/index.ts",
"lint": "vue-cli-service lint"
}
解释一下:--target lib
将一个单独的入口构建为一个库(打包为组件)--name npm-demo
组件的名称--dest lib
输出目录,默认为 dist./src/components/Loading/index.ts
入口文件
- 修改
tsconfig.ts
为了生成声明文件,需要加入如下的配置
compierOptions: {
...
"sourceMap": false, // 这个可以不关
"declaration": true,
"declarationDir": "lib",
...
}
- 创建
vue.config.js
module.exports = {
chainWebpack: config => {
// 为了让基于Typescript的组件生成它们的声明(.d.ts)文件
// 详情 https://github.com/vuejs/vue-cli/issues/1081
if (process.env.NODE_ENV === 'production') {
config.module.rule('ts').uses.delete('cache-loader');
config.module
.rule('ts')
.use('ts-loader')
.loader('ts-loader')
.tap((opts) => {
opts.transpileOnly = false;
opts.happyPackMode = false;
return opts;
});
}
},
// 设置css: { extract: false },可以强制内联,就不会将css单独打包成一个文件,导致页面没有style
css: { extract: false },
// 不生成SourceMap
productionSourceMap: false,
// 关闭并行打包,否则无法自动生成 `.d.ts` 文件
parallel: false
}
打包组件
运行 yarn lib
生成的目录结构如下
lib
│ demo.html
│ main.d.ts
│ npm-demo.common.js
│ npm-demo.umd.js
│ npm-demo.umd.min.js
│
└─components
└─Loading
index.d.ts
loading.vue.d.ts
作者的吐槽:个人感觉 npm-demo.umd.js
、demo.html
、npm-demo.common.js
、main.d.ts
删了也没关系,我们只要压缩后的版本就好。
可以看到 index.d.ts
、loading.vue.d.ts
已经生成了,现在我们把它们移到根目录(lib),修改后的文件目录为
lib
index.d.ts
loading.vue.d.ts
npm-demo.umd.min.js
发布准备
- 首先,你要有一个npm的账号...请读者自己百度,资料很多
- 然后,如果你使用了淘宝的镜像,需要临时切换成npm的
yarn config set registry https://registry.yarnpkg.com
- 在
lib
目录下生成package.json
yarn init
question name (lib): 组件名称
question version (1.0.0): 版本号
question description: 描述
question entry point (index.js): 入口文件
question repository url: 仓库地址
question author: 作者
question license (MIT): 许可协议
question private: 是否私有,必须为 false
- 修改
package.json
为了更好的描述我们的组件,需要修改一下
{
...
"types": "loading.vue.d.ts", // 类型声明文件入口
"keywords": [
"vue",
"vuejs",
"typescript",
"vuecli4.x"
]
}
发布组件
登录后
npm publish --access=public
如果发布失败,大概率是包名重复了,换一个
修改 package.json
的 name
为 @zeronofreya/npm-demo-2020-08-13
再次发布就可以了
结语
本文暂时告一段落,辛苦大家了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。