Skip to content

Commit

Permalink
Merge pull request #12 from BiYuqi/use-node-create-page
Browse files Browse the repository at this point in the history
Use node create page
  • Loading branch information
BiYuqi committed Feb 6, 2019
2 parents c877de3 + 5681d00 commit 65737bb
Show file tree
Hide file tree
Showing 16 changed files with 279 additions and 24 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
## 迭代日志
2019.02.06
* 新增命令行创建页面[README](./bin/README.md)

2018.10.22
* 增加个性化模板案例[layoutAuth](https://github.com/BiYuqi/webpack-seed/tree/master/src/layout/layoutAuth)

Expand Down
3 changes: 2 additions & 1 deletion INSTRODUCTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ eg:
* 页面支持ejs模板开发,模板文件建议统一规划到一个文件夹(本项目目前放在[templates/](https://github.com/BiYuqi/webpack-seed/tree/master/src/templates)注:views/目录只能放页面模块,不可放模板) 具体请看 [模板](https://github.com/BiYuqi/webpack-seed/blob/master/src/templates/index.test.ejs) [使用](https://github.com/BiYuqi/webpack-seed/blob/master/src/views/index/index.js#L7)
## 目录结构 (Source)
* **bin**
* ---命令行配置文件,支持创建页面
* **build/**
* ---config.js 开发,打包基础配置(包含输出文件名, 路径配置等都在此配置)
* ---utils.js 多入口,多页面基础配置
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@
- 支持ES6编写源码,编译生成生产代码
- 开发(生产)环境代码自动注入页面, 专注于开发
- 编译后的程序不依赖于外部的资源, 可自动替换线上资源地址
- 开箱即用的单元测试环境(当然了,测试用例还得您自己写)
- 开箱即用的单元测试环境(当然了,测试用例还得您自己写
- ...

注:本项目不依赖Jquery. lib库引入jquery仅仅是为了演示该项目可以自动加载第三方脚本作为链接使用, 如果不需要,在src/common/libs.js配置文件中移除即可


## What do we want?

展示下页面呈现结果(页面资源加载逻辑),这可能就是我们想要的模块化吧:sparkles:
Expand Down Expand Up @@ -131,6 +132,14 @@ npm run ci
```
注意:本项目有提交代码前跑lint的功能,请看package.json`husky`字段配置

**支持命令行创建页面**

该命令支持创建页面四件套,帮助快速构建页面,不再一个文件一个文件写
[README](./bin/README.md)
```js
npm run new
```

## Coding Standard

[INSTRODUCTION](https://github.com/BiYuqi/webpack-seed/blob/master/INSTRODUCTION.md)
Expand Down
23 changes: 23 additions & 0 deletions bin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## 运行

创建新页面, 暂时支持两种模板
```js
npm run new
```
## screenShots
![](./screenShots/step.png)
![](./screenShots/screen.png)

## 模板
页面种类config配置即可

```js
目前:standed & notStanded
standed: 含有header footer
notStanded: 不含有header footer
```

## TODO

- [ ] 支持多目录嵌套生成
- [ ] 重构代码
71 changes: 71 additions & 0 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#! /usr/bin/env node

const fs = require('fs')
const path = require('path')
const program = require('commander')
const inquirer = require('inquirer')
const handlebars = require('handlebars')

const descCheck = require('./middleware/desc')
const { getFileName, log, successLog, errorLog } = require('./utils/utils')
const templeteConfig = require('./templates/config')
const writeFiles = require('./middleware/writefile')

program.action(() => {
log(`
0. 模块是基于views层创建.
1. 文件名不包含数字, 模块名即为文件名, 不能与页面现存重复.
2. 常规的就是直接输入文件名(模块名)即可自动创建页面.
3. e.g. 输入new-page 即可交互式创建该页面.
4. 创建嵌套页面, 需要输入嵌套规则 path/path/path.[暂未实现 => TODO]
`)
inquirer
.prompt([
{
name: 'description',
message: '请输入页面模块名称',
validate: descCheck
},
{
type: 'list',
name: 'templete',
message: '请选择页面模板',
choices: Object.keys(templeteConfig)
},
{
name: 'title',
message: '请输入页面title(非必填,建议填写)'
}
])
.then(answer => {
const { description, templete, title } = answer
const { fileName } = getFileName(description)

fs.mkdir(path.resolve(__dirname, '../', `src/views/${fileName}`), err => {
if (err) {
errorLog(err)
throw err
}
successLog('创建目录成功')
const tplContent = fs.readFileSync(path.resolve(__dirname, 'templates/tpl.txt')).toString()
const indexContent = fs.readFileSync(path.resolve(__dirname, 'templates/index.txt')).toString()

const parseTplResult = handlebars.compile(tplContent)({
pageTitle: title ? title : '',
templateDir: templeteConfig[templete].dir,
templateName: templeteConfig[templete].name,
fileName
})
const parseIndexResult = handlebars.compile(indexContent)({
fileName
})

writeFiles(`src/views/${fileName}/tpl.js`, parseTplResult)
writeFiles(`src/views/${fileName}/index.js`, parseIndexResult)
writeFiles(`src/views/${fileName}/${fileName}.ejs`)
writeFiles(`src/views/${fileName}/${fileName}.scss`)
successLog('文件创建成功')
})
})
})
program.parse(process.argv)
18 changes: 18 additions & 0 deletions bin/middleware/desc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { getDirectoryName } = require('../utils/utils')

const hasNest = name => {
return name.indexOf('/') > -1
}

const descCheck = desc => {
if (!/^[a-z_-]+$/.test(desc)) {
return '文件仅支持字母,下划线,中划线,暂不支持数字, 且不能为空'
}
const result = getDirectoryName()
if (result.includes(desc)) {
return '文件夹已存在,请换个文件名重试'
}
return true
}

module.exports = descCheck
8 changes: 8 additions & 0 deletions bin/middleware/writefile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const path = require('path')
const fs = require('fs')
const { log } = require('../utils/utils')

module.exports = (address, template = '') => {
fs.writeFileSync(path.resolve(__dirname, '../../', address), template, 'utf8')
log('create: ' + address)
}
Binary file added bin/screenShots/screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added bin/screenShots/step.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions bin/templates/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// 模板文件夹名字 & 文件名
// 供生成页面使用
module.exports = {
standed: {
dir: 'layout',
name: 'layout'
},
notStanded: {
dir: 'layoutAuth',
name: 'layoutAuth'
}
}
6 changes: 6 additions & 0 deletions bin/templates/index.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* 默认样式+默认逻辑
*/
import '@/common/js/base'
import './{{fileName}}.scss'
import __ from 'utils/dom'
7 changes: 7 additions & 0 deletions bin/templates/tpl.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const content = require('./{{fileName}}.ejs')
const layout = require('layout/{{templateDir}}/{{templateName}}.js')
const pageTitle = '{{pageTitle}}'

const temp = layout.init({ pageTitle }).run(content())

module.exports = temp
30 changes: 30 additions & 0 deletions bin/utils/getdirname.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const fs = require('fs')
const path = require('path')

const matchName = str => str.match(/[^\/]+$/)[0]

const readdir = dir => {
let results = [path.resolve(dir)]
const files = fs.readdirSync(dir, 'utf8')
files.forEach(file => {
file = path.resolve(dir, file)

const stats = fs.statSync(file)
if (stats.isFile()) {
// results.push(file)
} else if (stats.isDirectory()) {
results = results.concat(readdir(file))
}
})
return results
}
const getDirectoryName = () => {
const filePaths = readdir(path.resolve(__dirname, '../../', 'src/views/'))
return filePaths.map(item => {
return matchName(item)
})
}

module.exports = {
getDirectoryName
}
39 changes: 39 additions & 0 deletions bin/utils/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const chalk = require('chalk')
const { getDirectoryName } = require('./getdirname')

const mkdir = () => {
return new Promise((resolve, reject) => {
fs.mkdir(dir, err => {
if (err) {
resolve(false)
} else {
resolve(true)
}
})
})
}

const getFileName = name => {
const result = name.split('/')
const directory = result.slice(0, result.length - 1)
const fileName = result.slice(-1)
return {
directory,
fileName
}
}

const log = message => console.log(chalk.green(`${message}`))

const successLog = message => console.log(chalk.magentaBright(`${message}`))

const errorLog = error => console.log(chalk.red(`${error}`))

module.exports = {
mkdir,
getFileName,
getDirectoryName,
log,
successLog,
errorLog
}
65 changes: 44 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 65737bb

Please sign in to comment.