Действительно ли 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 файл и соответствующий статический файл. Это преимущество также является недостатком, то есть если наш проект относительно большой, то вся логика и бизнес после упаковки находятся в одном файле. Есть несколько недостатков:
- Вся логика и бизнес находятся на одной странице, из-за чего страница загружается медленно
- Он очень медленный при упаковке и компиляции, что снижает эффективность разработки.
- Сильно связанный, при упаковке, если ошибка в одном месте, после упаковки и развёртывания весь сайт будет недоступен
Эти недостатки тоже довольно фатальные.Подумайте, если вы вызовете неопределенный метод при упаковке, а потом забудете опубликовать его во внешней сети, ваш начальник попросит вас с ним поболтать.
Исходя из вышеизложенного, как улучшить проект, созданный 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/Вики Ли/Веб…