123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- const fs = require('fs')
- const path = require('path')
- const chokidar = require('chokidar')
- const jsbeautify = require('js-beautify')
- const beautify = function(fileName, str, config) {
- if (path.extname(fileName) === '.vue') {
- return jsbeautify.html(str, config)
- } else if (path.extname(fileName) === '.html') {
- return jsbeautify.html(str, config)
- } else if (path.extname(fileName) === '.js') {
- return jsbeautify.js(str, config)
- } else if (path.extname(fileName) === '.css') {
- return jsbeautify.css(str, config)
- } else if (path.extname(fileName) === '.scss') {
- return jsbeautify.css(str, config)
- } else if (path.extname(fileName) === '.sass') {
- return jsbeautify.css(str, config)
- } else if (path.extname(fileName) === '.compass') {
- return jsbeautify.css(str, config)
- } else {
- return str
- }
- }
- class AutoCodePlugin {
-
- constructor(options) {
-
- this.watcher = []
-
- class AutoFile {
- constructor(options) {
- this.watchQueue = options
-
- this.file = {}
- }
-
- setFileData(d) {
- if (!d.key) { console.error('缺少文件key信息'); return }
- this.file[d.key] = d
- }
-
- write(d) {
-
- const bodyData = Object.keys(this.file).reduce((add, d) => {
- return add += this.file[d].value
- }, '')
-
- const data = beautify(this.watchQueue.outPath, this.watchQueue.out ? this.watchQueue.out(bodyData, this.file) : bodyData,
- d.beauty ? d.beauty : { indent_size: 4 }
- )
-
- fs.writeFileSync(this.watchQueue.outPath, data)
- }
-
- delete(key) {
- delete this.file[key]
- }
-
- getLevel(p1, p2) {
- const p1Resolve = this.getPath(p1)
- const p2Resolve = this.getPath(p2)
- const replace = p2Resolve.replace(p1Resolve, '')
- return (replace.split('/').length) - 1
- }
-
- getPath(p) {
- return path.resolve(p).split(path.sep).join('/')
- }
- }
-
-
- const usePolling = options.some(d => d.maxlevel > 1)
-
- options.forEach(d => {
-
- (async d => {
-
- if (!d.inPath) { console.error('缺少inPath参数'); return }
- if (!d.templateEach) { console.error('缺少templateEach参数'); return }
-
- const level = Number(d.maxlevel) ? Number(d.maxlevel) : 1
-
- if (!d.out) d.out = template => template
-
- if (!d.outPath) {
- const p = path.resolve(d.inPath).split(path.sep)
- p[p.length] = 'index.js'
- d.outPath = p.join('/')
- }
-
- const autoFile = new AutoFile(d)
-
- const watchLevel = d.maxlevel ? d.maxlevel : 1
-
- const op = {
-
- depth: watchLevel,
- usePolling
- }
- if (usePolling) {
-
- op.interval = 1000
- op.binaryInterval = 1000
- }
-
- const watcher = chokidar.watch(d.inPath, op)
- this.watcher.push(watcher)
-
- autoFile.write(d)
-
- const addFile = (dirName, kind) => {
-
- const lev = autoFile.getLevel(d.inPath, dirName)
- if (lev <= level && lev > 0) {
-
- let product = (process.env.NODE_ENV === 'production')
-
- if (this.NODE_ENV) product = (process.env.NODE_ENV === this.NODE_ENV)
-
- const isEmptyDir = (kind === 'dir' && fs.readdirSync(path.resolve(dirName)).length === 0)
-
- if (!product && kind === 'dir' && isEmptyDir && d.addIndex) {
-
- d.addIndex.forEach(autoTempalte => {
- ((autoTempalte, dirName) => {
- if (autoTempalte.state === 'file') {
-
- let name = ''
- if (!autoTempalte.name) name = 'index.js'
- if (!autoTempalte.template) autoTempalte.template = () => ''
-
- if (Array.prototype.toString.call(autoTempalte.name) === '[object Function]') {
- name = autoTempalte.name(path.resolve(dirName).split(path.sep).pop(), autoFile.getPath(dirName))
- } else {
- name = autoTempalte.name
- }
- const template = beautify(name, autoTempalte.template(path.resolve(dirName).split(path.sep).pop(), autoFile.getPath(dirName)),
- d.beauty ? d.beauty : { indent_size: 4 }
- )
- fs.writeFileSync(path.join(path.resolve(dirName), name), template)
- } else {
-
- let name = ''
- if (!autoTempalte.name) return
-
- if (Array.prototype.toString.call(autoTempalte.name) === '[object Function]') {
- name = autoTempalte.name(path.resolve(dirName).split(path.sep).pop(), autoFile.getPath(dirName))
- } else {
- name = autoTempalte.name
- }
-
- fs.mkdirSync(path.join(path.resolve(dirName), name))
- }
- })(autoTempalte, dirName)
- })
- }
-
- autoFile.setFileData({
-
- key: autoFile.getPath(dirName),
-
- value: d.templateEach ? d.templateEach(path.resolve(dirName).split(path.sep).pop(), autoFile.getPath(dirName), kind) : ''
- })
- autoFile.write(d)
- }
- }
-
- const deleteFile = dirName => {
- autoFile.delete(autoFile.getPath(dirName))
- autoFile.write(d)
- }
-
- watcher.on('addDir', dirName => addFile(dirName, 'dir'))
-
- watcher.on('unlinkDir', dirName => deleteFile(dirName))
-
- if (d.useFile) {
-
- const sameFile = (p1, p2) => {
- return (path.resolve(p1) === path.resolve(p2))
- }
-
- watcher.on('add', dirName => {
- if (!sameFile(d.outPath, dirName)) addFile(dirName, 'file')
- })
-
- watcher.on('unlink', dirName => {
- if (!sameFile(d.outPath, dirName)) deleteFile(dirName)
- })
- }
-
- watcher.on('error', function(error) {
- console.error('webpack AutoCodePlugin Error happened: ', error)
- })
- })(d)
- })
- }
-
- apply(compiler) {
-
- let product = (process.env.NODE_ENV === 'production')
-
- if (this.NODE_ENV) product = (process.env.NODE_ENV === this.NODE_ENV)
-
- if (compiler.hooks.done) {
-
-
- compiler.hooks.done.tap('done', () => {
- console.log('webpack done')
- this.watcher.forEach(d => d.close())
- })
- } else if (product) {
-
- compiler.plugin('done', () => {
- console.log('webpack done')
- this.watcher.forEach(d => d.close())
- })
- }
- }
- }
- module.exports = AutoCodePlugin
|