1 安装vue-cli3.0
0 淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
1 安装vue-cli
npm install -g @vue/cli
# OR
yarn global add @vue/cli
2 查看版本
vue --version
3 vue-cli构建项目
vue create vue-demo
选择默认即可、可起服务
4 目录结构
├── README.md # 说明
|-- dist # 打包后文件夹
├── babel.config.js # babel语法编译
├── package-lock.json
├── package.json
├── public # 静态文件夹
│ ├── favicon.ico
│ └── index.html #入口页面
└── src # 源码目录
├── App.vue - 页面
├── assets - 静态目录
│ └── logo.png
├── components 组件
│ └── HelloWorld.vue
└── main.js # 入口文件,加载公共组件
|-- vue.config.js # 配置文件
|-- .eslintrc.js # ES-lint校验
|-- .gitignore # git忽略上传的文件格式
|-- babel.config.js # babel语法编译
|-- package.json # 项目基本信息
标准的vue目录结构
2 环境变量和模式
0 介绍
在npm下实际上vue-cli 启动的时候,已经确定了环境变量与模式,这样方便代码的构建
打开package.json后
我们这边描述的环境就在scripts中
1 模式
是 Vue CLI 项目中一个重要的概念。默认情况下,一个 Vue CLI 项目有三个模式:
-
development
模式用于vue-cli-service serve
-
production
模式用于vue-cli-service build
和vue-cli-service test:e2e
-
test
模式用于vue-cli-service test:unit
你可以通过传递
--mode
选项参数为命令行覆写默认的模式。例如,如果你想要在构建命令中使用开发环境变量,请在你的package.json
脚本中加入
"dev-build": "vue-cli-service build --mode development",
2 调用
那么我们在代码里面怎么调用呢、和他的应用场景呢
process.env.NODE_ENV
这样我们就可以获取他的环境变量
3 场景
我们在src目录下新建一个config
构建一个env.js的目录
let baseUrl = '';
const env = process.env
if (env.NODE_ENV == 'development') {
baseUrl = `http://192.168.1.1`; // 开发环境地址
} else if (env.NODE_ENV == 'production') {
baseUrl = `http://192.168.1.2`; //生产环境地址
} else if (env.NODE_ENV == 'test') {
baseUrl = `http://192.168.1.3`; //测试环境地址
}
export {
baseUrl,
env
}
那么这样我们就可以直接使用不同环境下的
3 IE兼容处理、移除console
npm install @babel/polyfill -s
npm install babel-plugin-transform-remove-console -s
在babel.config.js中配置如下
const plugins = []
if (process.env.NODE_ENV === 'production') {
// 移除console.log
plugins.push('transform-remove-console')
}
module.exports = {
presets: [
['@vue/app', {
polyfills: [
'es6.array.iterator',
'es6.promise',
'es7.promise.finally',
'es6.symbol',
'es6.array.find-index',
'es7.array.includes',
'es6.string.includes',
'es6.array.find',
'es6.object.assign'
]
}]
],
plugins
}
4 vue-cli 基本配置
新建一个vue.config.js的文件夹,开始可配置vue-cli
module.exports = {
//部署应用包时的基本 URL
publicPath: process.env.NODE_ENV === 'production' ? '/online/' : './',
//当运行 vue-cli-service build 时生成的生产环境构建文件的目录
outputDir: 'dist',
//放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录
assetsDir: 'assets',
// eslint-loader 是否在保存的时候检查 安装@vue/cli-plugin-eslint有效
lintOnSave: true,
//是否使用包含运行时编译器的 Vue 构建版本。设置true后你就可以在使用template
runtimeCompiler: true,
// 生产环境是否生成 sourceMap 文件 sourceMap的详解请看末尾
productionSourceMap: false,
}
5 添加别名
新建一个vue.config.js的文件夹,开始可配置vue-cli
1 别名配置
const path = require('path'); //引入path模块(node)
const resolve = (dir) => path.join(__dirname, dir); //将文件组成绝对路径
module.exports = {
chainWebpack: config => {
// 添加别名
config.resolve.alias
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
}
}
2 运用场景
目录的结构可能层层叠叠,后在达到目录
例如: 刚刚的env.js目录
import {baseUrl} from '../config/env'
但是我们不一定保证,目录就那么靠近,那么怎么处理
// @代表src目录下,即可这样调用
import {baseUrl} from '@/config/env'
7 优化-配置externals
防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖
项目中的使用
一般性vue项目,我们都会把一些框架包,给抽离出来。例如:
- Vue
- ELEMENT
- VueRouter
- Vuex
- axios
1 引入框架
我们把一些外包引用的包,提取出来,放在public中
2 编辑 externals
我们在vue.config.
module.exports = {
configureWebpack: config => {
config.externals = {
'vue': 'Vue',
'element-ui': 'ELEMENT',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios'
}
}
3 引入cdn
那么这时候我们需要在 public/index.html
vue-demo
8 优化-开启Gzip 压缩
1 介绍
vue cli 3.0相比2.0有不少的改动,最明显的就是 build文件夹不见了,改为根目录的vue.config.js
在此记录一下Gzip配置的过程
npm i -D compression-webpack-plugin
2 修改vue.config.js
const CompressionPlugin = require("compression-webpack-plugin")
module.exports = {
configureWebpack:config=>{
if(process.env.NODE_ENV === 'production'){
return{
plugins: [
new CompressionPlugin({
test:/\.js$|\.html$|.\css/, //匹配文件名
threshold: 10240,//对超过10k的数据压缩
deleteOriginalAssets: false //不删除源文件
})
]
}
}
},
}
3 nginx配置gzip
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 6;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
第1行:开启Gzip
第2行:不压缩临界值,大于1K的才压缩,一般不用改
第3行:buffer,就是,嗯,算了不解释了,不用改
第4行:用了反向代理的话,末端通信是HTTP/1.0,有需求的应该也不用看我这科普文了;有这句的话注释了就行> 了,默认是HTTP/1.1
第5行:压缩级别,1-10,数字越大压缩的越好,时间也越长,看心情随便改吧
第6行:进行压缩的文件类型,缺啥补啥就行了,JavaScript有两种写法,最好都写上吧,总有人抱怨js文件没有压> 缩,其实多写一种格式就行了
第7行:跟Squid等缓存服务有关,on的话会在Header里增加"Vary: Accept-Encoding",我不需要这玩意,自己> 对照情况看着办吧
第8行:IE6对Gzip不怎么友好,不给它Gzip了
9 优化-首屏加载
vue-demo
正在加载 vue,请耐心等待
V1.3
10 预处理器 (Sass/Less/Stylus)
# Sass
npm install -D sass-loader node-sass
# Less
npm install -D less-loader less
# Stylus
npm install -D stylus-loader stylus
然后你就可以导入相应的文件类型,或在 *.vue 文件中这样来使用:
11 node自动化部署
1 安装scp2
npm install scp2 --save-dev
2 配置一个服务器列表
deploy/products.js
/*
*定义多个服务器账号 及 根据 SERVER_ID 导出当前环境服务器账号
*/
const SERVER_LIST = [
{
id: 0,
name: 'A-测试环境',
host: 'xxx.xxx.xxx.xxx', // ip
port: 22,// 端口
username: 'root', // 登录服务器的账号
password: 'root', // 登录服务器的账号
path: 'xxx/xxx/xxx', // 发布至静态服务器的项目路径
del: ['/var/www/jx/admin/js', '/var/www/jx/admin/css'] // 删除这些无法替换的
},
{
id: 1,
name: 'B-生成环境',
host: 'xxx.xxx.xxx.xxx', // ip
port: 22,// 端口
username: 'root', // 登录服务器的账号
password: 'root', // 登录服务器的账号
path: 'xxx/xxx/xxx', // 发布至静态服务器的项目路径
del: ['/var/www/jx/admin/js', '/var/www/jx/admin/css'] // 删除这些无法替换的
},
];
module.exports = SERVER_LIST;
3 创建scp2自动化部署脚本
const scpClient = require('scp2');
const ora = require('ora');
const chalk = require('chalk');
const servers = require('./products');
let server = servers[process.env.NODE_ENV === 'prod' ? 1 : 0];
const spinner = ora('正在发布到' + (process.env.NODE_ENV === 'prod' ? '生产' : '测试') + '服务器...');
var Client = require('ssh2').Client;
var conn = new Client();
conn
.on('ready', function() {
// rm 删除dist文件,\n 是换行 换行执行 重启nginx命令 我这里是用docker重启nginx
let dels = ""
server.del.forEach(item => {
dels += `rm -rf ${item}\n`;
});
conn.exec(dels, function (
err,
stream
) {
if (err) throw err;
stream
.on('close', function(code, signal) {
// 在执行shell命令后,把开始上传部署项目代码放到这里面
spinner.start();
scpClient.scp(
'dist/',
{
host: server.host,
port: server.port,
username: server.username,
password: server.password,
path: server.path
},
function (err) {
spinner.stop();
if (err) {
console.log(chalk.red('发布失败.\n'));
throw err;
} else {
console.log(chalk.green('Success! 成功发布到' + (process.env.NODE_ENV === 'prod' ? '生产' : '测试') + '服务器! \n'));
}
}
);
conn.end();
})
.on('data', function (data) {
console.log('STDOUT: ' + data);
})
.stderr.on('data', function (data) {
console.log('STDERR: ' + data);
});
});
})
.connect({
host: server.host,
port: server.port,
username: server.username,
password: server.password
});
4 添加指令
在 package.json 中添加指令
"upload-test": "NODE_ENV=test node ./deploy",
"upload-prod": "NODE_ENV=prod node ./deploy"
5 使用指令
发布测试环境
npm run upload-test
12 node自动化新建页面
每一次都需要需要写vue的大致构造,我觉得还是比较麻烦的一件事。一般性可以使用vscode新建,但是我认为node更加方便
1 配置属于你的模板
generateTpl.js
安装个人习惯可以写多个模板这里,我们只演示一种
exports.table = function(pageName) {
var tpl = `
${pageName}-page
`
return tpl;
}
2 安装 inquirer
npm install inquirer --save-dev
3 创建自动化新建脚本
var path = require('path');
var fs = require('fs');
var generateTpl = require('./generateTpl');
var inquirer = require('inquirer')
const createPage = {
template: "table",
init: function() {
const promptName = [{
type: 'input',
message: '模板的名称',
name: 'templateName',
filter: function (val) {
return val.toLowerCase()
}
}]
const promptList = [{
type: 'list',
message: '请选择一种模版',
name: 'template',
choices: ['表格', '表单'],
filter: function (val) {
return val.toLowerCase()
}
}]
inquirer.prompt(promptName).then(name => {
inquirer.prompt(promptList).then(anwsers => {
this.initParams(name.templateName);
if (anwsers.template==='表格') {
this.template = "table"
}else{
this.template = "form"
}
this.getAllPage();
this.generatePage();
})
})
},
initParams: function (templateName) {
this.pageName = templateName;
this.pageDir = path.join(__dirname, '../src/views');
this.allPages = ""
},
getAllPage: function() {
this.allPages = fs.readdirSync(this.pageDir);
},
generatePage: function(){
if(this.allPages.indexOf(this.pageName) == -1) {
this.toGenerageDir();
} else {
console.error('当前页面已经存在了');
}
},
toGenerageDir: function(){
try{
fs.mkdir(path.join(this.pageDir, this.pageName), function(err){
if(err){
console.error(err);
return;
}
this.toGenerateFiles();
console.log('页面创建完成');
}.bind(this));
}catch(e){
console.error(e);
}
},
toGenerateFiles: function() {
// 选择模板
var vueFile = path.join(this.pageDir, this.pageName, `index.vue`);
var imageDir = path.join(this.pageDir, this.pageName, 'images')
// 创建文件
fs.writeFileSync(vueFile, generateTpl[this.template](this.pageName));
fs.mkdirSync(imageDir)
}
}
createPage.init();
3 添加指令
在 package.json 中添加指令
"create-page": "node create-page/create-page.js",
4 使用指令
npm run create-page