用vscode和npm搭建uniapp+vite+vue3+ts开发环境

1,733 阅读3分钟

VSCode安装相关插件

uni相关插件

uni-helper
uni-create-view
uni-cloud-snippets
uni-highlight
uniapp小程序扩展

单元测试相关插件

Code Runner
Jest Runner
Playwright Test for VSCode

下载/解压项目模板

gitee.com/dcloud/uni-…

进入项目目录安装依赖

pnpm i

可能会报这样的错误

Error: Expected "0.17.19" but got "0.16.17"

 WARN  2 deprecated subdependencies found: sourcemap-codec@1.4.8, w3c-hr-time@1.0.2
Packages: +725
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 768, reused 721, downloaded 4, added 725, done
node_modules/.pnpm/registry.npmmirror.com+esbuild@0.17.19/node_modules/esbuild: Running postinstall script, failed in 2.1sde_modules/.pnpm/registry.npmmirror.com+esbuild@0.16.17/node_modules/esbuild: Running postinstall script, done in 2s
.../node_modules/esbuild postinstall$ node install.js
│ E:\workspace\uniapp\uni-preset-vue-vite-ts\node_modules\.pnpm\registry.npmmirror.com+esbuild@0.17.19\node_modules\e…
│     throw new Error(`Expected ${JSON.stringify(versionFromPackageJSON)} but got ${JSON.stringify(stdout)}`);
│           ^
│ Error: Expected "0.17.19" but got "0.16.17"
│     at validateBinaryVersion (E:\workspace\uniapp\uni-preset-vue-vite-ts\node_modules\.pnpm\registry.npmmirror.com+…
│     at E:\workspace\uniapp\uni-preset-vue-vite-ts\node_modules\.pnpm\registry.npmmirror.com+esbuild@0.17.19\node_mo…
│ Node.js v18.18.0
└─ Failed in 2.1s at E:\workspace\uniapp\uni-preset-vue-vite-ts\node_modules\.pnpm\registry.npmmirror.com+esbuild@0.17.19\node_modules\esbuild
node_modules/.pnpm/registry.npmmirror.com+esbuild@0.16.17/node_modules/esbuild: Running postinstall script, done in 2s
 ELIFECYCLE  Command failed with exit code 1.

解决方案

  1. 删除node_modules目录
  2. pnpm i esbuild@0.17.19 (因为预期是0.17.19的版本,但不知道什么原因没下到对应版本,那就强制下这个版本)

修改 vite.config.ts 文件

import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [uni()],
    resolve: {
        // 配置别名
        alias: {
            '@': resolve(__dirname, 'src')
        }
    },
    css: {
        // css预处理器
        preprocessorOptions: {
            scss: {
                // 因为uni.scss可以全局使用,这里根据自己的需求调整
                additionalData: '@import "./src/styles/global.scss";'
            }
        }
    },
    // 开发服务器配置
    server: {
        host: '0.0.0.0',
        port: 8080,
        // 请求代理
        proxy: {
            // 个人习惯,这里就用/dev作为前缀了
            '/dev': {
                target: 'https://xxx.com/api',
                changeOrigin: true,
                // 路径重写,去掉/dev
                rewrite: (path) => path.replace(/^\/dev/, '')
            }
        }
    },
    build: {
        // 禁用 gzip 压缩大小报告,以提升构建性能
        // brotliSize: false,
        /** 配置h5打包js,css,img分别在不同文件夹start */
        assetsDir: 'static/img/',
        rollupOptions: {
            output: {
                chunkFileNames: 'static/js/[name]-[hash].js',
                entryFileNames: 'static/js/[name]-[hash].js',
                assetFileNames: 'static/[ext]/[name]-[hash].[ext]'
            }
        }
        /** 配置h5打包js,css,img分别在不同文件夹end */
    }
})

修改 tsconfig.json 文件

pnpm i add @types/wechat-miniprogram @uni-helper/uni-app-types uni-cloud-types uni-ui-types -D
{
  "extends": "@vue/tsconfig/tsconfig.json",
  "compilerOptions": {
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "lib": ["esnext", "dom"],
    "types": ["@dcloudio/types", "@types/wechat-miniprogram"]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
  • @dcloudio/typesuni语法提示
  • miniprogram-api-typings,微信小程序wx语法提示
  • mini-types,支付宝小程序my语法提示

uni-helper | uni-helper 旨在增强 uni-app 系列产品的体验 (gitee.io)

uni-helper

封装 uni-request 请求

request.ts

/**
 * uni-request请求封装
 * 1. 统一配置接口地址
 * 2. 统一设置超时时间/报文格式/报文加密
 * 3. 统一身份认证
 * 4. 统一处理登录超时/接口异常提示
 * 5. 统一返回接口格式
 */

type responseType = {
  code: number;
  success: boolean;
  msg: string;
  result: any;
};

const request = (config: UniApp.RequestOptions) => {
  let url: string;
  if (/^(http|https):\/\/.*/.test(config.url)) {
    // 如果是以http/https开头的则不添加VITE_REQUEST_BASE_URL
    url = config.url;
  } else {
    url = import.meta.env.VITE_REQUEST_BASE_URL + config.url;
  }
  return new Promise<responseType>((resolve, reject) => {
    uni.request({
      ...config,
      url,
      /** 统一设置超时时间 */
      timeout: config.timeout || 60000,
      header: {
        ...config.header,
        /** 统一报文格式 */
        "Content-Type": "application/json;charset=UTF-8",
        /** 统一身份认证 */
        // Authorization: Token
      },
      success(res) {
        // 200状态码表示成功
        if (res.statusCode === 200) {
          resolve(res.data as any);
          return;
        }
        /**
         * 这里可以做一些登录超时/接口异常提示等处理
         */
        reject(res.data);
      },
      fail(result) {
        reject(result);
      },
    });
  });
};

export default {
  /**
   * get请求
   * @param url 请求地址
   * @param data 请求的参数
   * @param options 其他请求配置
   */
  get: (
    url: string,
    data?: UniApp.RequestOptions["data"],
    options?: UniApp.RequestOptions
  ) => {
    return request({
      ...options,
      url,
      data,
      method: "GET",
    });
  },
  /**
   * post请求
   * @param url 请求地址
   * @param data 请求的参数
   * @param options 其他请求配置
   */
  post: (
    url: string,
    data?: UniApp.RequestOptions["data"],
    options?: UniApp.RequestOptions
  ) => {
    return request({
      ...options,
      url,
      data,
      method: "POST",
    });
  },
};

集成 uni-ui

pnpm add @dcloudio/uni-ui
pnpm add sass -D

项目根目录下的 pages.json 并添加 easycom 节点:

{
	"easycom": {
        "autoscan": true,
        "custom": {
            "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
        }
    },

	"pages": [
		{
			"path": "pages/index/index",
			"style": {
				"navigationBarTitleText": "uni-app"
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	}
}

然后就可以直接使用了

| P.S. 无需再次引入,直接使用即可

<uni-rate :size="18" :value="5" />

集成pinia

pnpm add pinia

新建stores/index.ts

import { createPinia } from "pinia";

const store = createPinia();

export default store;

src/main.ts

import { createSSRApp } from "vue";
import App from "./App.vue";
// 引入pinia
import store from "./stores";

export function createApp() {
  const app = createSSRApp(App);
  // 整合进vue3
  app.use(store);
  return {
    app,
  };
}

集成调试工具

pnpm add  @dcloudio/uni-vue-devtools@3.0.0-3081220230817001 -D

@dcloudio/uni-vue-devtools 的版本必须与其他的@dcloudio/xxx版本一致,否则会出现如下错误

 [vite] [plugin:vite:import-analysis] Failed to resolve import "@dcloudio/uni-vue-devtools/lib/web/hook.js" from "src\main.ts". Does the file exist? 
at main.ts:1:7

从下面的截图中可以看出我的@dcloudio/xxx版本为3.0.0-3081220230817001, 所以,我前面就安装@dcloudio/uni-vue-devtools@3.0.0-3081220230817001

image.png

运行方式如下:

pnpm run dev:h5 --devtools

集成单元测试

集成playwrite

安装依赖

pnpm add cross-env puppeteer adbkit node-simctl jest jest-environment-node playwright @playwright/test @dcloudio/uni-automator @jest/globals @jest/types ts-node -D

注意: jest相关依赖不能高于以下版本

jest@27.0.4
jest-environment-node@27.5.1

uni-app cli项目@uniapp-cli | uni-app官网 (dcloud.net.cn)

注意 @dcloudio/uni-automator 的版本要与其他 @dcloudio/xxx 的版本保持一致

在项目根目录执行脚本

pnpm create playwright

Playwright 将下载所需的浏览器并创建以下文件。

playwright.config.ts
package.json
package-lock.json
tests/
  example.spec.ts
tests-examples/
  demo-todo-app.spec.ts

package.json中增加如下脚本

{
    ...
    "scripts": {
        "test:playwright-ui":"playwright test --ui",
        "test:playwright":"playwright test",
        "test:playwright-report":"playwright show-report",
    }
    ...
}
test:playwright-ui: 使用UI界面运行playwright测试
test:playwright: 无头模式运行playwright测试,并将测试结果打印到终端
test:playwright-report: 生成测试报告

集成jest

项目根目录新建jest.config.ts

import type { Config } from "@jest/types";

const config: Config.InitialOptions = {
  // uniapp环境配置开始
  globalTeardown: "@dcloudio/uni-automator/dist/teardown.js",
  testEnvironment: "@dcloudio/uni-automator/dist/environment.js",
  testEnvironmentOptions: {
    compile: true,
    // h5: {
    //   // 为了节省测试时间,可以指定一个 H5 的 url 地址,若不指定,每次运行测试,会先 npm run dev:h5
    //   url: "http://192.168.x.x:8080/h5/",
    //   options: {
    //     headless: false, // 配置是否显示 puppeteer 测试窗口
    //   },
    // },
    "app-plus": {
      // 需要安装 HBuilderX
      android: {
        appid: "H501AE3BA", //自定义基座测试需配置manifest.json中的appid
        package: "html_five_plus_test", //自定义基座测试需配置Android包名
        // executablePath: "HBuilderX/plugins/launcher/base/android_base.apk", // apk 目录或自定义调试基座包路径
        executablePath: "./android_base.apk", // apk 目录或自定义调试基座包路径
      },
      // ios: {
      //   // uuid 必须配置,目前仅支持模拟器,可以(xcrun simctl list)查看要使用的模拟器 uuid
      //   id: "",
      //   executablePath: "HBuilderX/plugins/launcher/base/Pandora_simulator.app", // ipa 目录
      // },
    },
    // "mp-weixin": {
    //   port: 9420, // 默认 9420
    //   account: "", // 测试账号
    //   args: "", // 指定开发者工具参数
    //   cwd: "", // 指定开发者工具工作目录
    //   launch: true, // 是否主动拉起开发者工具
    //   teardown: "disconnect", // 可选值 "disconnect"|"close" 运行测试结束后,断开开发者工具或关闭开发者工具
    //   remote: false, // 是否真机自动化测试
    //   executablePath: "", // 开发者工具cli路径,默认会自动查找,  windows: C:/Program Files (x86)/Tencent/微信web开发者工具/cli.bat", mac: /Applications/wechatwebdevtools.app/Contents/MacOS/cli
    // },
    // "mp-baidu": {
    //   port: 9430, // 默认 9430
    //   args: "", // 指定开发者工具参数
    //   cwd: "", // 指定开发者工具工作目录
    //   launch: true, // 是否主动拉起开发者工具
    //   teardown: "disconnect", // 可选值 "disconnect"|"close" 运行测试结束后,断开开发者工具或关闭开发者工具
    //   remote: false, // 是否真机自动化测试
    //   executablePath: "", // 开发者工具cli路径,默认会自动查找
    // },
  },
  // uniapp环境配置结束

  // jest解析ts的配置开始
  preset: "ts-jest",
  transform: {
    "/jest-test/.+\\.(j|t)sx?$": "ts-jest",
  },
  transformIgnorePatterns: ["/node_modules/(?!sample)"],
  // jest解析ts的配置结束
  testTimeout: 15000,
  reporters: ["default"],
  watchPathIgnorePatterns: ["/node_modules/", "/dist/", "/.git/"],
  // 注意这里要包含ts的扩展名,否则jest无法匹配到ts的测试用例
  moduleFileExtensions: ["js", "json", "ts"],
  rootDir: __dirname,
  // 匹配规则
  testMatch: ["<rootDir>/jest-test/**/*.{test,spec}.?(c|m)[jt]s?(x)"], // 测试文件目录
  // 忽略匹配的规则
  testPathIgnorePatterns: ["/node_modules/"],
};

export default config;

appid需要到 dcloud 开发者中心去生成: 应用列表 (dcloud.net.cn)

jest-test/demo.test.ts

/**
 * @jest-environment node
 *
 * jest-environment注解的作用是强制指定当前的jest环境,
 * 因为 jest.config.ts 中配置了 uniapp 的环境,
 * 如果运行普通jest测试,则会报错,
 * 因此这里需要强制指定当前的jest环境
 */

import { expect, test } from "@jest/globals";

function sum(a: number, b: number) {
  return a + b;
}

test("1加2等于3", () => {
  expect(sum(1, 2)).toBe(3);
});

package.json中增加如下脚本

{
    ...
    "scripts": {
        "test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
        "test:android": "cross-env UNI_PLATFORM=app UNI_OS_NAME=android jest -i",
        "test:ios": "cross-env UNI_PLATFORM=app UNI_OS_NAME=ios jest -i",
        "test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i",
        "test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
        "test:jest":"jest",
        "test:coverage": "jest --coverage"
    }
    ...
}

jest 查看测试报告和代码覆盖率 - 掘金 (juejin.cn)

自动化测试插件@extension | uni-app官网 (dcloud.net.cn)

安装 | Playwright 中文网 (nodejs.cn)

快速开始 · Jest (jestjs.io)

Jest 配置 · Jest (jestjs.io)

DCloud插件市场的使用

DCloud插件市场的使用 - 掘金 (juejin.cn)

在android基座上运行

pnpm run dev:app-android

此时控制台会输出

> uni-preset-vue@0.0.0 dev:app-android E:\workspace\uniapp\uni-preset-vue-vite-ts
> uni -p app-android

请注意运行模式下,因日志输出、sourcemap 以及未压缩源码等原因,性能和包体积,均不及发行模式。
编译器版本:3.8.12(vue3)
正在编译中...
DONE  Build complete. Watching for changes...
运行方式:打开 HBuilderX, 导入 dist\dev\app 运行。
ready in 6518ms.

使用hbuilder打开项目,运行 > 运行到手机或模拟器 > 运行到Android App基座

image.png

从上面的控制台输出信息可以得知,当前命令已经在监听文件内容改变了,所以,你所有的改动,都会热更新到基座中的app中

集成html5plus的能力

  1. 通过hbuilder的界面,在manifest.json文件中增加对应模块的权限
  2. 按照 HTML5+ API Reference (html5plus.org) 的API,操作相应硬件

image.png

uni-app官网 (dcloud.net.cn)

参考资料

uni-app官网 (dcloud.net.cn)

uniapp项目实践第二章:使用vscode开发uniapp项目_vscode开发uni-app_极客李华的博客-CSDN博客

pnpm i 出现错误Error: Expected “0.17.19“ but got “0.16.17“_一杯冰美式88的博客-CSDN博客

vite+typescript创建uni-app基础框架,开箱即用 - 掘金 (juejin.cn)

【vue项目迁移应用pnpm和dart-sass】操作流程和一些注意事项-CSDN博客

TypeScript 支持 | uni-app官网 (dcloud.net.cn)

这可能是最好、最详细的VSCode开发uni-app教程吧_vscode开发uniapp-CSDN博客

这可能是最好、最详细的VSCode开发uni-app教程吧_vscode开发uniapp-CSDN博客

【uni-app 基础】前端项目uniapp小兔鲜儿微信小程序_uniapp项目代码_黑马程序员官方的博客-CSDN博客

uni-vue-devtools | uni-app官网 (dcloud.net.cn)

在vscoed 中运行 uniapp 项目 - 掘金 (juejin.cn)