背景
前段时间使用webpack搭建了一个项目,感觉收获颇多。附上链接,大家有兴趣可以看一下( 使用webpack配置一个项目)。但是现在开发项目,直接使用webpack搭建项目,配置过于复杂,不能开箱即用,大家也早就抛弃了这种方式,而是使用vue-cli,create-react-app等脚手架针对技术栈直接搭建项目,方便快捷。今天尝试手撕一遍vue-cli搭建一个pc的项目。
预设技术栈 vue+vuex+vue-router+less+axios+element-ui, eslint+prettier+husky+lint-staged
- vue (项目框架)
- vuex (状态机)
- vue-router (路由)
- less (css预处理器)
- axios (进行接口请求)
- element-ui (组件库,便捷开发)
- eslint prettier (代码风格统一)
- husky lint-staged(在git提交的时候添加eslint检测钩子,保证所有的同学提交的代码风格都统一)
1.全局安装vue-cli
// 终端命令行
yarn global add @vue/cli
// 查看vue-cli版本
vue --version
2.使用vue-cli初始化一个项目
1.初始化项目
// 终端
vue create vue2-js-template // vue2-js-template是我的项目名,大家可以随便取名字
yarn serve 打开项目,好啦,完成了。(🐶头保命,哈哈,不过第一步确实完成了)
3.修改为多页面配置项目
1.修改目录结构
2.创建vue.config.js
// yarn add image-webpack-loader webpack-bundle-analyzer -D 终端运行
const path = require("path");
const BundleAnalyzerPlugin =
require("webpack-bundle-analyzer").BundleAnalyzerPlugin; // 打包分析
const { NODE_ENV } = process.env;
const isProduction = NODE_ENV === "production";
const isDevelopment = NODE_ENV === "development";
// 多页面打包配置
const getPages = () => {
return {
index: {
entry: "src/pages/index/main.js", // page 的入口
template: "public/index.html", // 模板来源
filename: "index.html", // 在 dist/index.html 的输出
title: "首页", // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
chunks: ["chunk-vendors", "chunk-common", "index"],
},
list: {
entry: "src/pages/list/main.js", // page 的入口
template: "public/index.html", // 模板来源
filename: "list.html",
title: "列表页面",
chunks: ["chunk-vendors", "chunk-common", "list"],
},
};
};
const getDevServe = () => {
const devServer = {
overlay: {
warnings: false, // 让浏览器 overlay 同时显示警告和错误
errors: true,
},
https: false, // https:{type:Boolean}
open: true, //配置自动启动浏览器
hotOnly: true, // 热更新
proxy: {
// 配置多个跨域
"/api": {
target: "http://xxx.xxx",
changeOrigin: true,
// ws: true,//websocket支持
secure: false,
pathRewrite: {
"^/api": "/",
},
},
},
};
if (isDevelopment) {
// 配置开发环境 访问路径跳转相关的html http://localhost:8088/list#/ => http://localhost:8088/list.html#/
const pages = getPages();
Object.keys(pages).forEach((page) => {
Reflect.set(devServer.proxy, `/${page}`, {
target: "./",
bypass: (req) => {
const { path } = req;
return path.indexOf("html") !== -1 ? path : `${path}.html`;
},
});
});
}
return devServer;
};
const getChainWebpack = (config) => {
config.module
.rule("images")
.use("image-webpack-loader")
.loader("image-webpack-loader")
.options({
bypassOnDebug: true,
})
.end();
if (isProduction) {
config.plugin("webpack-report").use(BundleAnalyzerPlugin, [
{
analyzerMode: "static",
},
]); // 打包环境做打包后文件大小分析展示
}
};
const setOptimization = (config) => {
// 提取公共chunk和node_modules的公共文件
config.optimization = {
splitChunks: {
cacheGroups: {
common: {
//抽取所有入口页面都需要的公共chunk
name: "chunk-common",
chunks: "initial",
minChunks: 2,
priority: 1,
enforce: true,
minSize: 0,
reuseExistingChunk: true,
},
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "chunk-vendors",
chunks: "all",
}, // node_modules的打包文件
},
},
};
};
module.exports = {
pages: getPages(), // 入口文件配置
publicPath: "./", // 打包资源引入,使用相对路径的引入,打出来的包可以被部署在任意路径
lintOnSave: !isProduction, // 生产环境禁用eslint-loader,可以加快生产构建
parallel: true, // 是否为 Babel 或 TypeScript 使用 thread-loader,多线程打包
css: {
requireModuleExtension: true,
},
pluginOptions: {
"style-resources-loader": {
preProcessor: "less",
patterns: [path.resolve(__dirname, "./src/style/variable.less")], // 设置less变量覆盖
},
}, //这是一个不进行任何 schema 验证的对象,因此它可以用来传递任何第三方插件选项
devServer: getDevServe(), // 开发环境dev-serve配置
chainWebpack: (config) => getChainWebpack(config), // 通过 webpack-merge 合并到最终的配置中
configureWebpack: (config) => {
setOptimization(config);
}, // 是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改。 一般可以用来做config的一些配置的更改
};
4.添加axios相关配置
1.安装axios
yarn add axios // axios库
yarn add qs // 做请求参数序列化使用
2.新建 src/config/axios.config.js
import axios from "axios";
import qs from "qs";
const instance = axios.create({
baseURL: "", // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
timeout: 20000, // 如果请求时间超过 `timeout` 的值,则请求会被中断
headers: {
["Cache-Control"]: "no-cache",
["Content-Type"]: "application/json",
["x-requested-with"]: "XMLHttpRequest",
}, // 自定义请求头
paramsSerializer: function (params) {
return qs.stringify(params, { arrayFormat: "indices" });
}, // `paramsSerializer`是可选方法,主要用于序列化`params`
});
// 添加请求拦截器
instance.request.use(
(config) => {
// 在发送请求之前
// 携带用户的token信息
return config;
},
(error) => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
instance.response.use(
(response) => {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
},
(error) => {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
}
);
export default instance;
5.添加elementUI组件库
1.安装elementUI
yarn add element-ui
2.在使用elementUI组件库的页面的main.js引入elementUI (src/pages/index/main.js)
// main.js
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.use(ElementUI);
6.处理eslint和prettier的规则(做一些自定义规则)
1.从package.json里面去除 eslintConfig,新建.eslintrc.js
module.exports = {
root: true,
env: {
node: true,
browser: true,
es6: true,
},
extends: ['plugin:vue/essential', 'eslint:recommended', '@vue/prettier'],
parserOptions: {
parser: 'babel-eslint',
},
rules: {
'no-multiple-empty-lines': 0, // 禁用不允许多行空格
},
};
2.新建.prettierrc.js
module.exports = {
printWidth: 200, //一行的字符数,如果超过会进行换行,默认为80
tabWidth: 4, //一个tab代表几个空格数,默认为80
useTabs: false, //是否使用tab进行缩进,默认为false,表示用空格进行缩减
semi: true, //行位是否使用分号,默认为true
singleQuote: true, //字符串是否使用单引号,默认为false,使用双引号
bracketSpacing: true, // 对象左右两侧需要空格
jsxBracketSameLine: false, // html 关闭标签换行
};
3.vscode的setting.json设置保存时候自动格式化
//setting.json
{
"editor.formatOnPaste": true,
"eslint.enable": true, //是否开启vscode的eslint
"eslint.alwaysShowStatus": true, //是否在保存的时候自动fix eslint
"eslint.options": {
//指定vscode的eslint所处理的文件的后缀
"extensions": [".js", ".vue", ".ts", ".tsx"]
},
"eslint.validate": [
//确定校验准则
"javascript"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
4.新建.eslintignore文件
**/node_modules/*
**/dist/*
5.运行eslint检测,格式化
yarn run lint
//注意:运行完成后,会有很多报错,显示出eslint和prettier冲突的感觉,需要关闭,重新启动一下vscode,让vscode重新读取.eslintrc.js的文件,就可以了
7. husky + lint-staged
1.配置
终端运行
1.//安装husky,lint-staged
yarn add husky lint-staged -D
2.// 配置husky
npx husky install
3.// 添加 pre-commit 的 git hook 脚本
npx husky add .husky/pre-commit "npx lint-staged"
4.// package.json 添加 lint-staged的命令
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"npm run lint"
]
},
2.检测
(1)关闭setting.json中的自动保存
(2)在代码中改动出一个不符合规范的代码片段,使用git提交,测试结果 修复了代码问题
代码仓库
小结
还有很多项目中使用的东西没有配置进去,但是一个简单的小框架确实是做好了,下期再见。