最近要开发一个小程序,为了降低学习成本,最后还是选择使用uniapp来开发,但是由于电脑性能不行,实在不想多跑一个应用程序,就简单搭建了一个可以用vscode跑的uniapp项目。
项目整体技术栈:vue3 + pinia + typescript + sass + unocss + vite5
基础框架
1、使用 uniapp官网中的Vue3/Vite版:
bash
npx degit dcloudio/uni-preset-vue#vite-ts uni-preset-vue-vite-ts
如果创建失败,可以直接下载模板
基础项目下载/安装完以后,目录如下:
我们可以看一下package.json文件中,有很多默认的依赖包:
由于我们仅需要发布微信小程序端,所以将其他没用的包都删掉:
在项目根目录下安装依赖包:
npm install
2、其他依赖包安装
另外安装了其他需要的依赖包,例如pinia、sass、unocss等等。
1)pinia ------ 全局状态管理
项目一些数据需要持久化,配套安装pinia-plugin-persistedstate,不需要可以不安装。
npm install pinia pinia-plugin-persistedstate
安装完以后在项目src
文件夹下新建文件夹store
,store
文件夹下新建文件index.ts
和 user.ts
:
然后按官网使用即可:
ts
// index.ts
import { createPinia } from 'pinia'
import { createPersistedState } from 'pinia-plugin-persistedstate' // 数据持久化
const store = createPinia()
store.use(
createPersistedState({
storage: {
getItem: uni.getStorageSync,
setItem: uni.setStorageSync,
},
}),
)
export default store
// 模块统一导出
export * from './user'
ts
// user.ts
import { defineStore } from 'pinia'
import { ref } from 'vue'
const initState = {
account: '',
name: '',
phone: '',
token: '',
}
export const useUserStore = defineStore(
'user',
() => {
// 初始化
const userInfo = ref<IUserInfo>({ ...initState })
// 设值
const setUserInfo = (val: IAccountInfo) => {
userInfo.value = val
}
return {
userInfo,
setUserInfo,
}
},
{
persist: true,
},
)
2)、sass ------ css预编译
css
npm install sass --save-d
3)、postcss ------ CSS转换
配套安装postcss-html 可以将html文件中的样式块中的CSS代码提取出来进行处理,还有postcss-scss可以将sass代码转换成CSS代码
css
npm install postcss postcss-html postcss-scss --save-d
在manifest.json中配置:
本项目和stylelint配套食用,其他具体配置见👇
4)、stylelint ------ CSS代码检查工具
包名 | 作用 |
---|---|
stylelint | CSS代码检查工具 |
stylelint-config-html | html文件-样式代码检查 |
stylelint-config-recommended | 样式代码检查配置插件(比stylelint-config-standard更加宽松) |
stylelint-config-recommended-scss | SCSS语法检查 |
stylelint-config-recommended-vue | vue文件-样式代码检查 |
stylelint-prettier | 样式代码检查和格式化工具 |
lua
npm install stylelint stylelint-config-html stylelint-config-recommended stylelint-config-recommended-scss stylelint-config-recommended-vue stylelint-prettier --save-d
在项目根目录下新建文件.stylelintrc.cjs
cjs
module.exports = {
root: true,
extends: [
'stylelint-config-recommended',
'stylelint-config-recommended-scss',
'stylelint-config-recommended-vue/scss',
'stylelint-config-html/vue',
'stylelint-config-recess-order',
],
plugins: ['stylelint-prettier'],
overrides: [
// 扫描 .vue/html 文件中的<style>标签内的样式
{
files: ['**/*.{vue,html}'],
customSyntax: 'postcss-html',
},
{
files: ['**/*.{css,scss}'],
customSyntax: 'postcss-scss',
},
],
// 自定义规则
rules: {
'prettier/prettier': true,
// 允许 global 、export 、v-deep等伪类
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['global', 'export', 'v-deep', 'deep'],
},
],
'unit-no-unknown': [
true,
{
ignoreUnits: ['rpx'],
},
],
// 小程序不能识别page标签
'selector-type-no-unknown': [
true,
{
ignoreTypes: ['page'],
},
],
// never|always|always-multi-line|never-multi-line
'comment-empty-line-before': 'never',
'custom-property-empty-line-before': 'never',
'no-empty-source': null,
'comment-no-empty': null,
'no-duplicate-selectors': null,
'scss/comment-no-empty': null,
'selector-class-pattern': null,
'font-family-no-missing-generic-family-keyword': null,
},
}
在项目根目录下新建文件.stylelintignore
,忽略一些不用检查的文件
bash
src/uni_modules/
5)、unocss ------ css原子化
配套安装unocss-applet
使用小程序预设
css
npm install unocss unocss-applet --save-d
在项目根目录下新建文件uno.config.ts
ts
// uno.config.ts
import {
type Preset,
defineConfig,
presetUno,
presetAttributify,
presetIcons,
transformerDirectives,
transformerVariantGroup,
} from 'unocss'
import { presetApplet, presetRemRpx } from 'unocss-applet'
const isMp = process.env?.UNI_PLATFORM?.startsWith('mp') ?? false
const presets: Preset[] = []
if (isMp) {
// 使用小程序预设
presets.push(presetApplet(), presetRemRpx())
} else {
presets.push(
// 非小程序用官方预设
presetUno(),
// 支持css class属性化
presetAttributify(),
)
}
export default defineConfig({
presets: [
...presets,
// 支持图标,需要搭配图标库,eg: @iconify-json/carbon, 使用 `<button class="i-carbon-sun dark:i-carbon-moon" />`
presetIcons({
scale: 1.2,
warn: true,
extraProperties: {
display: 'inline-block',
'vertical-align': 'middle',
},
}),
],
/**
* 自定义快捷语句
* @see https://github.com/unocss/unocss#shortcuts
*/
shortcuts: [
['center', 'flex justify-center items-center'],
['x-between', 'flex justify-between items-center'],
['b-b-s-1', 'b-b-1 b-b-solid b-b-#e5e5e5'],
['column', 'flex flex-col'],
['p-page', 'p-20rpx pb-40rpx'],
],
transformers: [
// 启用 @apply 功能
transformerDirectives(),
// 支持变体组功能,例如<div class="hover:(bg-gray-400 font-medium)"></div>
transformerVariantGroup()
],
rules: [
['pt-safe', { 'padding-top': 'env(safe-area-inset-top)' }],
['pb-safe', { 'padding-bottom': 'env(safe-area-inset-bottom)' }],
],
})
6)、unplugin-auto-import ------ 自动引入
arduino
npm install unplugin-auto-import --save-d
在vite.config.ts
中配置:
php
import AutoImport from 'unplugin-auto-import/vite'
// 其他配置省略,在plugins中配置自动引入
defineConfig({
plugins:[
AutoImport({
imports: ['vue', 'uni-app'],
// 自动引入生成文件的位置
dts: 'src/types/auto-import.d.ts',
// 可以自动导入 hooks
// dirs: ['src/hooks'],
// 如果配置了eslintrc
// eslintrc: { enabled: true },
vueTemplate: true, // default false
}),
]
})
7)、其他
包名 | 作用 |
---|---|
@uni-helper/uni-types | uniapp中的类型定义 |
@uni-helper/vite-plugin-uni-manifest | 使用 TypeScript 编写 uni-app 的 manifest.json |
@uni-helper/vite-plugin-uni-pages | 使用 TypeScript 编写 uni-app 的 pages.json |
sql
npm install @uni-helper/uni-types @uni-helper/vite-plugin-uni-manifest @uni-helper/vite-plugin-uni-pages --save-d
按装以后,在项目根目录下新建manifest.config.ts
和pages.config.ts
php
// manifest.config.ts
import { defineManifestConfig } from '@uni-helper/vite-plugin-uni-manifest'
import path from 'node:path'
import { loadEnv } from 'vite'
// 获取环境变量的范例
const env = loadEnv(process.env.NODE_ENV!, path.resolve(process.cwd(), 'env'))
const {
VITE_APP_TITLE,
VITE_UNI_APPID,
VITE_WX_APPID,
VITE_APP_PUBLIC_BASE,
VITE_FALLBACK_LOCALE,
} = env
export default defineManifestConfig({
name: VITE_APP_TITLE,
appid: VITE_UNI_APPID,
description: '',
versionName: '1.0.0',
versionCode: '100',
transformPx: false,
locale: VITE_FALLBACK_LOCALE, // 'zh-Hans'
h5: {
router: {
base: VITE_APP_PUBLIC_BASE,
},
},
/* 小程序特有相关 */
'mp-weixin': {
appid: VITE_WX_APPID,
setting: {
urlCheck: false,
postcss: true,
es6: true,
minified: true,
},
usingComponents: true,
optimization: {
subPackages: true,
},
lazyCodeLoading: 'requiredComponents',
scopedSlotsCompiler: 'augmented',
},
uniStatistics: {
enable: false,
},
vueVersion: '3',
})
php
import { defineUniPages } from '@uni-helper/vite-plugin-uni-pages'
import path from 'node:path'
import { loadEnv } from 'vite'
// 获取环境变量的范例
const env = loadEnv(process.env.NODE_ENV!, path.resolve(process.cwd(), 'env'))
const { VITE_APP_TITLE } = env
export default defineUniPages({
easycom: {
autoscan: true,
custom: {
'^Cus(.*)': '@/components/Cus$1.vue',
'^u-(.*)': 'uview-ui/components/u-$1/u-$1.vue',
},
},
pages: [
{
path: 'pages/home/Index',
type: 'home',
style: {
navigationStyle: 'custom',
enablePullDownRefresh: false, //当前页
disableScroll: true,
navigationBarTitleText: VITE_APP_TITLE,
},
},
{
path: 'pages/sign/Index',
style: {
navigationStyle: 'custom',
enablePullDownRefresh: false, //当前页
disableScroll: true,
navigationBarTitleText: '',
},
},
],
subPackages: [
{
root: 'pages-sub',
pages: [
{
path: 'order/Index',
style: {
navigationStyle: 'custom',
enablePullDownRefresh: false, //当前页
disableScroll: true,
},
}
],
},
],
preloadRule: {
'pages/home/Index': {
network: 'all',
packages: ['pages-sub'],
},
},
})
tsconfig.json
中增加@uni-helper/uni-types
配置:
json
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"noImplicitThis": true,
"allowSyntheticDefaultImports": true,
"allowJs": true,
"sourceMap": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"outDir": "dist",
"lib": ["esnext", "dom"],
"types": [
"@dcloudio/types",
"@uni-helper/uni-types",
]
},
"vueCompilerOptions": {
"target": 3,
"plugins": ["@uni-helper/uni-types/volar-plugin"]
},
"exclude": ["node_modules"],
"include": [
"src/*.ts",
"src/**/*.ts",
"src/**/*.js",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.jsx",
"src/**/*.vue",
"src/**/*.json"
]
}
这里有一个常见错误,如果项目在vscode中提示类型"IntrinsicElements"上不存在属性"template"错误,那么需要将vueCompilerOptions.target设置成"auto"。
除此之外还可以安装eslint,老生常谈就不赘述了,源代码中默认安装了,不需要可以删除。
环境变量配置
在项目根目录下创建文件夹env
:
每个文件中定义各自环境变量,公共不需要区分环境的放到.env
中。 然后在vite.config.ts中配置:
好啦,这样基础框架就搭建好了,总体来说分为三步:
- 从官网安装基础模版
- 将package.json中不需要的依赖删除
- 安装其他依赖,例如pinia、sass、unocss以及开发规范和格式化等插件,然后根据不同的插件进行配置。