Измените vue-cli, чтобы упростить его использование.

Командная строка JavaScript Vue.js Webpack

Действительно ли vue-cli работает?

vue-cli — это скаффолдинг, объединяющий webpack+vue.Благодаря этому скаффолдингу мы можем легко создать проект vue и даже представить vuex и vue-router. Конфигурация webpack прозрачна для пользователей, и пользователям не нужно обращать внимание на детальную настройку webpack, тем самым повышая эффективность разработки.
Так действительно ли работает vue-cli? Давайте посмотрим на конфигурацию Webpack, созданную vue-cli. Во-первых, давайте посмотрим на конфигурацию файла записи:

 entry: {
    app: './src/main.js'
 }

Очевидно, что это однозаходный файл.В сочетании с vue-router можно реализовать одностраничный проект.Также очень удобно запаковывать.Есть только один html файл и соответствующий статический файл. Это преимущество также является недостатком, то есть если наш проект относительно большой, то вся логика и бизнес после упаковки находятся в одном файле. Есть несколько недостатков:

  1. Вся логика и бизнес находятся на одной странице, из-за чего страница загружается медленно
  2. Он очень медленный при упаковке и компиляции, что снижает эффективность разработки.
  3. Сильно связанный, при упаковке, если ошибка в одном месте, после упаковки и развёртывания весь сайт будет недоступен

Эти недостатки тоже довольно фатальные.Подумайте, если вы вызовете неопределенный метод при упаковке, а потом забудете опубликовать его во внешней сети, ваш начальник попросит вас с ним поболтать.

Исходя из вышеизложенного, как улучшить проект, созданный vue-cli? Конечно, ответ - разделить модуль. Модифицировать конфигурацию вебпака, упаковать и скомпилировать по модулю, чтобы вся логика не уместилась на одной странице. Разделение труда по разработке (один человек, один модуль).

Модернизация

1. Измените структуру каталогов:

Первоначальная структура:

После преобразования:

modules #所有模块文件夹
└───   assets #所有模块共用的静态文件
│    │   css
│    │   img
│    │   js
└───   common #所有模块公用的js代码,比如util.js
└───   components #所有模块公用vue子模块,比如header.vue
└───src #所有模块的源码文件夹
│   └─── module_name #模块名
│   │     └─── assets #该模块特有的静态文件
│   │           │   css
│   │           │   img
│   │           │   js
│   │     └─── components #该模块特用vue子模块
│   │     └─── router #该模块特用vue路由设置
│   │     └─── util #该模块特用共有类js
│   │     │  App.vue #容器
│   │     │  index.html #模块模板文件
│   │     │  main.js #模块入口文件,文件名不要修改!!!

Давайте сначала рассмотрим наиболее важную модификацию, то есть добавление папки модулей. Папка src под модулями содержит все модули. Несколько модулей имеют общие ресурсы и компоненты, и каждый модуль также имеет свои собственные ресурсы и компоненты. Для сравнения мы можем знать, что на самом деле он разделяет один модуль под src vue-cli на несколько модулей. Конечно, если вы хотите разработать каждый модуль в соответствии с режимом, сгенерированным исходным vue-cli, каждый модуль может быть большим или маленьким, но рекомендуется, чтобы каждый модуль не был слишком большим, иначе смысл подмодулей не будет отлично.

2. Измените файл конфигурации веб-пакета.

1. Измените файл записи webpack.base.config.js:

entry: {
    app: utils.getEntry() // 之前是./src/main.js
}

utils.getEntry получает входной файл текущего разрабатываемого модуля, поэтому нам нужен способ получить текущий работающий модуль.Моя идея здесь состоит в том, чтобы выполнить файл js, когда мы запускаем npm run sart/build , этот файл js может получить модуль что пользователь вводит, он хочет запустить через подсказку, а затем передать текущий запущенный модуль в качестве параметра при запуске сервера веб-пакетов.

2. Добавьте start.js/build.js Поэтому добавьте файл start.js в папку команд со следующим содержимым:

const exec = require('child_process').exec
const { prompt } = require('inquirer')
const chalk = require('chalk')
// 询问用户想运行哪个模块,放入module变量当中
const question = [
  {
    type: 'input',
    name: 'module',
    message: 'Module name:',
    validate (val) {
      if (val === '') {
        return 'Module name is required!'
      } 
      return true
    }

  }
]
module.exports = prompt(question).then(({module}) => {
  // 要运行的模块作为参数传给dev-server.js
  let cmdStr = `node ./build/dev-server.js ${module}`
  var child = exec(cmdStr)
  child.stdout.on('data', function(data) {
    console.log('stdout: ' + data)
  })
  child.stderr.on('data', function(err) {
    console.log(err)
    process.exit()
  })
})

Содержимое build.js следующее:


const { prompt } = require('inquirer')
const exec = require('child_process').exec
const chalk = require('chalk')
const ora = require('ora')

const question = [
  {
    type: 'input',
    name: 'module',
    message: 'Module name:',
    validate (val) {
      if (val === '') {
        return 'Module name is required!'
      } 
      return true
    }
  }
]

module.exports = prompt(question).then(({module}) => {
  const spinner = ora(`Building ${module}...`)
  
  spinner.start()
  // 要运行的模块作为参数传给build.js
  var child = exec(`node ./build/build.js ${module}`)
  child.stdout.on('data', (data) => {
    console.log('stdout: ' + data)
  })

  child.stderr.on('data', function(err) {
    console.log(chalk.red(`\n building ${module} error`))
    console.log(chalk.red(err))
    process.exit()
  })

  child.on('close', function(code) {
    spinner.stop()
    console.log(chalk.green('\n √ Build completed!'))    
  })
})

После передачи параметров при работающем узле его можно получить через process.argv, потому что мы передаем второй параметр, поэтому process.argv[2] — это введенное нами имя модуля.

3. Добавьте вспомогательный метод utils.js

// 获取项目路径根路径
exports.getProjectPath = () => {
  console.log(fs.realpathSync(process.cwd()))
  return fs.realpathSync(process.cwd())
}
// 获取当前开发模块的路径, 如modules/views/test/
exports.getModulePath = () => {
  var moduleName = process.argv[2]
  return exports.getProjectPath() + '/modules/src/' + moduleName
}

Итак, входной файл для получения нашего текущего модуля выглядит так:

//获取子模块的入口文件,如modules/views/test/main.js
exports.getEntry = () => {
  return exports.getModulePath() + '/main.js'
}

Файлы модулей, которые необходимо запаковать, следующие:

// 根据当前正在开发的模块,获取想要打包的文件
exports.getOuputFileName = () => {
  var moduleName = process.argv[2]
  return exports.getProjectPath() + `/../${moduleName}/index.html`
}

4. Конечно, когда мы упаковываем, запакованные файлы нужно размещать в разных модулях, не все они запакованы под один html, поэтому модифицируем файл webpack.prod.config.js, модифицируем плагин HtmlWebpackPlugin, и указываем Путь упаковки.

new HtmlWebpackPlugin({
  filename: utils.getOuputFileName(),
  template: utils.getModuleTemplate(),
  inject: true,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: true
  }

5. Измените файл package.json

"scripts": {
    "start": "node command/start.js cross-env NODE_ENV=develoment",
    "build": "node command/build.js"
  },

Таким образом, среда выполнения разработки в основном завершена, и она запускается/упаковывается в соответствии с каждым модулем.

Вы заметили, что на самом деле структура каталогов между нашими модулями похожа, каждый раз, когда мы создаем новый модуль, нам нужно копировать и вставлять его, что очень механизировано, поэтому мы можем его автоматизировать.

Добавлять модули автоматически

Основная идея заключается в том, что мы выкладываем фиксированную структуру модуля на гитхаб и прикрепляем собственную ссылку:GitHub.com/Вики Ли/touch…
Затем используйте download-git-repo, чтобы загрузить его локально. Конечно, нам нужно запросить у пользователя имя модуля, который он хочет создать, через подсказку, а затем загрузить его с github и загрузить в папку с этим модулем.

const download = require('download-git-repo')
const { prompt } = require('inquirer')
const ora = require('ora')
const chalk = require('chalk')
const fs = require('fs')

var question = [
  {
    type: 'input',
    name: 'moduleName',
    message: 'Please input module name:',
    validate(val) {
      if(val === ''){
        return 'Module name is required'
      }
      return true
    }
  }
]

module.exports = prompt(question).then(({moduleName}) => {

  //模块存在
  if (fs.existsSync(`./modules/src/${moduleName}`)) {
    console.log(chalk.red(`Module '${moduleName}' exists!`))
    process.exit()
  }

  const spinner = ora('Downloading template...')
  
  spinner.start()
  download(`VikiLee/module_tempate#master`, `./modules/src/${moduleName}`, (err) => {
    if (err) {
      console.log(chalk.red(err))
      process.exit()
    }
    spinner.stop()
    console.log(chalk.green('New module has been created successfully!'))
  })
})

Также измените файл package.json и добавьте команду создания

"scripts": {
    "create": "node command/create.js",
    "start": "node command/start.js cross-env NODE_ENV=develoment",
    "build": "node command/build.js"
  },

Таким образом, новые модули создаются автоматически.

гит-адрес:GitHub.com/Вики Ли/Веб…