From 5d6e63dca43de2b5e9d3b96d11ec421f80554758 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Fri, 4 Jan 2019 18:13:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20TypeScript=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generator.js | 142 ++++++++++++---------- preset.json | 24 ++-- prompts.js | 86 ++++++------- template/common-ts/tsconfig.json | 34 ++++++ template/common/babel.config.js | 36 +++--- template/common/postcss.config.js | 12 +- template/default-ts/App.vue | 19 +++ template/default-ts/main.ts | 6 + template/default-ts/manifest.json | 55 +++++++++ template/default-ts/pages.json | 16 +++ template/default-ts/pages/index/index.vue | 41 +++++++ template/default-ts/static/logo.png | Bin 0 -> 4023 bytes template/default/main.js | 2 +- 13 files changed, 329 insertions(+), 144 deletions(-) create mode 100644 template/common-ts/tsconfig.json create mode 100755 template/default-ts/App.vue create mode 100755 template/default-ts/main.ts create mode 100755 template/default-ts/manifest.json create mode 100755 template/default-ts/pages.json create mode 100644 template/default-ts/pages/index/index.vue create mode 100755 template/default-ts/static/logo.png diff --git a/generator.js b/generator.js index e946800..fbd89b1 100644 --- a/generator.js +++ b/generator.js @@ -2,85 +2,95 @@ const fs = require('fs') const path = require('path') const isBinary = require('isbinaryfile') -// const stripJsonComments = require('strip-json-comments') -async function generate(dir, files, base = '') { +async function generate (dir, files, base = '') { + const glob = require('glob') - const glob = require('glob') - - glob.sync('**/*', { - cwd: dir, - nodir: true - }).forEach(rawPath => { - const sourcePath = path.resolve(dir, rawPath) - const filename = path.join(base, rawPath) - - if (isBinary.sync(sourcePath)) { - files[filename] = fs.readFileSync(sourcePath) // return buffer - } else { - const content = fs.readFileSync(sourcePath, 'utf-8') -//不再移除注释,需要通过注释支持条件编译(之前移除注释,主要为了 ui.js 操作 json 文件) -// if (sourcePath.indexOf('manifest.json') !== -1 || sourcePath.indexOf('pages.json') !== -1) { -// files[filename] = JSON.stringify(JSON.parse(stripJsonComments(content)), null, 2) -// } else - if (filename.charAt(0) === '_' && filename.charAt(1) !== '_') { - files[`.${filename.slice(1)}`] = content - } else if (filename.charAt(0) === '_' && filename.charAt(1) === '_') { - files[`${filename.slice(1)}`] = content - } else { - files[filename] = content - } - } - }) + glob.sync('**/*', { + cwd: dir, + nodir: true + }).forEach(rawPath => { + const sourcePath = path.resolve(dir, rawPath) + const filename = path.join(base, rawPath) + if (isBinary.sync(sourcePath)) { + files[filename] = fs.readFileSync(sourcePath) // return buffer + } else { + const content = fs.readFileSync(sourcePath, 'utf-8') + if (filename.charAt(0) === '_' && filename.charAt(1) !== '_') { + files[`.${filename.slice(1)}`] = content + } else if (filename.charAt(0) === '_' && filename.charAt(1) === '_') { + files[`${filename.slice(1)}`] = content + } else { + files[filename] = content + } + } + }) } module.exports = (api, options, rootOptions) => { + if (options.template === 'default-ts') { // 启用 typescript + api.extendPackage(pkg => { + return { + dependencies: { + 'vue-class-component': '^6.3.2', + 'vue-property-decorator': '^7.2.0' + }, + devDependencies: { + '@babel/plugin-syntax-typescript': '^7.2.0', + '@dcloudio/types': '*', + '@vue/cli-plugin-typescript': '^3.2.2', + 'typescript': api.hasPlugin('eslint') ? '~3.1.1' : '^3.0.0' + } + } + }) + } - api.render(async function(files) { + api.render(async function (files) { + Object.keys(files).forEach(name => { + delete files[name] + }) - Object.keys(files).forEach(name => { - delete files[name] - }) + const template = options.repo || options.template - const template = options.repo || options.template + const base = 'src' - const base = 'src' + if (template === 'default') { + await generate(path.resolve(__dirname, './template/default'), files, base) + } else if (template === 'default-ts') { + await generate(path.resolve(__dirname, './template/common-ts'), files) + await generate(path.resolve(__dirname, './template/default-ts'), files, base) + } else { + const ora = require('ora') + const home = require('user-home') + const download = require('download-git-repo') - if (template === 'default') { - await generate(path.resolve(__dirname, './template/default'), files, base) - } else { - const ora = require('ora') - const home = require('user-home') - const download = require('download-git-repo') + const spinner = ora('模板下载中...') + spinner.start() - const spinner = ora('模板下载中...') - spinner.start() + const tmp = path.join(home, '.uni-app/templates', template.replace(/[/:]/g, '-'), 'src') - const tmp = path.join(home, '.uni-app/templates', template.replace(/[\/:]/g, '-'), 'src') + if (fs.existsSync(tmp)) { + try { + require('rimraf').sync(tmp) + } catch (e) { + console.error(e) + } + } - if (fs.existsSync(tmp)) { - try { - require('rimraf').sync(tmp) - } catch (e) { - console.error(e) - } - } + await new Promise((resolve, reject) => { + download(template, tmp, err => { + spinner.stop() + if (err) { + return reject(err) + } + resolve() + }) + }) - await new Promise((resolve, reject) => { - download(template, tmp, err => { - spinner.stop() - if (err) { - return reject(err) - } - resolve() - }) - }) + await generate(tmp, files, base) + } - await generate(tmp, files, base) - } - - await generate(path.resolve(__dirname, './template/common'), files) - - }) -} + await generate(path.resolve(__dirname, './template/common'), files) + }) +} diff --git a/preset.json b/preset.json index d3fe5ca..7ff4fbd 100644 --- a/preset.json +++ b/preset.json @@ -1,14 +1,14 @@ { - "useConfigFiles": false, - "plugins": { - "@dcloudio/vue-cli-plugin-uni": {}, - "@vue/cli-plugin-babel": { - "version": "3.1.1", - "presets": [ - ["@vue/app", { - "useBuiltIns": "entry" - }] - ] - } - } + "useConfigFiles": false, + "plugins": { + "@dcloudio/vue-cli-plugin-uni": {}, + "@vue/cli-plugin-babel": { + "version": "3.2.2", + "presets": [ + ["@vue/app", { + "useBuiltIns": "entry" + }] + ] + } + } } diff --git a/prompts.js b/prompts.js index 0b7b986..7b75d90 100644 --- a/prompts.js +++ b/prompts.js @@ -1,43 +1,47 @@ module.exports = [{ - type: 'list', - name: 'template', - message: '请选择 uni-app 模板', - choices: [{ - name: '默认模板', - value: 'default' - }, - { - name: 'Hello uni-app', - value: 'dcloudio/hello-uniapp' - }, - { - name: '登录模板', - value: 'dcloudio/uni-template-login' - }, - { - name: '看图模板', - value: 'dcloudio/uni-template-picture' - }, - { - name: '自定义模板', - value: 'custom' - } - ], - default: 'None', - }, - { - when: answers => answers.template === 'custom', - type: 'input', - name: 'repo', - message: '请输入自定义 uni-app 模板地址', - filter(input) { - return new Promise(function(resolve, reject) { - if (input) { - resolve(input) - } else { - reject('uni-app 模板地址不能为空') - } - }) - } - } + type: 'list', + name: 'template', + message: '请选择 uni-app 模板', + choices: [{ + name: '默认模板', + value: 'default' + }, + { + name: '默认模板(TypeScript)', + value: 'default-ts' + }, + { + name: 'Hello uni-app', + value: 'dcloudio/hello-uniapp' + }, + { + name: '登录模板', + value: 'dcloudio/uni-template-login' + }, + { + name: '看图模板', + value: 'dcloudio/uni-template-picture' + }, + { + name: '自定义模板', + value: 'custom' + } + ], + default: 'None' +}, +{ + when: answers => answers.template === 'custom', + type: 'input', + name: 'repo', + message: '请输入自定义 uni-app 模板地址', + filter (input) { + return new Promise(function (resolve, reject) { + if (input) { + resolve(input) + } else { + reject(new Error('uni-app 模板地址不能为空')) + } + }) + } +} ] diff --git a/template/common-ts/tsconfig.json b/template/common-ts/tsconfig.json new file mode 100644 index 0000000..21e6cf5 --- /dev/null +++ b/template/common-ts/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "strict": true, + "jsx": "preserve", + "importHelpers": true, + "moduleResolution": "node", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "experimentalDecorators":true, + "sourceMap": true, + "baseUrl": ".", + "types": [ + "webpack-env", + "@dcloudio/types/uni-app" + ], + "paths": { + "@/*": [ + "./src/*" + ] + }, + "lib": [ + "esnext", + "dom", + "dom.iterable", + "scripthost" + ] + }, + "exclude": [ + "node_modules", + "unpackage" + ] +} diff --git a/template/common/babel.config.js b/template/common/babel.config.js index 822747b..cb269b4 100644 --- a/template/common/babel.config.js +++ b/template/common/babel.config.js @@ -1,24 +1,24 @@ const plugins = [] process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui'] process.UNI_LIBRARIES.forEach(libraryName => { - plugins.push([ - 'import', - { - 'libraryName': libraryName, - 'customName': (name) => { - return `${libraryName}/lib/${name}/${name}` - } - } - ]) + plugins.push([ + 'import', + { + 'libraryName': libraryName, + 'customName': (name) => { + return `${libraryName}/lib/${name}/${name}` + } + } + ]) }) module.exports = { - presets: [ - [ - '@vue/app', - { - useBuiltIns: 'entry' - } - ] - ], - plugins + presets: [ + [ + '@vue/app', + { + useBuiltIns: 'entry' + } + ] + ], + plugins } diff --git a/template/common/postcss.config.js b/template/common/postcss.config.js index 4650551..7f0d45f 100644 --- a/template/common/postcss.config.js +++ b/template/common/postcss.config.js @@ -1,9 +1,9 @@ const pkg = require('./package.json') module.exports = { - plugins: [ - require('autoprefixer')({ - browsers: pkg.browserslist - }), - require('@dcloudio/vue-cli-plugin-uni/packages/postcss') - ] + plugins: [ + require('autoprefixer')({ + browsers: pkg.browserslist + }), + require('@dcloudio/vue-cli-plugin-uni/packages/postcss') + ] } diff --git a/template/default-ts/App.vue b/template/default-ts/App.vue new file mode 100755 index 0000000..2a18a4d --- /dev/null +++ b/template/default-ts/App.vue @@ -0,0 +1,19 @@ + + + diff --git a/template/default-ts/main.ts b/template/default-ts/main.ts new file mode 100755 index 0000000..255135b --- /dev/null +++ b/template/default-ts/main.ts @@ -0,0 +1,6 @@ +import Vue from 'vue' +import App from './App.vue' + +Vue.config.productionTip = false + +new App().$mount() diff --git a/template/default-ts/manifest.json b/template/default-ts/manifest.json new file mode 100755 index 0000000..ed91a0e --- /dev/null +++ b/template/default-ts/manifest.json @@ -0,0 +1,55 @@ +{ + "name": "", + "appid": "", + "description": "", + "versionName": "1.0.0", + "versionCode": "100", + "transformPx":false, + "app-plus": { /* 5+App特有相关 */ + "modules": { /* 模块配置 */ + + }, + "distribute": { /* 应用发布信息 */ + "android": { /* android打包配置 */ + "permissions": ["", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "ios": { /* ios打包配置 */ + + }, + "sdkConfigs": { /* SDK配置 */ + + } + } + }, + "quickapp": { /* 快应用特有相关 */ + + }, + "mp-weixin": { /* 小程序特有相关 */ + "appid": "", + "setting" : { + "urlCheck" : true + } + } +} diff --git a/template/default-ts/pages.json b/template/default-ts/pages.json new file mode 100755 index 0000000..bf32f65 --- /dev/null +++ b/template/default-ts/pages.json @@ -0,0 +1,16 @@ +{ + "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages + { + "path": "pages/index/index", + "style": { + "navigationBarTitleText": "uni-app" + } + } + ], + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "uni-app", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8" + } +} diff --git a/template/default-ts/pages/index/index.vue b/template/default-ts/pages/index/index.vue new file mode 100644 index 0000000..4382098 --- /dev/null +++ b/template/default-ts/pages/index/index.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/template/default-ts/static/logo.png b/template/default-ts/static/logo.png new file mode 100755 index 0000000000000000000000000000000000000000..b5771e209bb677e2ebd5ff766ad5ee11790f305a GIT binary patch literal 4023 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 SYs}WS&%*SCNx89m_