# vue-project-archictecture **Repository Path**: jaqea/vue-project-archictecture ## Basic Information - **Project Name**: vue-project-archictecture - **Description**: 基于Webpack搭建的Vue项目目录结构 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-11-03 - **Last Updated**: 2021-01-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vue-project-archictecture 一个基于Webpack搭建的Vue项目目录结构。 所用技术: - 使用**Vue.js**作为编码语言。 - 使用**Webpack**进行项目打包及配置。 - 使用**Antd**组件进行页面编写。 - 集成**sass**、**Less**进行样式编写。 - 使用**Vue-router**管理路由。 - 使用**Vuex**管理数据。 - 使用**Axios**进行服务端交互。 - 使用**Eslint+Airbub、Prettier、Commitlint**配置规范代码。 ## 项目目录结构 ```cmd |-- vue-project-archictecture |-- .babelrc # babel配置文件 |-- .browserslistrc # 浏览器兼容配置 |-- .editorconfig # 代码风格配置文件 |-- .eslintrc.js # eslint配置文件 |-- .gitignore # git忽略文件 |-- .prettierrc.js # Prettier配置文件 |-- commitlint.config.js # commitlint配置文件 |-- package.json |-- yarn-error.log |-- yarn.lock |-- public | |-- favicon.ico | |-- index.html |-- src | |-- App.vue | |-- index.js | |-- api # API接口 | | |-- base.js # 环境域名配置 | | |-- modules # 模块接口 | | |-- demo.js | | |-- index.js | |-- assets | | |-- images | | | |-- demo.png | | |-- styles # 全局样式 | | |-- common.less # 入口文件 | | |-- layout.less # 全局布局样式 | | |-- mixin.less # 全局混合 | | |-- variable.less # 全局样式变量 | | |-- theme # antd主题配置 | | |-- base.js | |-- components # 全局组件 | | |-- loading # 加载效果组件 | | |-- loading.vue | |-- router | | |-- index.js | | |-- middleware # 路由中间件 | | | |-- auth.js | | | |-- demo.js | | | |-- guest.js | | | |-- index.js | | |-- routes # 路由 | | |-- index.js | |-- store | | |-- index.js | | |-- modules | | |-- demo | | |-- actions.js | | |-- getters.js | | |-- index.js | | |-- mutations.js | | |-- state.js | |-- utils # 全局公用方法 | | |-- http.js | |-- views | |-- home | | |-- home.less | | |-- home.vue | |-- login | | |-- login.vue | |-- notFound | |-- notFound.vue |-- webpack |-- webpack.base.conf.js # webpack基础配置 |-- webpack.dev.conf.js # 开发环境配置 |-- webpack.prod.conf.js # 生产环境配置 ``` ## 全局配置 ### webpack 基础配置: ```js // /webpack/webpack.base.conf.js const path = require("path"); const webpack = require("webpack"); const resolve = (dir) => path.resolve(__dirname, dir); const jsonToStr = (json) => JSON.stringify(json); const isProd = process.env.NODE_ENV === "production"; const { VueLoaderPlugin } = require("vue-loader"); module.exports = { entry: resolve("../src/index.js"), // 引入资源省略后缀,资源别名 resolve: { extensions: [".js", ".json", ".vue"], alias: { "@": resolve("../src"), assets: resolve("../src/assets"), views: resolve("../src/views"), components: resolve("../src/components"), api: resolve("../src/api"), store: resolve("../src/store"), router: resolve("../src/router"), }, }, module: { rules: [ { test: /\.(png|svg|jpg|gif)$/, use: [ { loader: "file-loader", options: { // 图片小于10kb就是图片地址,大于正常打包成base64格式编码 limit: 10000, // 输出路径 outputPath: "img/", // 指定生成的目录 name: "img/[name].[hash:7].[ext]", }, }, ], }, { test: /\.(woff|woff2|eot|ttf|otf|)$/, use: ["file-loader"], }, { test: /\.js$/, use: ["babel-loader"], exclude: /node_modules/, include: resolve("src"), }, { test: /\.vue$/, use: "vue-loader" }, { test: /\.(vue|js)$/, include: resolve("../src"), enforce: "pre", loader: "eslint-loader", options: { fix: true, emitWarning: true, }, }, ], }, plugins: [ // 定义全局变量 new webpack.DefinePlugin({ "process.env.NODE_ENV": isProd ? jsonToStr("production") : jsonToStr("development"), }), new VueLoaderPlugin(), ], performance: false, }; ``` 开发环境配置: ```js // /webpack/webpack.dev.conf.js const { merge } = require("webpack-merge"); const webpack = require("webpack"); const path = require("path"); const resolve = (dir) => path.resolve(__dirname, dir); const HtmlWebpackPlugin = require("html-webpack-plugin"); const baseWebpack = require("./webpack.base.conf"); const PROXY_URL = require("../src/api/base"); const antdThemeOption = require("../src/assets/styles/theme/base"); module.exports = merge(baseWebpack, { mode: "development", output: { path: resolve("../dist"), filename: "js/[name].js", chunkFilename: "js/[name].chunk.js", }, devtool: "source-map", devServer: { contentBase: resolve("../public"), port: "8080", inline: true, historyApiFallback: true, disableHostCheck: true, hot: true, open: true, proxy: { "/api": { target: PROXY_URL.development, changeOrigin: true, pathRewrite: { "^/api": "/", }, }, }, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], exclude: /node_modules/, }, { test: /\.less$/, use: [ "style-loader", "css-loader", { loader: "less-loader", options: { lessOptions: { modifyVars: antdThemeOption, javascriptEnabled: true, }, }, }, { loader: "style-resources-loader", options: { patterns: resolve("../src/assets/styles/common.less"), }, }, ], }, { test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"], }, ], }, optimization: { usedExports: true, splitChunks: { chunks: "all", }, }, plugins: [ new webpack.HotModuleReplacementPlugin(), new HtmlWebpackPlugin({ filename: "index.html", template: resolve("../public/index.html"), }), ], }); ``` 生产环境配置: ```js // /webpack/webpack.prod.conf.js const { merge } = require("webpack-merge"); const path = require("path"); const resolve = (dir) => path.resolve(__dirname, dir); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const OptimizeCss = require("optimize-css-assets-webpack-plugin"); const TerserWebpackPlugin = require("terser-webpack-plugin"); const baseWebpack = require("./webpack.base.conf"); module.exports = merge(baseWebpack, { mode: "production", devtool: false, output: { path: resolve("../dist"), filename: "static/js/[name].[chunkhash:8].js", }, optimization: { minimizer: [ new OptimizeCss(), new TerserWebpackPlugin({ // 压缩es6 terserOptions: { // 启用文件缓存 cache: true, // 使用多线程并行运行提高构建速度 parallel: true, // 使用 SourceMaps 将错误信息的位置映射到模块 sourceMap: true, }, }), ], }, module: { rules: [ { test: /\.(css|sass|scss|less)$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader", options: { importLoaders: 2, sourceMap: false, }, }, { loader: "postcss-loader", options: { sourceMap: false, }, }, { loader: "sass-loader", options: { sourceMap: false, }, }, { loader: "less-loader", options: { sourceMap: false, }, }, { loader: "style-resources-loader", options: { patterns: resolve("../src/assets/styles/common.less"), }, }, ], }, ], }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: resolve("../public/index.html"), title: "vue-project-archictecture", favicon: resolve("../public/favicon.ico"), // 压缩html minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true, }, }), new MiniCssExtractPlugin({ filename: "static/css/[name].[contenthash:8].css", }), new CopyWebpackPlugin({ patterns: [ { from: resolve("../public"), to: resolve("../dist"), }, ], }), ], }); ``` ### .eslintrc.js ESLint基本配置。 ```js // .eslintrc.js module.exports = { env: { browser: true, es2020: true, }, settings: { "import/resolver": { webpack: { config: "./webpack/webpack.base.conf.js", }, }, }, extends: ["plugin:vue/essential", "airbnb-base", "plugin:prettier/recommended"], parserOptions: { parser: "babel-eslint", ecmaVersion: 12, sourceType: "module", }, plugins: ["vue", "prettier", "babel"], rules: { "prettier/prettier": "error", quotes: [1, "double"], "import/extensions": [ "error", "always", { js: "never", vue: "never", }, ], "global-require": 0, "import/no-dynamic-require": 0, "import/no-cycle": 0, "import/prefer-default-export": 0, "no-console": 0, "no-param-reassign": 0, "import/no-extraneous-dependencies": 0, }, }; ``` ### .prettierrc.js Prettier格式化规则配置。 ```js // .prettierrc.js module.exports = { printWidth: 100, //一行的字符数,如果超过会进行换行,默认为80 tabWidth: 2, //一个tab代表几个空格数,默认为80 useTabs: false, //是否使用tab进行缩进,默认为false,表示用空格进行缩减 singleQuote: false, //字符串是否使用单引号,默认为false,使用双引号 semi: true, //行位是否使用分号,默认为true trailingComma: 'es5', //是否使用尾逗号,有三个可选值"" bracketSpacing: true, //对象大括号直接是否有空格,默认为true,效果:{ foo: bar } }; ``` ### commitlint.config.js commitlint 基础配置,用于检查 `git commit -m ''` 格式。 ```js // .commitlint.config.js module.exports = { // 继承默认配置 extends: ["@commitlint/config-angular"], // 自定义规则 rules: { "type-enum": [ 2, "always", ["test", "upd", "feat", "fix", "refactor", "docs", "chore", "style", "revert"], ], "header-max-length": [0, "always", 72], }, }; ``` `commit`的格式要求如下: ```cmd Type():