使用uniapp开发微信小程序-框架搭建

最近要开发一个小程序,为了降低学习成本,最后还是选择使用uniapp来开发,但是由于电脑性能不行,实在不想多跑一个应用程序,就简单搭建了一个可以用vscode跑的uniapp项目。

项目整体技术栈:vue3 + pinia + typescript + sass + unocss + vite5

基础框架

1、使用 uniapp官网中的Vue3/Vite版:

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.tsuser.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预编译

npm install sass --save-d

3)、postcss ------ CSS转换

配套安装postcss-html 可以将html文件中的样式块中的CSS代码提取出来进行处理,还有postcss-scss可以将sass代码转换成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 样式代码检查和格式化工具
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,忽略一些不用检查的文件

src/uni_modules/

5)、unocss ------ css原子化

配套安装unocss-applet使用小程序预设

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 ------ 自动引入

npm install unplugin-auto-import --save-d

vite.config.ts中配置:

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-appmanifest.json
@uni-helper/vite-plugin-uni-pages 使用 TypeScript 编写 uni-apppages.json
npm install @uni-helper/uni-types @uni-helper/vite-plugin-uni-manifest @uni-helper/vite-plugin-uni-pages --save-d

按装以后,在项目根目录下新建manifest.config.tspages.config.ts

// 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',
})

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配置:

{
  "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中配置:

好啦,这样基础框架就搭建好了,总体来说分为三步:

  1. 从官网安装基础模版
  2. 将package.json中不需要的依赖删除
  3. 安装其他依赖,例如pinia、sass、unocss以及开发规范和格式化等插件,然后根据不同的插件进行配置。
相关推荐
Kika写代码10 小时前
【微信小程序】页面跳转基础 | 我的咖啡店-综合实训
服务器·微信小程序·小程序
源码哥_博纳软云11 小时前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络11 小时前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
洗发水很好用12 小时前
uniApp打包H5发布到服务器(docker)
uni-app
关你西红柿子14 小时前
小程序app封装公用顶部筛选区uv-drop-down
前端·javascript·vue.js·小程序·uv
V+zmm1013414 小时前
基于小程序宿舍报修系统的设计与实现ssm+论文源码调试讲解
java·小程序·毕业设计·mvc·ssm
V+zmm1013421 小时前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
还这么多错误?!21 小时前
uniapp微信小程序,使用fastadmin完成一个一键获取微信手机号的功能
微信小程序·小程序·uni-app
_院长大人_21 小时前
微信小程序用户信息解密 AES/CBC/NoPadding 解密失败问题
微信小程序·小程序