diff --git a/packages/plugin-react/lib/add-component.js b/packages/plugin-react/lib/add-component.js index 1c70a0d9..da53d2f0 100644 --- a/packages/plugin-react/lib/add-component.js +++ b/packages/plugin-react/lib/add-component.js @@ -6,19 +6,10 @@ const Generator = require('yeoman-generator'); const { basename, join } = require('path'); const logger = require('@a8k/cli-utils/logger'); const fs = require('fs-extra'); -const loadConfig = require('@a8k/cli-utils/load-config'); +const { toArray, createExampleComponent } = require('./heper'); // logger.setOptions({ debug: true }); -if (!semver.satisfies(process.version, '>= 8.0.0')) { - console.error(chalk.red('✘ The generator will only work with Node v8.0.0 and up!')); - process.exit(1); -} - -const toArray = a => { - return Array.isArray(a) ? a : [a]; -}; - class CreateGenerator extends Generator { constructor(args, opts) { super(args, opts); @@ -56,7 +47,7 @@ class CreateGenerator extends Generator { choices: this.pagesList, }, ]); - this.props.filepath = `src/pages/${pagePath}/components`; + this.props.filepath = `src/pages/${pagePath}`; } else { this.props.filepath = 'src/components'; } @@ -79,22 +70,6 @@ class CreateGenerator extends Generator { this.props.name = name; } - _createExampleComponent() { - const { name, filepath } = this.props; - [ - ['common/componentTemplate/index.jsx.tpl', `${filepath}/${name}/index.jsx`], - ['common/componentTemplate/index.scss.tpl', `${filepath}/${name}/index.scss`], - ].forEach(([src, dest]) => { - src = this.templatePath(...toArray(src)); - dest = this.destinationPath(...toArray(dest)); - this.fs.copyTpl(src, dest, { - name, - className: `x-component-${name.toLowerCase()}`, - useConnect: this.props.type === 'page', - }); - }); - } - _copyFiles(files = []) { files.forEach(([src, dest]) => { src = toArray(src); @@ -113,21 +88,21 @@ class CreateGenerator extends Generator { writing() { logger.debug(`this.props: ${JSON.stringify(this.props)}`); - this._createExampleComponent(); + createExampleComponent(this, this.props.filepath, this.props.name, this.props.type === 'page'); } } -module.exports = baseDir => { - const config = loadConfig.loadSync({ - files: ['.imtrc.js', 'imtrc.js', 'a8k.config.js', 'package.json'], - cwd: baseDir, - packageKey: 'a8k', - }); +module.exports = ({ config, options }) => { + if (!semver.satisfies(process.version, '>= 8.0.0')) { + console.error(chalk.red('✘ The generator will only work with Node v8.0.0 and up!')); + process.exit(1); + } + return new Promise(resolve => { new CreateGenerator( { name: 'basic', - env: { cwd: baseDir }, + env: { cwd: options.baseDir }, resolved: __filename, }, { a8kconfig: config } diff --git a/packages/plugin-react/lib/add-page.js b/packages/plugin-react/lib/add-page.js new file mode 100644 index 00000000..5e64f8bf --- /dev/null +++ b/packages/plugin-react/lib/add-page.js @@ -0,0 +1,89 @@ +const path = require('path'); +const semver = require('semver'); +const chalk = require('chalk'); + +const Generator = require('yeoman-generator'); +const { basename, join } = require('path'); +const logger = require('@a8k/cli-utils/logger'); +const { PROJECT_MODE_SINGLE } = require('a8k/lib/const'); +const { toArray, createMultiExamplePage, createSingleExamplePage } = require('./heper'); + +// logger.setOptions({ debug: true }); + +class CreateGenerator extends Generator { + constructor(args, opts) { + super(args, opts); + + this.name = basename(process.cwd()); + this.props = { + config: opts.a8kconfig, + }; + + this.pagesPath = path.resolve(args.env.cwd, 'src/pages'); + + this.sourceRoot(join(__dirname, '../templates/')); + } + + async prompting() { + const { name } = await this.prompt([ + { + name: 'name', + message: '页面名称(使用下划线分割单词)', + type: 'input', + validate(input) { + if (!input) { + return '请输入组件名称'; + } + if (!/^([a-z_\d]+)$/.test(input)) { + return '格式错误(支持英文小写字母、数字、下划线)'; + } + return true; + }, + }, + ]); + this.props.name = name; + } + + _copyFiles(files = []) { + files.forEach(([src, dest]) => { + src = toArray(src); + dest = toArray(dest); + this.fs.copy(this.templatePath(...src), this.destinationPath(...dest)); + }); + } + + _copyTpls(files = []) { + files.forEach(([src, dest]) => { + src = toArray(src); + dest = toArray(dest); + this.fs.copyTpl(this.templatePath(...src), this.destinationPath(...dest), this.props); + }); + } + + writing() { + logger.debug(`this.props: ${JSON.stringify(this.props)}`); + if (this.props.config.mode === PROJECT_MODE_SINGLE) { + createSingleExamplePage(this, this.props.name); + } else { + createMultiExamplePage(this, this.props.name); + } + } +} + +module.exports = ({ config, options }) => { + if (!semver.satisfies(process.version, '>= 8.0.0')) { + console.error(chalk.red('✘ The generator will only work with Node v8.0.0 and up!')); + process.exit(1); + } + + return new Promise(resolve => { + new CreateGenerator( + { + name: 'basic', + env: { cwd: options.baseDir }, + resolved: __filename, + }, + { a8kconfig: config } + ).run(resolve); + }); +}; diff --git a/packages/plugin-react/lib/create.js b/packages/plugin-react/lib/create.js index a200ca34..12c8dd41 100644 --- a/packages/plugin-react/lib/create.js +++ b/packages/plugin-react/lib/create.js @@ -4,18 +4,15 @@ const chalk = require('chalk'); const Generator = require('yeoman-generator'); const { basename, join } = require('path'); const logger = require('@a8k/cli-utils/logger'); +const { + toArray, + createExampleComponent, + createMultiExamplePage, + createSingleExamplePage, +} = require('./heper'); // debug.enabled = true; -if (!semver.satisfies(process.version, '>= 8.0.0')) { - console.error(chalk.red('✘ The generator will only work with Node v8.0.0 and up!')); - process.exit(1); -} - -const toArray = a => { - return Array.isArray(a) ? a : [a]; -}; - class CreateGenerator extends Generator { constructor(args, opts) { super(args, opts); @@ -104,8 +101,8 @@ class CreateGenerator extends Generator { async _singlePage() { this._copyFiles([['single/src', 'src']]); this._copyTpls([['single/src/index.html', 'src/index.html']]); - this._createExampleComponent(); - this._createSingleExamplePage(); + createExampleComponent(this, 'src/components', 'Example', false); + createSingleExamplePage(this, 'index'); } async _multiPages() { @@ -117,60 +114,8 @@ class CreateGenerator extends Generator { this._copyFiles([['multi/app', 'app']]); this._copyTpls([['multi/nodemon.json', 'nodemon.json']]); } - this._createExampleComponent(); - this._createMultiExamplePage(); - } - - _createExampleComponent(name = 'Example') { - [ - ['common/componentTemplate/index.jsx.tpl', `src/components/${name}/index.jsx`], - ['common/componentTemplate/index.scss.tpl', `src/components/${name}/index.scss`], - ].forEach(([src, dest]) => { - src = this.templatePath(...toArray(src)); - dest = this.destinationPath(...toArray(dest)); - this.fs.copyTpl(src, dest, { - name, - className: `x-component-${name.toLowerCase()}`, - useConnect: false, - }); - }); - } - - _createMultiExamplePage(name = 'index') { - [ - ['multi/pageTemplate/action_creators.js', `src/pages/${name}/action_creators.js`], - ['multi/pageTemplate/action_types.js', `src/pages/${name}/action_types.js`], - ['multi/pageTemplate/index.html', `src/pages/${name}/index.html`], - ['multi/pageTemplate/index.jsx', `src/pages/${name}/index.jsx`], - ['multi/pageTemplate/index.scss', `src/pages/${name}/index.scss`], - ['multi/pageTemplate/ProviderContainer.jsx', `src/pages/${name}/ProviderContainer.jsx`], - ['multi/pageTemplate/reducer.js', `src/pages/${name}/reducer.js`], - ['multi/pageTemplate/store.js', `src/pages/${name}/store.js`], - ].forEach(([src, dest]) => { - src = toArray(src); - dest = toArray(dest); - this.fs.copyTpl(this.templatePath(...src), this.destinationPath(...dest), { - name, - className: `x-page-${name.toLowerCase()}`, - }); - }); - } - - _createSingleExamplePage(name = 'index') { - [ - ['single/pageTemplate/action_creators.js', `src/pages/${name}/action_creators.js`], - ['single/pageTemplate/action_types.js', `src/pages/${name}/action_types.js`], - ['single/pageTemplate/index.jsx', `src/pages/${name}/index.jsx`], - ['single/pageTemplate/index.scss', `src/pages/${name}/index.scss`], - ['single/pageTemplate/reducer.js', `src/pages/${name}/reducer.js`], - ].forEach(([src, dest]) => { - src = toArray(src); - dest = toArray(dest); - this.fs.copyTpl(this.templatePath(...src), this.destinationPath(...dest), { - name, - className: `x-page-${name.toLowerCase()}`, - }); - }); + createExampleComponent(this, 'src/components', 'Example', false); + createMultiExamplePage(this, 'index'); } _commonFiles() { @@ -222,6 +167,10 @@ class CreateGenerator extends Generator { } module.exports = projectDir => { + if (!semver.satisfies(process.version, '>= 8.0.0')) { + console.error(chalk.red('✘ The generator will only work with Node v8.0.0 and up!')); + process.exit(1); + } return new Promise(resolve => { new CreateGenerator({ name: 'basic', diff --git a/packages/plugin-react/lib/heper.js b/packages/plugin-react/lib/heper.js new file mode 100644 index 00000000..bf7eef60 --- /dev/null +++ b/packages/plugin-react/lib/heper.js @@ -0,0 +1,69 @@ +const toArray = a => { + return Array.isArray(a) ? a : [a]; +}; + +/** + * + * @param {Generator} context Generator 上下文 + * @param {string} dist 目标目录:src/components,src/pages/xxx/components + * @param {string} name 组件名称 + * @param {boolean} useConnect 是否使用connect + */ +const createExampleComponent = (context, dist, name, useConnect) => { + [ + ['common/componentTemplate/index.jsx.tpl', `${dist}/${name}/index.jsx`], + ['common/componentTemplate/index.scss.tpl', `${dist}/${name}/index.scss`], + ].forEach(([src, dest]) => { + src = context.templatePath(...toArray(src)); + dest = context.destinationPath(...toArray(dest)); + context.fs.copyTpl(src, dest, { + name, + className: `x-component-${name.toLowerCase()}`, + useConnect, + }); + }); +}; + +const createMultiExamplePage = (context, name) => { + [ + ['multi/pageTemplate/action_creators.js', `src/pages/${name}/action_creators.js`], + ['multi/pageTemplate/action_types.js', `src/pages/${name}/action_types.js`], + ['multi/pageTemplate/index.html', `src/pages/${name}/index.html`], + ['multi/pageTemplate/index.jsx', `src/pages/${name}/index.jsx`], + ['multi/pageTemplate/index.scss', `src/pages/${name}/index.scss`], + ['multi/pageTemplate/ProviderContainer.jsx', `src/pages/${name}/ProviderContainer.jsx`], + ['multi/pageTemplate/reducer.js', `src/pages/${name}/reducer.js`], + ['multi/pageTemplate/store.js', `src/pages/${name}/store.js`], + ].forEach(([src, dest]) => { + src = toArray(src); + dest = toArray(dest); + context.fs.copyTpl(context.templatePath(...src), context.destinationPath(...dest), { + name, + className: `x-page-${name.toLowerCase()}`, + }); + }); +}; + +const createSingleExamplePage = (context, name) => { + [ + ['single/pageTemplate/action_creators.js', `src/pages/${name}/action_creators.js`], + ['single/pageTemplate/action_types.js', `src/pages/${name}/action_types.js`], + ['single/pageTemplate/index.jsx', `src/pages/${name}/index.jsx`], + ['single/pageTemplate/index.scss', `src/pages/${name}/index.scss`], + ['single/pageTemplate/reducer.js', `src/pages/${name}/reducer.js`], + ].forEach(([src, dest]) => { + src = toArray(src); + dest = toArray(dest); + context.fs.copyTpl(context.templatePath(...src), context.destinationPath(...dest), { + name, + className: `x-page-${name.toLowerCase()}`, + }); + }); +}; + +module.exports = { + toArray, + createExampleComponent, + createMultiExamplePage, + createSingleExamplePage, +}; diff --git a/packages/plugin-react/lib/plugin-react.js b/packages/plugin-react/lib/plugin-react.js index f7825792..813cf897 100644 --- a/packages/plugin-react/lib/plugin-react.js +++ b/packages/plugin-react/lib/plugin-react.js @@ -1,13 +1,14 @@ const getNpmCommand = require('@a8k/cli-utils/npm'); +const logger = require('@a8k/cli-utils/logger'); const fs = require('fs-extra'); const inquirer = require('inquirer'); const ora = require('ora'); const path = require('path'); const shell = require('shelljs'); const util = require('util'); -const { PROJECT_MODE_SINGLE, PROJECT_MODE_MULTI } = require('a8k/lib/const'); const createGenerator = require('./create'); const addComponent = require('./add-component'); +const addPage = require('./add-page'); exports.apply = context => { const { config, options } = context; @@ -38,6 +39,7 @@ exports.apply = context => { } await createGenerator(projectDir); + await context.hooks.invokePromise('afterCreate', context); console.log('✨ File Generate Done'); const spinner = ora('安装依赖').start(); @@ -45,6 +47,12 @@ exports.apply = context => { shell.cd(projectDir); await util.promisify(shell.exec)(`${npmCmd} i`, { silent: true }); spinner.succeed('安装依赖完毕'); + try { + await util.promisify(shell.exec)('npx eslint --fix src a8k.config.js --ext jsx,js'); + spinner.succeed('执行eslint校验'); + } catch (e) { + logger.warn('执行eslint校验失败'); + } await context.hooks.invokePromise(context); spinner.succeed('项目创建完毕'); }); @@ -54,23 +62,16 @@ exports.apply = context => { .alias('p') .description('新建页面') .action(async () => { - switch (config.mode) { - case PROJECT_MODE_MULTI: - break; - case PROJECT_MODE_SINGLE: - console.log('xxxx'); - break; - default: - break; - } + addPage(context); + await context.hooks.invokePromise('afterAddPage', context); }); context .registerCommand('component') .alias('c') .description('新建组件') .action(async () => { - // const { baseDir } = require(path.join(process.cwd(), './a8k.config.js')); - addComponent(path.resolve(process.cwd())); + addComponent(context); + await context.hooks.invokePromise('afterAddComponent', context); }); }; exports.name = 'builtin:react'; diff --git a/packages/plugin-react/templates/common/a8k.config.js b/packages/plugin-react/templates/common/a8k.config.js index 2655e9af..47f699ac 100644 --- a/packages/plugin-react/templates/common/a8k.config.js +++ b/packages/plugin-react/templates/common/a8k.config.js @@ -59,7 +59,8 @@ module.exports = { }, <% } %> // 修改webpack配置文件 - chainWebpack(config) { + chainWebpack() { + }, plugins: [], }; diff --git a/packages/plugin-react/templates/multi/pageTemplate/index.html b/packages/plugin-react/templates/multi/pageTemplate/index.html index ec27c027..a91ae208 100644 --- a/packages/plugin-react/templates/multi/pageTemplate/index.html +++ b/packages/plugin-react/templates/multi/pageTemplate/index.html @@ -1 +1,2 @@ {% extends "../../assets/template.html" %} +{% block timingId %}88888-8-8{% endblock %} \ No newline at end of file diff --git a/packages/plugin-react/templates/multi/src/assets/template.html b/packages/plugin-react/templates/multi/src/assets/template.html index ea1bb4eb..3cb034b3 100644 --- a/packages/plugin-react/templates/multi/src/assets/template.html +++ b/packages/plugin-react/templates/multi/src/assets/template.html @@ -9,15 +9,15 @@ - + {% block title %}{% endblock %} - + - + - +