diff --git a/packages/create-fes-app/bin/create-fes-app.js b/packages/create-fes-app/bin/create-fes-app.js deleted file mode 100755 index d2316ff6..00000000 --- a/packages/create-fes-app/bin/create-fes-app.js +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -require('../lib/cli'); diff --git a/packages/create-fes-app/bin/create-fes-app.mjs b/packages/create-fes-app/bin/create-fes-app.mjs new file mode 100755 index 00000000..a214a81c --- /dev/null +++ b/packages/create-fes-app/bin/create-fes-app.mjs @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +import { runMain } from '../dist/index.mjs'; + +runMain(); diff --git a/packages/create-fes-app/package.json b/packages/create-fes-app/package.json index 30837f12..bf8e8cf2 100644 --- a/packages/create-fes-app/package.json +++ b/packages/create-fes-app/package.json @@ -17,20 +17,33 @@ "fes" ], "sideEffects": false, - "main": "dist/index.js", + "main": "dist/index.mjs", + "module": "dist/index.mjs", "bin": { - "create-fes-app": "bin/create-fes-app.js" + "create-fes-app": "bin/create-fes-app.mjs" }, "files": [ "bin", "dist", "templates/**/*" ], + "scripts": { + "dev": "tsup --watch --sourcemap", + "build": "tsup" + }, "publishConfig": { "access": "public" }, "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.2", "fs-extra": "^11.3.1", - "validate-npm-package-name": "^3.0.0" + "glob": "^11.0.3", + "mustache": "^4.2.0", + "semver": "^7.7.2", + "validate-npm-package-name": "^6.0.2" + }, + "devDependencies": { + "@types/validate-npm-package-name": "^4.0.2" } } diff --git a/packages/create-fes-app/src/Generator.ts b/packages/create-fes-app/src/Generator.ts deleted file mode 100644 index 37c384ba..00000000 --- a/packages/create-fes-app/src/Generator.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { copyFileSync, readFileSync, statSync, writeFileSync } from 'node:fs'; -import { dirname, join, relative } from 'node:path'; - -import chalk from 'chalk'; -import glob from 'glob'; -import mkdirp from 'mkdirp'; -import Mustache from 'mustache'; - -interface GeneratorOptions { - cwd: string; - args: Record; -} - -interface CopyTplOptions { - templatePath: string; - target: string; - context: Record; -} - -interface CopyDirectoryOptions { - path: string; - target: string; - context: Record; -} - -class Generator { - cwd: string; - args: Record; - - constructor({ cwd, args }: GeneratorOptions) { - this.cwd = cwd; - this.args = args; - } - - async run(): Promise { - await this.writing(); - } - - async writing(): Promise { } - - copyTpl(opts: CopyTplOptions): void { - const tpl = readFileSync(opts.templatePath, 'utf-8'); - const content = Mustache.render(tpl, opts.context); - mkdirp.sync(dirname(opts.target)); - // eslint-disable-next-line no-console - console.log(`${chalk.green('Write:')} ${relative(this.cwd, opts.target)}`); - writeFileSync(opts.target, content, 'utf-8'); - } - - copyDirectory(opts: CopyDirectoryOptions): void { - const files = glob.sync('**/*', { - cwd: opts.path, - dot: true, - ignore: ['**/node_modules/**'], - }); - files.forEach((file) => { - const absFile = join(opts.path, file); - if (statSync(absFile).isDirectory()) { - return; - } - if (file.endsWith('.tpl')) { - return this.copyTpl({ - templatePath: absFile, - target: join(opts.target, file.replace(/\.tpl$/, '')), - context: opts.context, - }); - } - // eslint-disable-next-line no-console - console.log(`${chalk.green('Copy: ')} ${file}`); - const absTarget = join(opts.target, file); - mkdirp.sync(dirname(absTarget)); - copyFileSync(absFile, absTarget); - }); - } -} - -export default Generator; diff --git a/packages/create-fes-app/src/cli.js b/packages/create-fes-app/src/cli.js deleted file mode 100644 index 699643f2..00000000 --- a/packages/create-fes-app/src/cli.js +++ /dev/null @@ -1,51 +0,0 @@ -import { existsSync } from 'node:fs'; -import { join } from 'node:path'; -import process from 'node:process'; -import { chalk, yParser } from '@fesjs/utils'; - -const args = yParser(process.argv.slice(2), { - alias: { - version: ['v'], - help: ['h'], - force: ['f'], - merge: ['m'], - proxy: ['x'], - }, - boolean: ['version', 'help', 'merge', 'force'], -}); - -if (args._.length > 1) { - console.log(chalk.yellow('\n Warning: You provided more than one argument. The first one will be used as the app\'s name, the rest are ignored.')); -} - -if (args.version && !args._[0]) { - args._[0] = 'version'; - const local = existsSync(join(__dirname, '../.local')) - ? chalk.cyan('@local') - : ''; - const { name, version } = require('../package.json'); - console.log(`${name}@${version}${local}`); -} -else if (args.help && !args._[0]) { - console.log(` -Usage: create-fes-app - -Options: - -v, --version Output the current version - -h, --help Display help for command - -f, --force Overwrite target directory if it exists - -m, --merge Merge target directory if it exists - -x, --proxy Use specified proxy when creating project - `); -} -else { - require('.') - .default({ - cwd: process.cwd(), - args, - }) - .catch((err) => { - console.error(`Create failed, ${err.message}`); - console.error(err); - }); -} diff --git a/packages/create-fes-app/src/generator/App.js b/packages/create-fes-app/src/generator/App.js deleted file mode 100644 index 0249a0e5..00000000 --- a/packages/create-fes-app/src/generator/App.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Generator } from '@fesjs/utils'; - -export default class AppGenerator extends Generator { - constructor({ cwd, args, path, targetDir }) { - super({ - cwd, - args, - }); - this.path = path; - this.targetDir = targetDir; - } - - async writing() { - this.copyDirectory({ - context: { - version: require('../../package.json').version, - }, - path: this.path, - target: this.targetDir, - }); - } -} diff --git a/packages/create-fes-app/src/generator/Plugin.js b/packages/create-fes-app/src/generator/Plugin.js deleted file mode 100644 index 1a89334d..00000000 --- a/packages/create-fes-app/src/generator/Plugin.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Generator } from '@fesjs/utils'; - -export default class AppGenerator extends Generator { - constructor({ cwd, args, path, targetDir, name }) { - super({ - cwd, - args, - }); - this.path = path; - this.targetDir = targetDir; - this.name = name; - } - - async writing() { - this.copyDirectory({ - context: { - version: require('../../package.json').version, - name: this.name, - }, - path: this.path, - target: this.targetDir, - }); - } -} diff --git a/packages/create-fes-app/src/index.js b/packages/create-fes-app/src/index.js deleted file mode 100644 index caeb9bec..00000000 --- a/packages/create-fes-app/src/index.js +++ /dev/null @@ -1,121 +0,0 @@ -import path from 'node:path'; -import process from 'node:process'; -import { chalk } from '@fesjs/utils'; -import fs from 'fs-extra'; -import inquirer from 'inquirer'; -import validateProjectName from 'validate-npm-package-name'; - -import AppGenerator from './generator/App'; -import PluginGenerator from './generator/Plugin'; -import { clearConsole } from './utils'; - -export default async ({ cwd, args }) => { - if (args.proxy) { - process.env.HTTP_PROXY = args.proxy; - } - const projectName = args._[0]; - const inCurrent = projectName === '.'; - const name = inCurrent ? path.relative('../', cwd) : projectName; - const targetDir = path.resolve(cwd, projectName || '.'); - - const result = validateProjectName(name); - if (!result.validForNewPackages) { - console.error(chalk.red(`Invalid project name: "${name}"`)); - result.errors - && result.errors.forEach((err) => { - console.error(chalk.red.dim(`Error: ${err}`)); - }); - result.warnings - && result.warnings.forEach((warn) => { - console.error(chalk.red.dim(`Warning: ${warn}`)); - }); - throw new Error('Process exited'); - } - if (fs.pathExistsSync(targetDir) && !args.merge) { - if (args.force) { - await fs.remove(targetDir); - } - else if (inCurrent) { - clearConsole(); - const { ok } = await inquirer.prompt([ - { - name: 'ok', - type: 'confirm', - message: 'Generate project in current directory?', - }, - ]); - if (!ok) { - return null; - } - } - else { - clearConsole(); - const { action } = await inquirer.prompt([ - { - name: 'action', - type: 'list', - message: `Target directory ${chalk.cyan(targetDir)} already exists. Pick an action:`, - choices: [ - { name: 'Overwrite', value: 'overwrite' }, - { name: 'Merge', value: 'merge' }, - { name: 'Cancel', value: false }, - ], - }, - ]); - if (!action) { - return null; - } - if (action === 'overwrite') { - console.log(`\nRemoving ${chalk.cyan(targetDir)}...`); - await fs.remove(targetDir); - } - } - } - - clearConsole(); - const { template } = await inquirer.prompt([ - { - name: 'template', - type: 'list', - message: 'Pick an template:', - choices: [ - { name: 'PC, suitable for management desk front-end applications', value: 'pc' }, - { name: 'H5, suitable for mobile applications', value: 'h5' }, - { name: 'Plugin, suitable for fes plugin', value: 'plugin' }, - { name: 'Cancel', value: false }, - ], - }, - ]); - - if (template === 'pc' || template === 'h5') { - const generator = new AppGenerator({ - cwd, - args, - targetDir, - path: path.join(__dirname, `../templates/app/${template}`), - }); - await generator.run(); - console.log(); - console.log(chalk.green(`project ${projectName} created successfully, please execute the following command to use:`)); - console.log(`$ cd ${projectName}`); - console.log('$ pnpm i'); - console.log('$ pnpm dev'); - console.log(); - } - else if (template === 'plugin') { - const generator = new PluginGenerator({ - cwd, - args, - targetDir, - path: path.join(__dirname, '../templates/plugin'), - name, - }); - await generator.run(); - console.log(); - console.log(chalk.green(`plugin ${projectName} created successfully, please execute the following command to use:`)); - console.log(`$ cd ${projectName}`); - console.log('$ pnpm i'); - console.log('$ pnpm dev'); - console.log(); - } -}; diff --git a/packages/create-fes-app/src/index.ts b/packages/create-fes-app/src/index.ts new file mode 100644 index 00000000..398e1145 --- /dev/null +++ b/packages/create-fes-app/src/index.ts @@ -0,0 +1,2 @@ +export { main } from './main'; +export { runMain } from './run'; diff --git a/packages/create-fes-app/src/main.ts b/packages/create-fes-app/src/main.ts new file mode 100644 index 00000000..0f25ceec --- /dev/null +++ b/packages/create-fes-app/src/main.ts @@ -0,0 +1,114 @@ +import { join, relative, resolve } from 'node:path'; +import process from 'node:process'; +import { defineCommand } from 'citty'; +import consola from 'consola'; + +import validate from 'validate-npm-package-name'; +import pkg from '../package.json' assert { type: 'json' }; +import { getWorkPath } from './shared'; +import { setupGlobalConsole } from './utils/console'; +import { checkEngines } from './utils/engines'; +import { copyDirectory } from './utils/gen'; + +export const main = defineCommand({ + meta: { + name: pkg.name, + version: pkg.version, + description: pkg.description, + }, + args: { + name: { + type: 'positional', + description: '项目名称', + required: true, + }, + proxy: { + type: 'string', + description: '代理地址', + alias: ['-p'], + }, + merge: { + type: 'boolean', + description: '是否合并', + alias: ['m'], + }, + force: { + type: 'boolean', + description: '是否强制覆盖', + alias: ['f'], + }, + }, + async setup() { + setupGlobalConsole(); + await checkEngines(); + }, + async run({ args }) { + const inCurrent = args.name === '.'; + const cwd = getWorkPath(); + const projectName = inCurrent ? relative('../', cwd) : args.name; + + const result = validate(projectName); + if (!result.validForNewPackages) { + consola.error(`Invalid project name: "${projectName}"`); + result.errors + && result.errors.forEach((err) => { + consola.error(`Error: ${err}`); + }); + result.warnings + && result.warnings.forEach((warn) => { + consola.warn(`Warning: ${warn}`); + }); + process.exit(0); + } + + const template = await consola.prompt('Pick an template:', { + type: 'select', + options: [{ + label: 'PC, suitable for management desk front-end applications', + value: 'pc', + }, { + label: 'H5, suitable for mobile applications', + value: 'h5', + }, { + label: 'Plugin, suitable for fes plugin', + value: 'plugin', + }, { + label: 'Cancel', + value: 'cancel', + }], + }); + + const targetDir = resolve(cwd, projectName || '.'); + if (template === 'pc' || template === 'h5') { + copyDirectory({ + context: { + version: pkg.version, + }, + path: join(__dirname, `../templates/app/${template}`), + target: targetDir, + }); + consola.success(`Project ${projectName} created successfully!`); + consola.box([ + `cd ${projectName}`, + 'pnpm i', + 'pnpm dev', + ].join('\n')); + } + else if (template === 'plugin') { + copyDirectory({ + context: { + version: pkg.version, + name: projectName, + }, + path: join(__dirname, '../templates/plugin'), + target: targetDir, + }); + consola.success(`plugin ${projectName} created successfully, please execute the following command to use:`); + consola.box([ + `cd ${projectName}`, + 'pnpm i', + 'pnpm dev', + ].join('\n')); + } + }, +}); diff --git a/packages/create-fes-app/src/run.ts b/packages/create-fes-app/src/run.ts new file mode 100644 index 00000000..e125c6f8 --- /dev/null +++ b/packages/create-fes-app/src/run.ts @@ -0,0 +1,5 @@ +import { runMain as _runMain } from 'citty'; + +import { main } from './main'; + +export const runMain = () => _runMain(main); diff --git a/packages/create-fes-app/src/shared.ts b/packages/create-fes-app/src/shared.ts new file mode 100644 index 00000000..24982102 --- /dev/null +++ b/packages/create-fes-app/src/shared.ts @@ -0,0 +1,27 @@ +import { readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import process from 'node:process'; +import { fileURLToPath } from 'node:url'; + +export const OWNER_DIR = join(dirname(fileURLToPath(import.meta.url)), '..'); + +export function getWorkPath() { + return process.env.PWD || process.cwd(); +} + +export function removeSync(dir: string) { + rmSync(dir, { + recursive: true, + force: true, + }); +} + +export function readJsonSync(filePath: string) { + const content = readFileSync(filePath, 'utf-8'); + + return JSON.parse(content); +} + +export function writeJSONSync(filePath: string, data: Record) { + writeFileSync(filePath, JSON.stringify(data, null, 2)); +} diff --git a/packages/create-fes-app/src/utils.js b/packages/create-fes-app/src/utils.js deleted file mode 100644 index adac0ed7..00000000 --- a/packages/create-fes-app/src/utils.js +++ /dev/null @@ -1,14 +0,0 @@ -import process from 'node:process'; -import readline from 'node:readline'; - -export function clearConsole(title) { - if (process.stdout.isTTY) { - const blank = '\n'.repeat(process.stdout.rows); - console.log(blank); - readline.cursorTo(process.stdout, 0, 0); - readline.clearScreenDown(process.stdout); - if (title) { - console.log(title); - } - } -} diff --git a/packages/create-fes-app/src/utils/console.ts b/packages/create-fes-app/src/utils/console.ts new file mode 100644 index 00000000..ce3435a2 --- /dev/null +++ b/packages/create-fes-app/src/utils/console.ts @@ -0,0 +1,17 @@ +import process from 'node:process'; + +import { consola } from 'consola'; + +export function setupGlobalConsole(opts: { dev?: boolean } = {}) { + // Wrap all console logs with consola for better DX + if (opts.dev) { + consola.wrapAll(); + } + else { + consola.wrapConsole(); + } + + process.on('unhandledRejection', err => consola.error('[unhandledRejection]', err)); + + process.on('uncaughtException', err => consola.error('[uncaughtException]', err)); +} diff --git a/packages/create-fes-app/src/utils/engines.ts b/packages/create-fes-app/src/utils/engines.ts new file mode 100644 index 00000000..067d1fcc --- /dev/null +++ b/packages/create-fes-app/src/utils/engines.ts @@ -0,0 +1,17 @@ +import process from 'node:process'; + +import { logger } from './logger'; + +export async function checkEngines() { + const satisfies = await import('semver/functions/satisfies.js').then( + r => r.default || (r as any as typeof import('semver/functions/satisfies.js')), + ); // npm/node-semver#381 + const currentNode = process.versions.node; + const nodeRange = '>= 18.0.0'; + + if (!satisfies(currentNode, nodeRange)) { + logger.warn( + `Current version of Node.js (\`${currentNode}\`) is unsupported and might cause issues.\n Please upgrade to a compatible version \`${nodeRange}\`.`, + ); + } +} diff --git a/packages/create-fes-app/src/utils/gen.ts b/packages/create-fes-app/src/utils/gen.ts new file mode 100644 index 00000000..a15b4418 --- /dev/null +++ b/packages/create-fes-app/src/utils/gen.ts @@ -0,0 +1,49 @@ +import { readFileSync, statSync } from 'node:fs'; +import { join, relative } from 'node:path'; +import consola from 'consola'; +import { copySync, outputFileSync } from 'fs-extra/esm'; +import { globSync } from 'glob'; +import Mustache from 'mustache'; + +import { getWorkPath } from '../shared'; + +function copyTpl(opts: { + templatePath: string; + target: string; + context: Record; +}): void { + const tpl = readFileSync(opts.templatePath, 'utf-8'); + const content = Mustache.render(tpl, opts.context); + + consola.success(`Write: ${relative(getWorkPath(), opts.target)}`); + outputFileSync(opts.target, content, 'utf-8'); +} + +export function copyDirectory(opts: { + path: string; + target: string; + context: Record; +}): void { + const files = globSync('**/*', { + cwd: opts.path, + dot: true, + ignore: ['**/node_modules/**'], + }); + files.forEach((file) => { + const absFile = join(opts.path, file); + if (statSync(absFile).isDirectory()) { + return; + } + if (file.endsWith('.tpl')) { + return copyTpl({ + templatePath: absFile, + target: join(opts.target, file.replace(/\.tpl$/, '')), + context: opts.context, + }); + } + + consola.success(`Copy: ${file}`); + const absTarget = join(opts.target, file); + copySync(absFile, absTarget); + }); +} diff --git a/packages/create-fes-app/src/utils/logger.ts b/packages/create-fes-app/src/utils/logger.ts new file mode 100644 index 00000000..a18ef5ae --- /dev/null +++ b/packages/create-fes-app/src/utils/logger.ts @@ -0,0 +1,3 @@ +import { consola } from 'consola'; + +export const logger = consola.withTag('fes'); diff --git a/packages/create-fes-app/templates/app/h5/package.json b/packages/create-fes-app/templates/app/h5/package.json index 17a2dc07..70d89ab3 100644 --- a/packages/create-fes-app/templates/app/h5/package.json +++ b/packages/create-fes-app/templates/app/h5/package.json @@ -12,17 +12,18 @@ "access": "public" }, "dependencies": { - "@fesjs/builder-webpack": "^3.1.0", - "@fesjs/fes": "^3.1.17", - "@fesjs/plugin-icon": "^4.0.0", - "@fesjs/plugin-request": "^4.0.1", + "@fesjs/builder-webpack": "^4.0.0", + "@fesjs/fes": "^4.0.0", + "@fesjs/plugin-icon": "^5.0.0", + "@fesjs/plugin-request": "^5.0.0", "core-js": "^3.43.0", + "lodash-es": "^4.17.21", "vue": "^3.5.17" }, "devDependencies": { - "@antfu/eslint-config": "4.16.1", - "eslint": "9.29.0", + "@antfu/eslint-config": "^5.2.2", + "eslint": "^9.35.0", "postcss-px-to-viewport-8-plugin": "^1.2.5", - "typescript": "5.8.3" + "typescript": "^5.9.2" } } diff --git a/packages/create-fes-app/templates/app/h5/src/app.js b/packages/create-fes-app/templates/app/h5/src/app.js deleted file mode 100644 index fb0e2fd9..00000000 --- a/packages/create-fes-app/templates/app/h5/src/app.js +++ /dev/null @@ -1,44 +0,0 @@ -import { defineRuntimeConfig } from '@fesjs/fes'; - -export default defineRuntimeConfig({ - request: { - // API 前缀 - baseURL: '', - dataHandler(data, response) { - // 处理响应内容异常 - if (data.code !== '0') { - if (data.code === '20000') { - console.log('hello world'); - } - throw new Error(response); - } - // 响应数据格式化 - return data?.result ? data.result : data; - }, - // http 异常,和插件异常 - errorHandler(error) { - if (error.response) { - // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围 - console.log(error.response.data); - console.log(error.response.status); - console.log(error.response.headers); - } else if (error.request) { - // 请求已经成功发起,但没有收到响应 - // `error.request` 在浏览器中是 XMLHttpRequest 的实例, - // 而在node.js中是 http.ClientRequest 的实例 - console.log(error.request); - } else if (error.type) { - // 插件异常 - console.log(error.msg); - } else { - // 发送请求时出了点问题 - console.log('Error', error.message); - } - console.log(error.config); - }, - // 请求拦截器 - requestInterceptors: [], - // 响应拦截器 - responseInterceptors: [], - }, -}); diff --git a/packages/create-fes-app/templates/app/h5/src/app.ts b/packages/create-fes-app/templates/app/h5/src/app.ts new file mode 100644 index 00000000..74221d99 --- /dev/null +++ b/packages/create-fes-app/templates/app/h5/src/app.ts @@ -0,0 +1,42 @@ +import { defineRuntimeConfig } from '@fesjs/fes' +import { isPlainObject } from 'lodash-es' + +export default defineRuntimeConfig({ + request: { + baseURL: '', + timeout: 10000, // 默认 10s + method: 'POST', // 默认 post + mergeRequest: false, // 是否合并请求 + responseType: null, // 可选 'json' | 'text' | 'blob' | 'arrayBuffer' | 'formData',默认根据 content-type 处理 + credentials: 'include', // 默认 include, 'include' | 'same-origin' | 'omit' + headers: {}, // 传给服务器的 header + cacheData: false, // 是否缓存 + requestInterceptor: (config: Config) => Config, + responseInterceptor: (response: RequestResponse) => RequestResponse, + transformData(data, response) { + // 处理响应内容异常 + if (isPlainObject(data)) { + if (data.code === '10000') { + return Promise.reject(data) + } + return data?.result ? data.result : data + } + return data + }, + // http 异常,和插件异常 + errorHandler(error) { + // 处理业务异常,例如上述 transformData 抛出的异常 + if (error.code) { + console.log(error.msg) + } + else if (error.response) { + // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围 + console.log(`服务异常:${error.response.status}`) + } + else { + // 请求异常 + console.log(error.msg || error.message || `请求失败`) + } + }, + }, +}) diff --git a/packages/create-fes-app/templates/app/h5/src/common/service.js b/packages/create-fes-app/templates/app/h5/src/common/service.ts similarity index 100% rename from packages/create-fes-app/templates/app/h5/src/common/service.js rename to packages/create-fes-app/templates/app/h5/src/common/service.ts diff --git a/packages/create-fes-app/templates/app/h5/src/common/utils.js b/packages/create-fes-app/templates/app/h5/src/common/utils.js deleted file mode 100644 index 27bf8a19..00000000 --- a/packages/create-fes-app/templates/app/h5/src/common/utils.js +++ /dev/null @@ -1,64 +0,0 @@ -// TODO -// 时间格式化 -// js 数字精度计算 -// 手机号、身份证号 等的校验 -// 数字分割 - -export function resetContainerHeight(dom) { - const originalHeight = document.body.clientHeight || document.documentElement.clientHeight; - - window.onresize = function () { - const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; - if (resizeHeight < originalHeight) { - // 恢复内容区域高度 - const container = document.querySelector(dom); - container.style.height = originalHeight; - } - }; -} - -export function resetInputBlur() { - const isWechat = window.navigator.userAgent.match(/MicroMessenger\/([\d.]+)/i); - if (!isWechat) return; - const wechatVersion = isWechat[1]; - const version = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/); - - // 如果设备类型为iOS 12+ 和wechat 6.7.4+,恢复成原来的视口 - if (+wechatVersion.replace(/\./g, '') >= 674 && +version[1] >= 12) { - window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight)); - } -} - -export function getQueryString(name) { - const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i'); - const r = window.location.search.substr(1).match(reg); - if (r != null) { - return decodeURIComponent(r[2]); - } - return null; -} - -export function simpleRequest(options) { - const xhr = new XMLHttpRequest(); - xhr.timeout = 3000; - if (options.type === 'GET') { - xhr.open(options.type, options.url, options.async || true); - xhr.send(null); - } else if (options.type === 'POST') { - xhr.open(options.type, options.url, options.async || true); - xhr.setRequestHeader('Content-Type', 'application/json'); - xhr.send(JSON.stringify(options.data || {})); - } - xhr.onreadystatechange = function () { - if (xhr.readyState === 4) { - if (xhr.status >= 200 && xhr.status < 300) { - options.successed(xhr.responseText); - } else { - options.failed && options.failed(xhr); - } - } - }; - xhr.ontimeout = function () { - options.failed && options.failed(xhr); - }; -} diff --git a/packages/create-fes-app/templates/app/h5/src/common/utils.ts b/packages/create-fes-app/templates/app/h5/src/common/utils.ts new file mode 100644 index 00000000..f5edc645 --- /dev/null +++ b/packages/create-fes-app/templates/app/h5/src/common/utils.ts @@ -0,0 +1,61 @@ +export function resetContainerHeight(dom) { + const originalHeight = document.body.clientHeight || document.documentElement.clientHeight + + window.onresize = function () { + const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight + if (resizeHeight < originalHeight) { + // 恢复内容区域高度 + const container = document.querySelector(dom) + container.style.height = originalHeight + } + } +} + +export function resetInputBlur() { + const isWechat = window.navigator.userAgent.match(/MicroMessenger\/([\d.]+)/i) + if (!isWechat) + return + const wechatVersion = isWechat[1] + const version = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/) + + // 如果设备类型为iOS 12+ 和wechat 6.7.4+,恢复成原来的视口 + if (+wechatVersion.replace(/\./g, '') >= 674 && +version[1] >= 12) { + window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight)) + } +} + +export function getQueryString(name) { + const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i') + const r = window.location.search.substr(1).match(reg) + if (r != null) { + return decodeURIComponent(r[2]) + } + return null +} + +export function simpleRequest(options) { + const xhr = new XMLHttpRequest() + xhr.timeout = 3000 + if (options.type === 'GET') { + xhr.open(options.type, options.url, options.async || true) + xhr.send(null) + } + else if (options.type === 'POST') { + xhr.open(options.type, options.url, options.async || true) + xhr.setRequestHeader('Content-Type', 'application/json') + xhr.send(JSON.stringify(options.data || {})) + } + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (xhr.status >= 200 && xhr.status < 300) { + options.successed(xhr.responseText) + } + else { + options.failed && options.failed(xhr) + } + } + } + xhr.ontimeout = function () { + options.failed && options.failed(xhr) + } +} diff --git a/packages/create-fes-app/templates/app/h5/src/pages/index.vue b/packages/create-fes-app/templates/app/h5/src/pages/index.vue index 5b275aa0..200f2d7f 100644 --- a/packages/create-fes-app/templates/app/h5/src/pages/index.vue +++ b/packages/create-fes-app/templates/app/h5/src/pages/index.vue @@ -1,43 +1,37 @@ - - + +