Publish: 2018-12-18 12:51:58 Tags: vue vue-cli
# 导读
- Vue CLI 3 (opens new window)
- 如何使用Vue CLI 3加速你的开发工作流? (opens new window)
- 燃烧你的CLI (opens new window)
- 我在维护VUE CLI项目过程中学到了什么@VueConf CN 2018 (opens new window)
# vue-cli 基本要点
- 安装 (opens new window)
- 快速开发 (opens new window)
- 安装、插件和 Preset (opens new window)
- 配置参考 (opens new window)
- 插件开发指南 (opens new window)
- demo1:vue-cli-plugin-auto-router (opens new window)
- demo2:vue-cli-plugin-register-component (opens new window)
- 展望:
@kuaizi/vue-plugin-preset-kz
# 如何将 vue-cli 2.x
项目升级到 3.x
# Q: vue-cli 3.x
的项目依赖文件是什么?
.
├── README.md
├── babel.config.js √
├── node_modules
├── package.json √
├── public √
├── src √
├── tests
├── vue.config.js√
└── yarn.lock
其中主要的的文件主要有 package.json
和 vue.config.js
,babel.config.js
是可选独立文件配置及 package.json
中配置。
# Q: 如何升级已有项目的构建环境?
# 新建 vue.config.js
文件
在项目根目录新建 vue.config.js
,该文件是 vue-cli 3.x
运行读取配置入口及 vue ui
获取项目并识别配置信息。
const glob = require('glob')
const path = require('path')
const resolve = folder => path.resolve(__dirname, folder)
// 多页面入口路径
const PAGE_PATH = resolve('src/pages')
/**
* 获取多页面配置对象
* @param {String} entry 是否指定单入口
*/
function getPagesConfig (entry) {
const pages = {}
// 规范中定义每个单页文件结构
// index.html,main.js,App.vue
glob.sync(PAGE_PATH + '/*/index.js')
.forEach(filePath => {
const pageName = path.basename(path.dirname(filePath))
if (entry && entry !== pageName) return;
pages[pageName] = {
entry: filePath,
// 除了首页,其他按第二级目录输出
// 浏览器中直接访问/news,省去/news.html
// 指定单页根目录直接访问
filename: `${pageName === 'index' || entry ? '' : pageName + '/'}index.html`,
template: path.dirname(filePath) + '/index.html',
hash: true,
}
})
return pages
}
module.exports = {
// 读取2.x 的配置
baseUrl: process.env.NODE_ENV === 'production' ? webpackConf.build.assetsPublicPath : '/',
assetsDir: 'static',
// 禁用md5文件名,改查询参数 md5
filenameHashing: false,
productionSourceMap: false,
lintOnSave: true,
// 多页配置
pages: {
...pages
},
// 配置webpack
configureWebpack: {
cache: true,
plugins: [
new webpack.DefinePlugin({
// 定义你的环境变量
VUE_APP_ALLOW_ROUTES: JSON.stringify(argv.route)
})
],
performance: {
hints: false
},
optimization: {
// vue cli 3.x默认没有生产manifest.js文件
runtimeChunk: process.env.NODE_ENV === 'production' ? { name: 'manifest' } : false
}
},
// 扩展webpack配置
chainWebpack: config => {
// 移除 prefetch 插件
config.plugins.delete('preload')
config.plugins.delete('prefetch')
// 移除多页面preload,prefetch插件
Object.keys(pages).forEach(page => {
config.plugins.delete(`preload-${page}`)
config.plugins.delete(`prefetch-${page}`)
})
config.resolve
.alias
.set('vue$', 'vue/dist/vue.esm.js')
.set('assets', resolve('src/assets'))
.set('config', resolve('src/config'))
.set('components', resolve('src/components'))
.set('index', resolve('src/entries/index'))
.set('I18n', resolve('src/i18n'))
.set('Lib', resolve('src/lib'))
.set('API', resolve('src/lib/services'))
.set('mixins', resolve('src/lib/mixins'))
// 自动别名
Object.keys(devRouter)
.forEach(alias => {
config.resolve.alias.set(alias, devRouter[alias])
})
// 添加 css 全局变量资源插件
const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
types.forEach(
type => addStyleResource(config.module.rule('less').oneOf(type))
)
},
// 开发服务器配置
devServer: {
// port: `8081`,
port: webpackConf.dev.port,
proxy: webpackConf.dev.proxyTable
},
}
配置这么少就可以升级到 vue-cli 3.x
环境吗?当然还缺少 vue cli 3.x
构建运行的依赖包,我们要修改 package.json
,移除一些旧的依赖如 babel-loader
、webpack
等等一些,重新安装新的版本,新的版本大多数新的依赖包会指定 @scope
,比如 @babel/core@7.0.0-beta.47
, "@vue/cli-plugin-babel"
{
"name": "preset-demo",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
// 兼容旧的命令
"dev": "vue-cli-service serve --copy",
"review": "serve -s dist",
"test:e2e": "vue-cli-service test:e2e",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"axios": "^0.18.0",
"babel-polyfill": "^6.22.0",
"countup": "^1.8.2",
"echarts": "^4.2.0-rc.1",
"iview": "^3.1.1",
"lodash": "^4.17.11",
"normalize.css": "^8.0.0",
"nprogress": "^0.2.0",
"vue": "^2.5.17",
"vue-i18n": "^8.1.0",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
},
"devDependencies": {
// 构建环境依赖的包
"@vue/cli-plugin-babel": "^3.0.3",
"@vue/cli-plugin-e2e-nightwatch": "^3.0.4",
"@vue/cli-plugin-eslint": "^3.0.3",
"@vue/cli-plugin-unit-mocha": "^3.0.4",
"@vue/cli-service": "^3.0.3",
"@vue/test-utils": "^1.0.0-beta.20",
"chai": "^4.1.2",
"less": "^2.7.2",
"less-loader": "^3.0.0",
"serve": "^10.0.1",
"style-resources-loader": "1.2.1",
"vue-template-compiler": "^2.5.17"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {
"vue/no-parsing-error": [
2,
{
"x-invalid-end-tag": false
}
]
},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
# Q:貌似还是挺麻烦的,有没有更快的方式?
有的,通过自行写脚本命令去处理。
目标:
- 移除旧的配置文件,如
.babelrc
、.eslintrc
等 - 替换依赖包新的版本和添加新依赖,如
@vue/cli-plugin-babel
、babel-loader@8.04
等 - 新建文件
babel.config.js
、.env.local
等
# 1.移除旧的配置文件
移除旧的文件会容易造成旧的配置文件丢失,因此我们的做法就是将旧的配置文件重命名即可。
const renameFiles = ['.babelrc', '.eslintrc.js', 'package.json']
// rename old file
renameFiles.filter(f => fs.existsSync(resolveFile(f)))
.forEach(f => fs.renameSync(resolveFile(f), `_${f}`))
# 2. 替换依赖包新的版本和添加新依赖
我们将 vue-cli 3.x
生成的项目下的 package.json
作为配置文件模板,将新旧文件json合并到新的配置文件 package.json
。
const removeDependencies = ['vue-template-compiler', 'babel-core', 'vue-loader', 'vue-style-loader', 'url-loader', 'file-loader', 'webpack', 'webpack-bundle-analyzer', 'webpack-dev-middleware', 'webpack-hot-middleware', 'html-webpack-plugin', 'babel-plugin-transform-runtime', 'babel-polyfill']
const updatePkg = fs.readJSONSync(resolve(__dirname, './template/package.json'))
// Remove old Dependencies
removeDependencies.forEach(d => {
if (pkg.dependencies && pkg.dependencies[d]) {
delete pkg.dependencies[d]
} else if (pkg.devDependencies && pkg.devDependencies[d]) {
delete pkg.devDependencies[d]
}
})
// update package.json
fs.writeFileSync(
'./package.json',
JSON.stringify(
merge(
pkg,
updatePkg,
// 旧项目名称版本保留
{
name: pkg.name,
version: pkg.version,
author: pkg.author
}
),
null, 2)
)
# 新建文件
新的配置文件我们可以从模板目录中考到就项目目录中
const copyFiles = [
'.editorconfig',
'.eslintignore',
'babel.config.js',
'vue.config.js',
'.env.local',
'styleguide.config.js'
].map(file => ({
path: resolve(__dirname, `./template/${file}`),
name: file
}))
// fs.copyFileSync
copyFiles.forEach(file => {
fs.existsSync(file.path) && fs.copySync(file.path, resolveFile(file.name))
})
# kz update 一键升级
vue cli 2.x
项目一键升级 vue-cli 3.x
童叟无欺。只需
> kz update
# 期待
vue cli 3.x
插件社区将越来越完善,丰富好用的插件会越来越多,将优秀的插件组合不断的优化我们的构建工作流,同时我们也可以尝试开发自己合适的插件,不断的提高自己。