pnpm
https://pnpm.io/zh/installation
支持monorepo 单一仓库, 当前项目只能使用当前项目的包, 不可使用其依赖依赖的包1
使用pnpm, 依赖包将被存放在一个统一的位置
硬链接 (安装包时启用): 多个文件夹平等的共享同一个存储单元 (就算删除其中一个,仍可通过其他文件夹访问)
软链接: 其他文件或目录的引用
mklink /H new source
跨磁盘会报警告 ==cross-device link not permitted==, 包存储应与安装的位置处于同一驱动器和文件系统上,否则,包将被复制,而不是被链接。 这是由于硬链接的工作方式带来的一个限制,因为一个文件系统上的文件无法寻址另一个文件系统中的位置。
如果您在磁盘
A
上执行pnpm install
,则 pnpm 存储必须位于磁盘A
。 如果 pnpm 存储位于磁盘B
,则所有需要的包将被直接复制到项目位置而不是链接。 这个严重的抑制了 pnpm 的存储和性能优势。
安装pnpm
npm install -g pnpm
config get registry
pnpm set registry https://registry.npm.taobao.org
# https://registry.npmjs.org/
pnpm config set store-dir E:/.pnpm-store# 修改默认仓库地址
pnpm store path # 获取包仓库地址(pnpm的仓库不能跨磁盘)
pnpm store prune # 从store中删除当前未被(硬连接)引用的包来释放store的空间
比较
https://pnpm.io/zh/feature-comparison
npm命令 | pnpm等价命令 |
---|---|
npm install | pnpm install 安装全部依赖 |
npm install 包名 | pnpm add (-D) 包名 |
npm uninstall 包名 | pnpm remove 包名 |
npm run 脚本 | pnpm 脚本 |
集成eslint
依赖
pnpm create vite@latest vue3 --template vue
# 继承 校验import vue
pnpm add -D eslint eslint-config-airbnb-base eslint-plugin-import eslint-plugin-vue vite-plugin-eslint
# vite-plugin-eslint可在控制台打印错误信息 注册插件
import eslint from 'vite-plugin-eslint';
eslint({ cache: false })
集成stylelint
- 关闭vue的校验, 暂时有bug
依赖引入
需要在IDE[集成开发环境]里面配置stylelint 开启vue scss css 的规范检查
pnpm create vite@latest proj --template vue ; cd proj ; pnpm install
# 给css加前缀等适应操作 安装postcss
pnpm add -D autoprefixer postcss
# 校验css
pnpm add -D stylelint stylelint-config-standard stylelint-config-recommended vite-plugin-stylelint
# 使用scss和 scss lint 需要在IDE stylelint加上支持scss文件
pnpm add -D sass stylelint-config-standard-scss
import stylelint from 'vite-plugin-stylelint';
stylelint()
postcss
当前目录新建 postcss.config.js
pnpm add -D autoprefixer postcss
export default {
plugins: {
autoprefixer: {}
},
};
// 测试并打印 会自动加上前缀
::placeholder {
color: gray;
}
自动化
依赖
pnpm create vite@latest vue3-template --template vue ; cd vue3-template ; pnpm install
pnpm add -D unplugin-auto-import unplugin-vue-components vite-plugin-vue-setup-extend
# https://www.npmjs.com/package/unplugin-auto-import
import Components from 'unplugin-vue-components/vite'
Components({ /* options */ }),
import AutoImport from 'unplugin-auto-import/vite';
AutoImport({ imports: ['vue'], dts:"config/auto-import.d.ts"})
Css UI框架
pnpm add -D @tailwindcss/line-clamp postcss-nesting tailwindcss postcss-import
Svg配置
pnpm add -D vite-plugin-svg-icons
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
createSvgIconsPlugin({
iconDirs: [resolve(process.cwd(), 'src/icons/svg')],
symbolId: 'icon-[dir]-[name]',
svgoOptions: false
})
import 'virtual:svg-icons-register';
import svgIcon from '@/icons/svg-icon.vue';
app.component('svg-icon', svgIcon);
element plus
pnpm add element-plus
打包运行
npm install -g serve serve -s dist --debug
或者 vite preview
其他依赖
# 给setup语法加 name
pnpm add -D vite-plugin-vue-setup-extend
# 清除console
pnpm add -D vite-plugin-remove-console
# 打包显示进度条 https://blog.csdn.net/gongjin2012/article/details/125333102
pnpm add -D vite-plugin-progress
# 打包报告
pnpm add -D rollup-plugin-visualizer
# gzip压缩
pnpm add -D vite-plugin-compression
#兼容IE
pnpm add -D @vitejs/plugin-legacy
// import legacy from '@vitejs/plugin-legacy';
// legacy({
// targets: ['ie >= 11'],
// additionalLegacyPolyfills: ['regenerator-runtime/runtime']
// })
# hooks api
pnpm add @vueuse/core
# VueI18n
pnpm add vue-i18n #必须安装 前置依赖
pnpm add -D @intlify/vite-plugin-vue-i18n
// 默认仅支持 组合式api
VueI18n({ include: [resolve(__dirname, '../locales/**')],})
// use
import { createI18n } from 'vue-i18n';
import messages from '@intlify/vite-plugin-vue-i18n/messages';
const i18n = createI18n({
locale: 'en',
fallbackLocale: 'en',
messages,
});
// 使用 locale可改变其值与文件名相等
const { locale, t } = useI18n();
# mock 数据
pnpm add -D vite-plugin-mock
#swiper https://www.swiper.com.cn
pnpm add swiper # :watchOverflow="false"单页面生效
# 全屏混动
pnpm add vue-fullpage.js
# 美化基本html
pnpm add animate.css hover.css normalize.css
# ui
pinia
cnpm install --save axios@0.18.1 #请求发送
cnpm install --save vue-router@3.0.6 #路由
cnpm install --save-dev plop@2.3.0 #代码生成
cnpm install --save nprogress@0.2.0 #进度条
cnpm install --save path-to-regexp@2.4.0 # 匹配路由路径表达式工
cnpm install --save video.js
cnpm install --save js-cookie
cnpm install file-saver --save #文件保存
cnpm install --save jszip #压缩
cnpm install --save xlsx #excel
vite功能特性
依赖构建
/*
依赖预构建 全代码抛弃require
1. vite将CommonJS或UMD发布的依赖项转换为 ESM 的语法规范 (esbuild实现), 放到node_modules/.vite/deps
2. 路径问题 , 强制 Vite 重新构建依赖,你可以用 --force 命令行选项启动开发服务器
3. 网络多包传输时, Vite 将有许多内部模块的ESM依赖关系转换为单个或几个模块, 只需要一个HTTP请求
4. @type import('vite').UserConfig 类型注释
*/
环境变量/全局常量
/*
环境变量/dotenv 定义常量define
1. mode 通过 --mode 指定
2. 在js中 使用 import.meta.env.VITE_xxx 使用环境变量
3. define: { NUM: JSON.stringify(1) }
*/
静态资源
配置jsconfig.json 以识别 @
/* 静态资源 1. 类似与babel, postcss主要工作是转议 2. 在js中 使用 import.meta.env.VITE_xxx 使用环境变量 3. define: { NUM: JSON.stringify(1) } */
CSS
/*
css
1. 类似与babel, postcss主要工作是转议
2. 在js中 使用 import.meta.env.VITE_xxx 使用环境变量
3. 较小的资源体积小于 assetsInlineLimit 选项值 则会被内联为 base64 data URL
*/
修改源码无效
- –force 刷新.vite缓存
SCSS
:deep()
::v-deep 弃用
:deep(.el-progress__text) { }
https://blog.jetbrains.com/webstorm/2022/10/webstorm-2022-2-3/
修改css var
const el = ref(null);
const cssVar = useCssVar('--el-color-primary', el);
// 等同于
const el = document.documentElement;
getComputedStyle(el).getPropertyValue('--el-color-primary')
/**
1. 当属性--primary不存在时 默认 #d060d0
2. 设置属性: document.getElementById('app').style.setProperty('--primary', 'red');
2. 获取属性: document.getElementById('app').style.getPropertyValue('--primary')
3. 通过以上方法设置主题
*/
$primary: var(--el-color-primary);
filewatcher
npm install -g sass
可使用 在项目的index.scss 下可查看编译好的源码
其他语法
!default //降低scss变量优先级
!global // 表示就用此值
map.deep-merge https://www.sasscss.com/documentation/modules/map
主题定制
Vue3语法
props
// defineProps无需 import 导入
const props = defineProps({
iconClass: {
type: String,
required: true
}
});
const iconName = computed(() => `#icon-${props.iconClass}`);
ref reactive
- ref用于基本数据类型响应式 , 原理是
reactive 用于对象数组类型的响应式
torefs
解构props
defineExpose
子组件传值给父组件
// 子组件 tree const handleNodeClick = () => { console.log('要执行的方法') } //将方法暴露出 defineExpose({ handleNodeClick}) // 父组件 通过ref <tree :show="show" ref="treeRef"> </tree> const treeRef = ref() const handleClick = () => { //获取ref中的子组件方法handleNodeClick() treeRef.value.handleNodeClick() }
依赖注入
可以是响应式的
provide('state', state); const inj = inject('state');
globalProperties
const app = createApp(App);
app.config.globalProperties.$user = {
name: '梅长苏',
weapons: '长剑',
title: '刺客'
}
<p>姓名:{{$user.name}} </p>
const { proxy } = getCurrentInstance()
console.log(proxy.$user)
getCurrentInstance
获取当前组件实例
const { proxy } = getCurrentInstance() console.log(proxy.$user)
数组的响应式
const state = ref([])
state.value = [1, 2, 3]
const state = reactive({
arr: []
});
state.arr = [1, 2, 3]
工具
节流
const debouncedFn = useDebounceFn((entries) => {
const entry = entries[0];
const { width } = entry.contentRect;
console.log('output=>', width);
}, 1000);
useResizeObserver(app, debouncedFn);
refs替代
<full-page class="full-page-view" ref="fullPageView">
const fullPageView = ref();
const changeTab = (index) => {
tabIndex.value = index;
fullPageView.value.api.moveTo(index + 1);
};
vue3开发uniapp
版本问题
- npm update 无法解决 去main.fest 增加忽略