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 0000000..b5771e2 Binary files /dev/null and b/template/default-ts/static/logo.png differ diff --git a/template/default/main.js b/template/default/main.js index 0656173..21fcbeb 100755 --- a/template/default/main.js +++ b/template/default/main.js @@ -6,6 +6,6 @@ Vue.config.productionTip = false App.mpType = 'app' const app = new Vue({ - ...App + ...App }) app.$mount()