├── src
├── app.css
├── composables
│ ├── index.ts
│ └── useDark.ts
├── pages
│ ├── index
│ │ ├── index.config.ts
│ │ └── index.vue
│ └── hello
│ │ ├── index.config.ts
│ │ └── index.vue
├── layouts
│ └── Layout.vue
├── store
│ └── counter.ts
├── app.config.ts
├── app.ts
├── icons
│ └── loading.svg
├── components
│ └── Footer.vue
└── index.html
├── .npmrc
├── .eslintignore
├── .eslintrc
├── config
├── dev.js
├── module
│ ├── TimePlugin.js
│ ├── keywords.ts
│ └── TaroResolver.ts
├── plugin-mini-ci.js
├── prod.js
└── index.js
├── project.tt.json
├── .gitignore
├── babel.config.js
├── project.config.json
├── types
└── global.d.ts
├── tsconfig.json
├── README.md
├── uno.config.ts
└── package.json
/src/app.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/composables/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useDark'
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist=true
2 | strict-peer-dependencies=false
3 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | index.html
2 | node_modules
3 | dist
4 | .history
5 | .swc
6 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@antfu", "./src/.eslintrc-auto-import.json"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/index/index.config.ts:
--------------------------------------------------------------------------------
1 | export default definePageConfig({
2 | navigationBarTitleText: '首页',
3 | })
4 |
--------------------------------------------------------------------------------
/src/pages/hello/index.config.ts:
--------------------------------------------------------------------------------
1 | export default definePageConfig({
2 | navigationBarTitleText: 'Hello',
3 | })
4 |
--------------------------------------------------------------------------------
/config/dev.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | NODE_ENV: '"development"',
4 | },
5 | defineConstants: {
6 | },
7 | mini: {},
8 | h5: {},
9 | }
10 |
--------------------------------------------------------------------------------
/src/layouts/Layout.vue:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/project.tt.json:
--------------------------------------------------------------------------------
1 | {
2 | "miniprogramRoot": "./",
3 | "projectname": "taro-unocss",
4 | "appid": "testAppId",
5 | "setting": {
6 | "es6": false,
7 | "minified": false
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | deploy_versions/
3 | .temp/
4 | .rn_temp/
5 | node_modules/
6 | .DS_Store
7 | taro-apis.json
8 | scripts/
9 | auto-imports.d.ts
10 | components.d.ts
11 | .eslintrc-auto-import.json
12 | Hooks/
13 | .history
14 | .swc
15 |
--------------------------------------------------------------------------------
/src/composables/useDark.ts:
--------------------------------------------------------------------------------
1 | import { useDark, useToggle } from '@vueuse/core'
2 |
3 | export const isDark = useDark({
4 | onChanged: (val) => {
5 | setStorageSync('theme', val ? 'dark' : 'light')
6 | },
7 | })
8 | export const toggleDark = useToggle(isDark)
9 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | // babel-preset-taro 更多选项和默认值:
2 | // https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md
3 | module.exports = {
4 | presets: [
5 | ['taro', {
6 | framework: 'vue3',
7 | ts: true,
8 | }],
9 | ],
10 | }
11 |
--------------------------------------------------------------------------------
/config/module/TimePlugin.js:
--------------------------------------------------------------------------------
1 | /** * @param ctx {import('@tarojs/service').IPluginContext} */
2 | module.exports = (ctx) => {
3 | ctx.onBuildStart(() => {
4 | // console.time('build in ')
5 | })
6 | ctx.onBuildFinish(() => {
7 | // console.timeEnd('build in ')
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/src/store/counter.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia'
2 |
3 | export const useCounterStore = defineStore('counter', {
4 | state: () => ({
5 | count: 0,
6 | }),
7 | actions: {
8 | increment() {
9 | this.count++
10 | },
11 | decrement() {
12 | this.count--
13 | },
14 | },
15 | })
16 |
--------------------------------------------------------------------------------
/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "miniprogramRoot": "./dist",
3 | "projectname": "taro-unocss",
4 | "description": "A Taro starter with unocss and auto-import",
5 | "appid": "touristappid",
6 | "setting": {
7 | "urlCheck": true,
8 | "es6": false,
9 | "postcss": false,
10 | "minified": false
11 | },
12 | "compileType": "miniprogram"
13 | }
14 |
--------------------------------------------------------------------------------
/src/app.config.ts:
--------------------------------------------------------------------------------
1 | export default defineAppConfig({
2 | pages: [
3 | 'pages/index/index',
4 | 'pages/hello/index',
5 | ],
6 | window: {
7 | backgroundTextStyle: 'light',
8 | navigationBarBackgroundColor: '#fff',
9 | navigationBarTitleText: 'WeChat',
10 | navigationBarTextStyle: 'black',
11 | },
12 | // tabBar: {},
13 | // subPackages: [],
14 | darkmode: true,
15 | // debug: true,
16 | })
17 |
--------------------------------------------------------------------------------
/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import { createPinia } from 'pinia'
3 |
4 | import 'uno.css'
5 | import './app.css'
6 |
7 | const App = createApp({
8 | async onShow() {
9 | if (!getStorageSync('theme')) {
10 | const info = await getSystemInfo()
11 | setStorageSync('theme', info.theme || 'light')
12 | }
13 | },
14 | // 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
15 | })
16 |
17 | App.use(createPinia())
18 |
19 | export default App
20 |
--------------------------------------------------------------------------------
/src/icons/loading.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/types/global.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | declare module '*.png';
4 | declare module '*.gif';
5 | declare module '*.jpg';
6 | declare module '*.jpeg';
7 | declare module '*.svg';
8 | declare module '*.css';
9 | declare module '*.less';
10 | declare module '*.scss';
11 | declare module '*.sass';
12 | declare module '*.styl';
13 |
14 | declare namespace NodeJS {
15 | interface ProcessEnv {
16 | TARO_ENV: 'weapp' | 'swan' | 'alipay' | 'h5' | 'rn' | 'tt' | 'quickapp' | 'qq' | 'jd'
17 | }
18 | }
19 |
20 | declare module '@tarojs/components' {
21 | export * from '@tarojs/components/types/index.vue3'
22 | }
23 |
--------------------------------------------------------------------------------
/src/components/Footer.vue:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | Count is {{ counter.count }}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | [ {{ props.layout }} Page ]
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/pages/hello/index.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "module": "ESNext",
5 | "target": "es2016",
6 | "lib": ["DOM", "es2016"],
7 | "strict": true,
8 | "esModuleInterop": true,
9 | "incremental": false,
10 | "skipLibCheck": true,
11 | "moduleResolution": "node",
12 | "experimentalDecorators": true,
13 | "resolveJsonModule": true,
14 | "noUnusedLocals": true,
15 | "forceConsistentCasingInFileNames": true,
16 | "outDir": "lib",
17 | "sourceMap": true,
18 | "allowJs": true,
19 | "jsx": "preserve",
20 | "types": [
21 | "webpack-env",
22 | "node"
23 | ],
24 | "paths": {
25 | "~/*": ["src/*"],
26 | "@/*": ["src/*"]
27 | }
28 | },
29 | "include": ["./src", "./types"],
30 | "exclude": ["dist", "node_modules"]
31 | }
32 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Taro & UnoCSS
12 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/config/plugin-mini-ci.js:
--------------------------------------------------------------------------------
1 | async function CIPluginFn() {
2 | // 可以在这里做一些异步事情, 比如请求接口获取配置
3 | /**
4 | * @typedef { import("@tarojs/plugin-mini-ci").CIOptions } CIOptions
5 | * @type {CIOptions}
6 | */
7 | return {
8 | weapp: {
9 | appid: 'touristappid',
10 | privateKeyPath: '',
11 | // privateKeyPath: '密钥文件相对项目根目录的相对路径,例如 key/private.appid.key',
12 | },
13 | tt: {
14 | email: '字节小程序邮箱',
15 | password: '字节小程序密码',
16 | },
17 | alipay: {
18 | appid: '支付宝小程序appid',
19 | toolId: '工具id',
20 | privateKeyPath: '密钥文件相对项目根目录的相对路径,例如 key/pkcs8-private-pem',
21 | },
22 | dd: {
23 | appid: '钉钉小程序appid,即钉钉开放平台后台应用管理的 MiniAppId 选项',
24 | token: '令牌,从钉钉后台获取',
25 | },
26 | swan: {
27 | token: '鉴权需要的token令牌',
28 | },
29 | // 版本号
30 | version: '1.0.0',
31 | // 版本发布描述
32 | desc: '版本描述',
33 | }
34 | }
35 |
36 | export default ['@tarojs/plugin-mini-ci', CIPluginFn]
37 |
--------------------------------------------------------------------------------
/src/pages/index/index.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Taro-Unocss
2 |
3 | 一套使用 Taro + Vue3 + TypeScript 的初始化模板,在此基础上增加了一些配置好的库,方便快速进行开发。
4 |
5 | + taro: v3.6.6
6 | + webpack: v5.x
7 |
8 | ## 功能
9 |
10 | 自动引入 + Typescript 类型声明,可以非常方便的进行开发
11 |
12 | + [`unplugin-auto-import`](https://github.com/antfu/unplugin-auto-import): 自动按需引入 Taro 所有API
13 | + [`unplugin-vue-components`](https://github.com/antfu/unplugin-vue-components): 自动引入组件
14 | + [`unocss`](https://github.com/unocss/unocss): unocss 原子化 css 引擎
15 | + [`pinia`](https://github.com/vuejs/pinia): 状态管理
16 | + [`unocss - presetIcons`](https://github.com/unocss/unocss/tree/main/packages/preset-icons): 提供丰富的 SVG 图标,简单易用易扩展
17 | + [`vueuse/core`](https://github.com/vueuse/vueuse): 一组高效的 Composition API 集合
18 |
19 | > **注意事项**
20 | >
21 | > + 由于小程序限制,VueUse 和元素有关的 API 都不能使用,但是,部分和 Vue 相关的 API 可以使用
22 | > + 依赖升级可能会出现问题,出现问题请退回到现在的版本
23 |
24 | ## 文件结构
25 |
26 | + components: 公共组件
27 | + composables: 实用 API 集合
28 | + icons: 自定义图标
29 | + store: 状态管理
30 |
31 | ## 开发
32 |
33 | ```bash
34 | npx degit aliuq/mp-taro .
35 | pnpm install
36 | pnpm dev:weapp
37 | pnpm build:weapp
38 | ```
39 |
40 | ## 感谢
41 |
42 | 感谢 [@antfu](https://github.com/antfu) 开源的 UnoCSS 项目以及其他的开源项目,让我们可以更加方便的进行开发。
43 |
--------------------------------------------------------------------------------
/config/prod.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | NODE_ENV: '"production"',
4 | },
5 | defineConstants: {
6 | },
7 | mini: {},
8 | h5: {
9 | /**
10 | * WebpackChain 插件配置
11 | * @docs https://github.com/neutrinojs/webpack-chain
12 | */
13 | // webpackChain (chain) {
14 | // /**
15 | // * 如果 h5 端编译后体积过大,可以使用 webpack-bundle-analyzer 插件对打包体积进行分析。
16 | // * @docs https://github.com/webpack-contrib/webpack-bundle-analyzer
17 | // */
18 | // chain.plugin('analyzer')
19 | // .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [])
20 |
21 | // /**
22 | // * 如果 h5 端首屏加载时间过长,可以使用 prerender-spa-plugin 插件预加载首页。
23 | // * @docs https://github.com/chrisvfritz/prerender-spa-plugin
24 | // */
25 | // const path = require('path')
26 | // const Prerender = require('prerender-spa-plugin')
27 | // const staticDir = path.join(__dirname, '..', 'dist')
28 | // chain
29 | // .plugin('prerender')
30 | // .use(new Prerender({
31 | // staticDir,
32 | // routes: [ '/pages/index/index' ],
33 | // postProcess: (context) => ({ ...context, outputPath: path.join(staticDir, 'index.html') })
34 | // }))
35 | // }
36 | },
37 | }
38 |
--------------------------------------------------------------------------------
/uno.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig, presetAttributify, presetIcons, presetTypography, presetUno, transformerDirectives, transformerVariantGroup } from 'unocss'
2 |
3 | import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
4 | import presetWeapp from 'unocss-preset-weapp'
5 | import { transformerAttributify, transformerClass } from 'unocss-preset-weapp/transformer'
6 |
7 | export default defineConfig({
8 | shortcuts: [
9 | {
10 | 'border-base': 'border-gray-200 dark:border-dark-200',
11 | 'bg-base': 'bg-white dark:bg-dark-100',
12 | 'color-base': 'text-gray-900 dark:text-gray-300',
13 | 'color-fade': 'text-gray-900:50 dark:text-gray-300:50',
14 | },
15 | ],
16 | rules: [],
17 | presets: [
18 | presetUno({
19 | preflight: false,
20 | }),
21 | presetWeapp({
22 | isH5: process.env.TARO_ENV === 'h5',
23 | platform: 'taro',
24 | taroWebpack: 'webpack5',
25 | whRpx: false,
26 | }),
27 | presetAttributify(),
28 | presetIcons({
29 | collections: {
30 | carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default),
31 | mdi: () => import('@iconify-json/mdi/icons.json').then(i => i.default),
32 | my: FileSystemIconLoader(
33 | './src/icons',
34 | svg => svg.replace(/#fff/, 'currentColor'),
35 | ),
36 | },
37 | scale: 1.2,
38 | warn: true,
39 | }),
40 | presetTypography(),
41 | ],
42 | transformers: [
43 | transformerDirectives(),
44 | transformerVariantGroup(),
45 | transformerAttributify(),
46 | transformerClass(),
47 | ],
48 | })
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "taro-unocss",
3 | "version": "0.0.0",
4 | "private": true,
5 | "description": "A Taro + Vue3 + Typescript template with unocss and auto import",
6 | "templateInfo": {
7 | "name": "default",
8 | "typescript": true,
9 | "css": "none"
10 | },
11 | "author": "",
12 | "scripts": {
13 | "build:weapp": "taro build --type weapp",
14 | "build:swan": "taro build --type swan",
15 | "build:alipay": "taro build --type alipay",
16 | "build:tt": "taro build --type tt",
17 | "build:h5": "taro build --type h5",
18 | "build:rn": "taro build --type rn",
19 | "build:qq": "taro build --type qq",
20 | "build:jd": "taro build --type jd",
21 | "build:quickapp": "taro build --type quickapp",
22 | "dev:weapp": "npm run build:weapp -- --watch",
23 | "dev:swan": "npm run build:swan -- --watch",
24 | "dev:alipay": "npm run build:alipay -- --watch",
25 | "dev:tt": "npm run build:tt -- --watch",
26 | "dev:h5": "npm run build:h5 -- --watch",
27 | "dev:rn": "npm run build:rn -- --watch",
28 | "dev:qq": "npm run build:qq -- --watch",
29 | "dev:jd": "npm run build:jd -- --watch",
30 | "dev:quickapp": "npm run build:quickapp -- --watch",
31 | "lint": "eslint .",
32 | "lint:fix": "npm run lint --fix",
33 | "pre:gen-taro-api": "npx tsx config/module/TaroResolver.ts"
34 | },
35 | "browserslist": [
36 | "last 3 versions",
37 | "Android >= 4.1",
38 | "ios >= 8"
39 | ],
40 | "dependencies": {
41 | "@babel/runtime": "^7.21.5",
42 | "@tarojs/components": "3.6.6",
43 | "@tarojs/plugin-framework-vue3": "3.6.6",
44 | "@tarojs/plugin-http": "^3.6.6",
45 | "@tarojs/plugin-platform-h5": "^3.6.6",
46 | "@tarojs/plugin-platform-weapp": "^3.6.6",
47 | "@tarojs/runtime": "3.6.6",
48 | "@tarojs/taro": "3.6.6",
49 | "@vueuse/core": "^10.1.2",
50 | "axios": "^1.4.0",
51 | "pinia": "^2.0.36",
52 | "vue": "^3.3.2"
53 | },
54 | "devDependencies": {
55 | "@antfu/eslint-config": "^0.38.6",
56 | "@babel/core": "^7.21.8",
57 | "@iconify-json/carbon": "^1.1.16",
58 | "@iconify-json/mdi": "^1.1.52",
59 | "@tarojs/plugin-html": "3.6.6",
60 | "@tarojs/plugin-mini-ci": "^3.6.6",
61 | "@tarojs/webpack5-runner": "3.6.6",
62 | "@types/node": "^20.1.5",
63 | "@types/webpack-env": "^1.18.0",
64 | "@unocss/webpack": "^0.51.13",
65 | "@vue/babel-plugin-jsx": "^1.1.1",
66 | "@vue/compiler-sfc": "^3.3.2",
67 | "babel-preset-taro": "3.6.6",
68 | "eslint": "^8.40.0",
69 | "local-pkg": "^0.4.3",
70 | "stylelint": "^15.6.1",
71 | "typescript": "^5.0.4",
72 | "unocss": "^0.51.13",
73 | "unocss-preset-weapp": "^0.6.3",
74 | "unplugin-auto-import": "^0.16.0",
75 | "unplugin-vue-components": "^0.24.1",
76 | "vue-loader": "^17.1.1",
77 | "webpack": "^5.82.1"
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/config/module/keywords.ts:
--------------------------------------------------------------------------------
1 | export const reservedKeywords = [
2 | 'abstract',
3 | 'arguments',
4 | 'boolean',
5 | 'break',
6 | 'byte',
7 | 'case',
8 | 'catch',
9 | 'char',
10 | 'class',
11 | 'const',
12 | 'continue',
13 | 'debugger',
14 | 'default',
15 | 'delete',
16 | 'do',
17 | 'double',
18 | 'else',
19 | 'enum',
20 | 'eval',
21 | 'export',
22 | 'extends',
23 | 'false',
24 | 'final',
25 | 'finally',
26 | 'float',
27 | 'for',
28 | 'function',
29 | 'goto',
30 | 'if',
31 | 'implements',
32 | 'import',
33 | 'in',
34 | 'instanceof',
35 | 'int',
36 | 'interface',
37 | 'let',
38 | 'long',
39 | 'native',
40 | 'new',
41 | 'null',
42 | 'package',
43 | 'private',
44 | 'protected',
45 | 'public',
46 | 'return',
47 | 'short',
48 | 'static',
49 | 'super',
50 | 'switch',
51 | 'synchronized',
52 | 'this',
53 | 'throw',
54 | 'throws',
55 | 'transient',
56 | 'true',
57 | 'try',
58 | 'typeof',
59 | 'var',
60 | 'void',
61 | 'volatile',
62 | 'while',
63 | 'with',
64 | 'yield,',
65 | 'Array',
66 | 'Date',
67 | 'eval',
68 | 'function',
69 | 'hasOwnProperty',
70 | 'Infinity',
71 | 'isFinite',
72 | 'isNaN',
73 | 'isPrototypeOf',
74 | 'length',
75 | 'Math',
76 | 'NaN',
77 | 'name',
78 | 'Number',
79 | 'Object',
80 | 'prototype',
81 | 'String',
82 | 'toString',
83 | 'undefined',
84 | 'valueOf',
85 | 'alert',
86 | 'all',
87 | 'anchor',
88 | 'anchors',
89 | 'area',
90 | 'assign',
91 | 'blur',
92 | 'button',
93 | 'checkbox',
94 | 'clearInterval',
95 | 'clearTimeout',
96 | 'clientInformation',
97 | 'close',
98 | 'closed',
99 | 'confirm',
100 | 'constructor',
101 | 'crypto',
102 | 'decodeURI',
103 | 'decodeURIComponent',
104 | 'defaultStatus',
105 | 'document',
106 | 'element',
107 | 'elements',
108 | 'embed',
109 | 'embeds',
110 | 'encodeURI',
111 | 'encodeURIComponent',
112 | 'escape',
113 | 'event',
114 | 'fileUpload',
115 | 'focus',
116 | 'form',
117 | 'forms',
118 | 'frame',
119 | 'innerHeight',
120 | 'innerWidth',
121 | 'layer',
122 | 'layers',
123 | 'link',
124 | 'location',
125 | 'mimeTypes',
126 | 'navigate',
127 | 'navigator',
128 | 'frames',
129 | 'frameRate',
130 | 'hidden',
131 | 'history',
132 | 'image',
133 | 'images',
134 | 'offscreenBuffering',
135 | 'open',
136 | 'opener',
137 | 'option',
138 | 'outerHeight',
139 | 'outerWidth',
140 | 'packages',
141 | 'pageXOffset',
142 | 'pageYOffset',
143 | 'parent',
144 | 'parseFloat',
145 | 'parseInt',
146 | 'password',
147 | 'pkcs11',
148 | 'plugin',
149 | 'prompt',
150 | 'propertyIsEnum',
151 | 'radio',
152 | 'reset',
153 | 'screenX',
154 | 'screenY',
155 | 'scroll',
156 | 'secure',
157 | 'select',
158 | 'self',
159 | 'setInterval',
160 | 'setTimeout',
161 | 'status',
162 | 'submit',
163 | 'taint',
164 | 'text',
165 | 'textarea',
166 | 'top',
167 | 'unescape',
168 | 'untaint',
169 | 'window',
170 | 'onblur',
171 | 'onclick',
172 | 'onerror',
173 | 'onfocus',
174 | 'onkeydown',
175 | 'onkeypress',
176 | 'onkeyup',
177 | 'onmouseover',
178 | 'onload',
179 | 'onmouseup',
180 | 'onmousedown',
181 | 'onsubmit',
182 | ]
183 |
--------------------------------------------------------------------------------
/config/module/TaroResolver.ts:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs'
2 | import path from 'node:path'
3 | import { resolveModule } from 'local-pkg'
4 | import type { ImportNameAlias, ImportsMap } from 'unplugin-auto-import/types'
5 | import { reservedKeywords } from './keywords'
6 |
7 | const cachePath = './config/module/taro-apis.json'
8 |
9 | // generateApis()
10 | function generateApis() {
11 | const exclude = [
12 | 'fail', 'success', 'complete', 'reject', 'resolve',
13 | ...reservedKeywords,
14 | ]
15 | const conflicts: Record = {
16 | nextTick: 'taroNextTick',
17 | getCurrentInstance: 'taroGetCurrentInstance',
18 | }
19 |
20 | const dir = resolveModule('@tarojs/taro')
21 | if (!dir) {
22 | console.error('\n[auto-import] Not found package `@tarojs/taro`, have you installed it?')
23 | console.error('see more https://github.com/NervJS/taro')
24 | return
25 | }
26 |
27 | try {
28 | const typesDir = `${path.dirname(dir) + path.sep}types`
29 | let maps: Array = []
30 |
31 | const filesList: string[] = readFiles(typesDir)
32 |
33 | for (const file of filesList) {
34 | if (file.includes('taro.extend.d.ts'))
35 | continue
36 |
37 | const pContent = fs.readFileSync(file, 'utf-8')
38 | const match = pContent.match(/(interface TaroStatic \{(.|\n)*\})/) || []
39 | const content = match[0]
40 | const reg = /(?<=\s{4})(?\w+)(?=(\s?\()|\<)/g
41 |
42 | if (!content)
43 | continue
44 |
45 | const funcs: Array = (content.match(reg) || [])
46 | .filter(fun => !exclude.includes(fun))
47 | .map((fun: string) => conflicts[fun] ? [fun, conflicts[fun]] : fun)
48 |
49 | maps = maps.concat(funcs)
50 | }
51 |
52 | maps = [
53 | 'getEnv',
54 | ['getCurrentInstance', 'taroGetCurrentInstance'],
55 | ...Array.from(new Set(maps)),
56 | ] as ImportNameAlias[]
57 |
58 | // fs.writeFileSync('./config/module/taro-apis.json', JSON.stringify(maps, null, 2))
59 | return maps
60 | }
61 | catch (err: any) {
62 | console.error(
63 | 'Some errors have occurred, '
64 | + 'please report an issue at https://github.com/antfu/unplugin-auto-import/issues/new?'
65 | + `title=${encodeURIComponent('[Taro] Failed generate apis')}&body=${encodeURIComponent(err?.message)}`,
66 | )
67 | console.error(err)
68 | }
69 | }
70 |
71 | function readFiles(dir: string, filesList: string[] = []) {
72 | const files = fs.readdirSync(dir)
73 |
74 | for (const file of files) {
75 | const filePath = path.resolve(dir, file)
76 | const stat = fs.statSync(filePath)
77 | if (stat.isDirectory())
78 | readFiles(filePath, filesList)
79 |
80 | else
81 | filesList.push(filePath)
82 | }
83 |
84 | return filesList
85 | }
86 |
87 | export default function (): ImportsMap {
88 | let jsonAPIs: (string | ImportNameAlias)[] = []
89 | if (fs.existsSync(cachePath)) {
90 | jsonAPIs = JSON.parse(fs.readFileSync(cachePath, 'utf-8'))
91 | }
92 | else {
93 | jsonAPIs = generateApis() || []
94 | jsonAPIs.length && fs.writeFileSync(cachePath, JSON.stringify(jsonAPIs, null, 2))
95 | }
96 |
97 | return {
98 | '@tarojs/taro': jsonAPIs,
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | import path from 'node:path'
2 | import AutoImport from 'unplugin-auto-import/webpack'
3 | import Components from 'unplugin-vue-components/webpack'
4 | import UnoCSS from '@unocss/webpack'
5 | import TaroResolver from './module/TaroResolver'
6 |
7 | const r = p => path.resolve(__dirname, '..', p)
8 |
9 | const isDev = process.env.NODE_ENV === 'development'
10 |
11 | function webpackChain(chain) {
12 | // 添加自动引入
13 | // https://github.com/antfu/unplugin-auto-import
14 | chain.plugin('unplugin-auto-import').use(AutoImport({
15 | imports: [
16 | 'vue',
17 | // 注意: 针对可能出现的 `$` 和 `$$`,手动排除
18 | // https://vuejs.org/guide/extras/reactivity-transform.html#refs-vs-reactive-variables
19 | {
20 | 'vue/macros': ['$ref', '$shallowRef', '$toRef', '$customRef', '$computed'],
21 | },
22 | TaroResolver(),
23 | ],
24 | dts: 'src/auto-imports.d.ts',
25 | dirs: [
26 | 'src/composables',
27 | 'src/store',
28 | ],
29 | vueTemplate: true,
30 | eslintrc: {
31 | enabled: true,
32 | filepath: 'src/.eslintrc-auto-import.json',
33 | globalsPropValue: true,
34 | },
35 | }))
36 |
37 | // 添加组件按需引入, 自动引入 `src/components` 目录下的组件
38 | // https://github.com/antfu/unplugin-vue-components
39 | chain.plugin('unplugin-vue-components').use(Components({
40 | dts: 'src/components.d.ts',
41 | dirs: ['src/components', 'src/layouts'],
42 | resolvers: [],
43 | types: [{
44 | from: '@tarojs/components',
45 | names: [
46 | 'Ad', 'AdCustom', 'AnimationVideo', 'AnimationView', 'ArCamera', 'Audio', 'AwemeData', 'Block', 'Button', 'Camera', 'Canvas', 'ChannelLive', 'ChannelVideo', 'Checkbox', 'CheckboxGroup', 'CommentDetail', 'CommentList', 'ContactButton', 'CoverImage', 'CoverView', 'CustomWrapper', 'Editor', 'FollowSwan', 'Form', 'FunctionalPageNavigator', 'GridView', 'Icon', 'Image', 'InlinePaymentPanel', 'Input', 'KeyboardAccessory', 'Label', 'Lifestyle', 'Like', 'ListView', 'LivePlayer', 'LivePusher', 'Login', 'Lottie', 'Map', 'MatchMedia', 'MovableArea', 'MovableView', 'NativeSlot', 'NavigationBar', 'Navigator', 'OfficialAccount', 'OpenData', 'PageContainer', 'PageMeta', 'Picker', 'PickerGroup', 'PickerView', 'PickerViewColumn', 'Progress', 'PullToRefresh', 'Radio', 'RadioGroup', 'RichText', 'RootPortal', 'RtcRoom', 'RtcRoomItem', 'ScrollView', 'ShareElement', 'Slider', 'Slot', 'StickyHeader', 'StickySection', 'Swiper', 'SwiperItem', 'Switch', 'TabItem', 'Tabbar', 'Tabs', 'Text', 'Textarea', 'Video', 'VideoControl', 'VideoDanmu', 'View', 'VoipRoom', 'WebView',
47 | ],
48 | }],
49 | }))
50 |
51 | // 添加 unocss 支持
52 | // https://github.com/unocss/unocss
53 | chain.plugin('unocss').use(UnoCSS())
54 |
55 | // 支持 mjs 模块
56 | chain.merge({
57 | module: {
58 | rule: {
59 | mjs: {
60 | test: /\.mjs$/,
61 | include: [/node_modules/],
62 | type: 'javascript/auto',
63 | },
64 | },
65 | },
66 | })
67 | }
68 | /** @type {import('@tarojs/taro/types/compile').IProjectConfig} */
69 | const config = {
70 | projectName: 'Taro & UnoCSS',
71 | date: '2022-6-7',
72 | designWidth: 750,
73 | deviceRatio: {
74 | 640: 2.34 / 2,
75 | 750: 1,
76 | 828: 1.81 / 2,
77 | },
78 | sourceRoot: 'src',
79 | outputRoot: `dist/${process.env.TARO_ENV}`,
80 | plugins: [
81 | '@tarojs/plugin-html',
82 | '@tarojs/plugin-http',
83 | ['@tarojs/plugin-framework-vue3', {
84 | vueLoaderOption: {
85 | // 添加 vue-macros 支持
86 | reactivityTransform: true, // 开启vue3响应性语法糖
87 | },
88 | }],
89 | // r('config/module/TimePlugin'),
90 | ],
91 | // jsMinimizer: 'terser',
92 | defineConstants: {
93 | },
94 | copy: {
95 | patterns: [],
96 | options: {},
97 | },
98 | alias: {
99 | '~': r('src'),
100 | '@': r('src'),
101 | },
102 | framework: 'vue3',
103 | compiler: {
104 | type: 'webpack5',
105 | prebundle: {
106 | timings: true,
107 | },
108 | },
109 | cache: {
110 | enable: false, // Webpack 持久化缓存配置,建议开启。默认配置请参考:https://docs.taro.zone/docs/config-detail#cache
111 | },
112 | logger: {
113 | stats: true,
114 | },
115 | mini: {
116 | webpackChain,
117 | hot: true,
118 | // minifyXML: {
119 | // collapseWhitespace: true,
120 | // },
121 | // prerender: {
122 | // match: 'pages/*/**', // 所有以 `pages/shop/` 开头的页面都参与 prerender
123 | // console: true, // 在 prerender 过程中 console 打印语句是否执行
124 | // },
125 | postcss: {
126 | // 可以进行 autoprefixer 的配置。配置项参考官方文档 https://github.com/postcss/autoprefixer
127 | // autoprefixer: {
128 | // enable: true,
129 | // config: {
130 | // // autoprefixer 配置项
131 | // },
132 | // },
133 | pxtransform: {
134 | enable: true,
135 | config: {
136 |
137 | },
138 | },
139 | url: {
140 | enable: true,
141 | config: {
142 | limit: 1024, // 设定转换尺寸上限
143 | maxSize: 10, // 设定转换尺寸上限(单位:kbytes)
144 | },
145 | },
146 | cssModules: {
147 | enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
148 | config: {
149 | namingPattern: 'module', // 转换模式,取值为 global/module
150 | generateScopedName: '[name]__[local]___[hash:base64:5]',
151 | },
152 | },
153 | },
154 | },
155 | h5: {
156 | publicPath: '/',
157 | staticDirectory: 'static',
158 | webpackChain,
159 | postcss: {
160 | autoprefixer: {
161 | enable: true,
162 | config: {
163 | },
164 | },
165 | cssModules: {
166 | enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
167 | config: {
168 | namingPattern: 'module', // 转换模式,取值为 global/module
169 | generateScopedName: '[name]__[local]___[hash:base64:5]',
170 | },
171 | },
172 | },
173 | },
174 | }
175 |
176 | module.exports = function (merge) {
177 | if (isDev)
178 | return merge({}, config, require('./dev'))
179 |
180 | return merge({}, config, require('./prod'))
181 | }
182 |
--------------------------------------------------------------------------------