vue cli4构建基于typescript的vue组件并发布到npm
基于vue cli创建一个vue项目
首先安装最新的vue cli脚手架,
npm install --global @vue/cli
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\@vue\cli\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) + @vue/cli@4.4.6
added 1230 packages from 670 contributors in 118.122s
查看安装的vue -V
@vue/cli 4.4.6
创建项目:vue create my-project-name(“my-project-name”,这个可以根据需要命名,尽量用英文)
Vue CLI v4.4.6
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, Router, Vuex, CSS Pre-processors, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with node-sass)
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? Yes
? Save preset as: ts_tmpl
创建完成之后,会出现如下提示
Running completion hooks... � Generating README.md... � Successfully created project my-project-name.
� Get started with the following commands: $ cd my-project-name
$ npm run serve
根据提示执行命令
E:\vue_codes>cd my-project-name E:\vue_codes\my-project-name>npm run serve > my-project-name@0.1.0 serve E:\vue_codes\my-project-name
> vue-cli-service serve INFO Starting development server...
Starting type checking service...
Using 1 worker with 2048MB memory limit
98% after emitting CopyPlugin DONE Compiled successfully in 5304ms 上午11:13:54 No type errors found
Version: typescript 3.9.7
Time: 3160ms App running at:
- Local: http://localhost:8080/
- Network: http://192.168.1.95:8080/ Note that the development build is not optimized.
To create a production build, run npm run build.
在浏览器输入地址:http://localhost:8080/
出现如上图所示界面,表示项目创建成功了。
生成的代码目录结构如下:
两个声明文件:shims-vue.d.ts和shims.tsx.d.ts
shims-vue.d.ts:由于 TypeScript 默认并不支持 *.vue 后缀的文件,所以在 vue 项目中引入的时候需要创建一个shims-vue.d.ts 文件,放在项目项目对应使用目录下,例如 src/shims-vue.d.ts,用来支持*.vue 后缀的文件
shims-tsx.d.ts:允许.tsx 结尾的文件,在 Vue 项目中编写 jsx 代码
tsconfig.json:
typescript配置文件,主要用于指定待编译的文件和定义编译选项
normalize.css:Normalize.css 是一个可以定制的CSS文件,它让不同的浏览器在渲染网页元素的时候形式更统一。Normalize.css是一种CSS reset的替代方案。
.browserslistrc:这个配置能够分享目标浏览器和nodejs版本在不同的前端工具。这些工具能根据目标浏览器自动来进行配置,Browserslist这个东西单独是没用的,(补充: 在vue官方脚手架中,browserslist字段会被 @babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。)
browserslist的配置文件:
> 1% 兼容全球使用率大于1%的游览器
last 2 versions 兼容每个游览器的最近两个版本
not ie <= 8 不兼容ie8及以下
具体可见 browserslist。
postcss.config.js:用于配置将px转化成rem,和自动添加CSS浏览器前缀等。
改造项目结构
这种组件项目和我们日常的项目还是有很大区别的,由于前面我采用的是vue cli创建的完整模板项目,这里许多东西用不到,我们就将其删掉,最终项目目录结构如下:
examples:是组件使用示例
src/components:是组件源码
package.json代码如下:
{
"name": "jie-echarts",
"version": "0.1.0",
"private": false,
"description": "echarts组件",
"main": "dist/JieEcharts.common.js",
"author": "zouqj<zouyujie@126.com>",
"license": "MIT",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"lib": "vue-cli-service build --target lib --name JieEcharts ./src/index.ts"
},
"dependencies": {
"core-js": "^3.6.5",
"echarts": "^4.8.0",
"ts-loader": "^8.0.1",
"vue": "^2.6.11",
"vue-class-component": "^7.2.3",
"vue-property-decorator": "^8.4.2",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@types/echarts": "^4.6.4",
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
"@vue/cli-plugin-router": "~4.4.0",
"@vue/cli-plugin-typescript": "~4.4.0",
"@vue/cli-plugin-vuex": "~4.4.0",
"@vue/cli-service": "~4.4.0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^6.2.2",
"node-sass": "^4.12.0",
"prettier": "^1.19.1",
"sass-loader": "^8.0.2",
"typescript": "~3.9.3",
"vue-template-compiler": "^2.6.11"
}
}
重点注意标红部分的配置。
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"typeRoots": ["/@types", "./node_modules/@types"],
"types": ["webpack-env"],
"paths": {
"@/*": ["src/*"]
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": ["node_modules"]
}
vue.config.js代码如下:
'use strict';
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation. const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
const resolve = (dir) => path.resolve(__dirname, dir);
module.exports = {
// 修改 src 目录 为 examples 目录
pages: {
index: {
entry: 'examples/main.ts',
template: 'public/index.html',
filename: 'index.html',
},
},
// vue 通过 file-loader 用版本哈希值和正确的公共基础路径来决定最终的图片路径,再用 url-loader 将小于 4kb 的
// 图片内联,以减少 HTTP 请求的数量。所以我们可以通过 chainWebpack 调整图片的大小限制。例如,我们将
// 图片大小限制设置为 13kb,低于13kb的图片全部被内联,高于13kb的图片会放在单独的img文件夹中。
chainWebpack: (config) => {
const imagesRule = config.module.rule('images');
imagesRule
.use('url-loader')
.loader('url-loader')
.tap((options) => Object.assign(options, { limit: 13312 }));
},
// 设置css: { extract: false },可以强制内联,就不会将css单独打包成一个文件,导致页面没有style
css: { extract: false },
productionSourceMap: false,
};
.npmignore可以将一些不需要发布到npm的文件忽略掉,.npmignore配置如下:
.*
package-lock.json
/.git/
/.vscode/
tslint.json
tsconfig.json
*.log .DS_Store
/dist
/examples
/node_modules
/public
/src
/tests
.browserslistrc
jest.config.js
vue.config.js # local env files
.env.local
.env.*.local # Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log* # Editor directories and files
.idea
.vscode
.gitignore
.npmignore
.npmrc
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
components下面
index.ts代码:
import jieEcharts from './jie-echarts.vue'; (jieEcharts as any).install = (Vue: any) => {
Vue.component(jieEcharts.name, jieEcharts);
}; export default jieEcharts;
jie-echarts.vue代码:
<template>
<!-- 每一个图表都有自己唯一的id,需要动态传入。 -->
<div :ref="id" :id="id" :class="myclass" :style="style" />
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from "vue-property-decorator";
import Echarts from "echarts";
@Component({
name: "jie-echarts"
})
export default class extends Vue {
@Prop({ default: "myCharts" }) private id!: string;
@Prop({ default: "100%" }) private width!: string;
@Prop({ default: "200px" }) private height!: string;
@Prop({ default: "echarts-line" }) private myclass!: string;
@Prop() private options!: object;
@Prop({ default: false }) private loading!: boolean; private MyEcharts: any = null; // echarts实例 created() {
console.log("this.options :>> ", this.options);
}
mounted() {
this.InitCharts();
} get style() {
return {
height: this.height,
width: this.width
};
}
@Watch("options", { deep: true })
onChangeOption(newVal: string, oldVal: string) {
if (this.MyEcharts) {
if (newVal) {
// console.log(JSON.stringify(newVal))
this.MyEcharts.setOption(newVal, true);
} else {
this.MyEcharts.setOption(oldVal, true);
}
setTimeout(() => {
this.MyEcharts.resize();
});
} else {
this.InitCharts();
}
}
@Watch("height")
onChangeHeight(val: string) {
if (val) {
this.height = val;
}
if (this.MyEcharts) {
this.MyEcharts.setOption(this.options, true);
} else {
this.InitCharts();
}
}
@Watch("loading")
onChangeLoading(val: boolean) {
if (val == true) {
this.showLoading();
}
if (val == false) {
this.hideLoading();
}
}
//-----------------------method----------------------
// 组件初始化
private InitCharts() {
const dom: any = this.$refs[this.id] as HTMLDivElement; // document.getElementById(this.id);
this.MyEcharts = Echarts.init(dom);
if (this.loading == true) {
this.showLoading();
}
/**
* 此方法适用于所有项目的图表,但是每个配置都需要在父组件传进来,相当于每个图表的配置都需要写一遍,不是特别的省代码,主要是灵活度高
* echarts的配置项,你可以直接在外边配置好,直接扔进来一个this.option
*/
this.MyEcharts.clear(); // 适用于大数据量的切换时图表绘制错误,先清空在重绘
this.MyEcharts.setOption(this.options, true); // 设置为true可以是图表切换数据时重新渲染
setTimeout(() => {
this.MyEcharts.resize();
});
// 当窗口变化时随浏览器大小而改变
window.addEventListener("resize", () => {
this.MyEcharts.resize();
});
this.MyEcharts.on("click", (params: any) => {
this.mapClick(params);
});
}
//组件单击事件
private mapClick(params: any) {
// console.log(params, 999999);
const data = {
color: params.color,
data: params.data,
dataIndex: params.dataIndex,
seriesIndex: params.seriesIndex,
chartType: params.componentSubType
};
this.$parent.$emit("chartParams", JSON.stringify(data));
if (params.seriesType == "map") {
this.$emit("mapValue", params.name);
} else {
this.$emit("eclick", params);
}
}
private showLoading() {
if (this.MyEcharts) {
this.MyEcharts.showLoading({
text: "loading"
// color: '#4cbbff',
// textColor: '#4cbbff',
});
}
}
private hideLoading() {
if (this.MyEcharts) {
this.MyEcharts.hideLoading();
}
}
}
</script>
<style lang="scss" scoped>
.echarts-line {
height: 100%;
}
</style>
@types目录下:
component.d.ts代码:
import Vue from 'vue'; export class VanComponent {
static name: string;
static install(vue: typeof Vue): void;
}
shims-vue.d.ts代码:
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
App.vue代码:
<template>
<div id="app">
<jie-echarts :options="echartsOptions"></jie-echarts>
<!-- <router-view /> -->
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch, Prop } from "vue-property-decorator";
import jieEcharts from "../src/index";
@Component({
components: {
jieEcharts
}
})
export default class TestJieEchartsPreview extends Vue {
protected echartsOptions = {
xAxis: {
type: "category",
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
},
yAxis: {
type: "value"
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: "line"
}
]
};
}
</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;
} #nav {
padding: 30px; a {
font-weight: bold;
color: #2c3e50; &.router-link-exact-active {
color: #42b983;
}
}
}
</style>
执行npm run serve,运行结果如下:
发布到NPM
3.执行npm login,进行登录
PS E:\vue_codes\my-project-name> npm login
Username: zouyujie
Password:
Email: (this IS public) zouyujie@126.com
如果你是使用的淘宝镜像,注意啊要先切换到npm官网镜像,切换方式:npm config set registry https://registry.npmjs.org/
4.执行命令 npm publish,进行发布,如果出现如下图所示错误:
说明邮箱没有绑定成功,点击https://www.npmjs.com/email-edit,进行绑定,然后重新执行npm publish,运行结果如下:
PS E:\vue_codes\my-project-name> npm publish
npm notice
npm notice package: jie-echarts@0.1.0
npm notice === Tarball Contents ===
npm notice 632B dist/index.html
npm notice 4.3kB dist/favicon.ico
npm notice 66B babel.config.js
npm notice 965.0kB dist/js/chunk-vendors.80f39f1d.js
npm notice 6.3kB dist/js/index.f9222971.js
npm notice 1.4kB package.json
npm notice 327B README.md
npm notice === Tarball Details ===
npm notice name: jie-echarts
npm notice version: 0.1.0
npm notice package size: 341.3 kB
npm notice unpacked size: 978.0 kB
npm notice shasum: 2b65bfa887ba4677dc95a36a4b0403ebfecc9fde
npm notice integrity: sha512-RwSE3lC8N3wZT[...]b1b9cvJ8UtL/w==
npm notice total files: 7
npm notice
+ jie-echarts@0.1.0
至此,npm发布成功。
然后我们去npm上,查看我们发布的npm包,
如果能看到如下图所示界面:
说明已发布成功。
注意:每次重新发布都要记得修改一下版本号,否则会发布失败。
vue cli4构建基于typescript的vue组件并发布到npm的更多相关文章
- 基于Typescript的Vue项目配置国际化
基于Typescript的Vue项目配置国际化 简介 使用vue-i18n插件对基于Typescript的vue项目配置国际化,切换多种语言, 配合element-ui或者其他UI库 本文以配置中英文 ...
- 开发自己的react-native组件并发布到npm[转]
原文链接:https://www.jianshu.com/p/091a68ea1ca7 写在前面 在做react-native开发的时候,我们经常会找到一些第三方组件,并且通过npm install的 ...
- 如何创建一个前端 React 组件并发布到 NPM
首先npm文档摆在这里: https://www.npmjs.cn/ 参考组件 https://github.com/rakuten-rex/rex-dropdownhttps://www.npmjs ...
- 教你搭建基于typescript的vue项目
自尤大去年9月推出vue对typescript的支持后,一直想开箱尝试,对于前端sr来说,vue的顺滑加上ts的面向对象,想着就非常美好~ 终于在两个月前,找到了个机会尝试了一把vue+ts的组合. ...
- 【react】使用 create-react-app 构建基于TypeScript的React前端架构----上
写在前面 一直在探寻,那优雅的美:一直在探寻,那精湛的技巧:一直在探寻,那简单又直白,优雅而美丽的代码. ------ 但是在JavaScript的动态类型.有时尴尬的自动类型转换,以及 “0 == ...
- 将 Vue 组件库发布到 npm
制作了一套自己的组件库,并发布到npm上,项目代码见 GitHub . 前期准备 有一个npm账号 安装了vue-cli 搭建项目 vue init webpack hg-vcomponents cd ...
- 基于node的前端组件包发布至nexus和npmjs
目录 目录... 3 1. 前言... 1 2. 配置... 1 2.1. 建立组件的导出模块... 1 2.2. 建立组件入口文件... 1 2.3. 配置“ng-package.json”文件.. ...
- 将自己的组件打包发布到npm
在项目中有些组件在各个项目中都会调用,那么将组件发布到npm ,用到的项目去下载,这样会省去一些不必要的麻烦. 将组件发布到npm 中的步骤 做个记录 1.项目的创建,我这里使用 vue init w ...
- 跟我一起写一个hello-world react组件并发布到npm
第一步:初始化我们的配置 $ mkdir react-hello-world $ cd react-hello-world/ $ npm init -y 修改我们的package.json文件 //p ...
随机推荐
- When Lambo with Howdoo
原文链接:https://howdoo.io/when-lambo/ 为了庆祝即将推出的革命性新社交媒体平台Howdoo以及我们令人惊喜的合作伙伴关系和社区,我们正在发起一项竞赛,以最终回答“When ...
- C++敲代码前的准备工作
#pragma GCC target("avx,sse2,sse3,sse4,popcnt") #pragma GCC optimize("O2,Ofast,inline ...
- BERT源码分析及使用方法
本文原作者:梁源 BERT (Bidirectional Encoder Representations from Transformers) 官方代码库 包含了BERT的实现代码与使用BERT进行文 ...
- P2295 MICE 网格中的DP
题目描述 分析 很好的一道网格中的\(DP\)题 我们设\(f[x][y]\)为小象到达坐标为\((x,y)\)的点时看到的最少的老鼠的数量 但是这样定义是不好转移的,因为小象可能从上面的格子转移下来 ...
- day39 进程
目录 一.进程对象的其他方法 二.僵尸进程与孤儿进程(了解) 1 僵尸进程 2 孤儿进程 三.守护进程 四.互斥锁 五.进程间通信 六.IPC机制 七.生产者消费者模型 八.线程理论 一.进程对象的其 ...
- web 部署专题(二):gunicore 并发部署(用gunicorn+gevent启动Flask项目)
转自:https://blog.csdn.net/dutsoft/article/details/51452598 Flask,webpy,Django都带着 WSGI server,当然性能都不好, ...
- 《利用Python进行数据分析》自学知识图谱-导航
项目简介 Project Brief <利用Python进行数据分析-第二版>自学过程中整理的知识图谱. Python for Data Analysis: Data Wrangling ...
- ffmpeg播放器实现详解 - 视频显示
ffplay是ffmpeg源码中一个自带的开源播放器实例,同时支持本地视频文件的播放以及在线流媒体播放,功能非常强大. FFplay: FFplay is a very simple and port ...
- bilibili自定义调整视频播放速度
自定义调整视频播放速度 在b站的播放页面,按下f12,打开控制台 在控制台中复制下面代码,想几倍速就把2.5改成你想要的播放速度 document.querySelector('video').pla ...
- Azure 提供负载均衡(一)Azure Traffic Manager 为我们的Web项目提供负载均衡
一,引言 上一篇讲到我们将自己的Net Core Web 项目部署到 Azure 的 Web App 的一项 pass 服务,假如随着项目的日益增长的访问量,之前部署到单节点的应用可能无法保证其稳定性 ...