千家信息网

vue-cli目录结构详细讲解

发表于:2025-01-30 作者:千家信息网编辑
千家信息网最后更新 2025年01月30日,这篇文章主要讲解了"vue-cli目录结构详细讲解",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"vue-cli目录结构详细讲解"吧!一个vue-cli
千家信息网最后更新 2025年01月30日vue-cli目录结构详细讲解

这篇文章主要讲解了"vue-cli目录结构详细讲解",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"vue-cli目录结构详细讲解"吧!

一个vue-cli的项目结构如下:

目录

结构预览

├─build         // 保存一些webpack的初始化配置,项目构建│ ├─build.js      // 生产环境构建│ ├─check-version.js  // 检查npm、node版本│ ├─vue-loader.conf.js // webpack loader配置│ ├─webpack.base.conf.js// webpack基础配置│ ├─webpack.dev.conf.js // 开发环境配置,构建本地开发服务器│ ├─webpack.prod.conf.js// 生产环境的配置│├─config        // config文件夹保存一些项目初始化的配置│ ├─dev.env.js     // 开发环境的配置│ ├─index.js      // 项目一些配置变量│ ├─prod.env.js     // 生产环境的配置│├─dist         // 打包后的项目├─node_modules     // 依赖包│├─src          // 源码目录│ ├─assets       // 静态文件目录│ ├─components     // 组件文件│ ├─router       // 路由│ ├─App.vue       // 是项目入口文件│ ├─main.js       // 是项目的核心文件,入口├─static        // 静态资源目录 ├─.babelrc       // Babel的配置文件├─.editorconfig     // 代码规范配置文件├─.gitignore      // git忽略配置文件├─.postcssrc.js     // postcss插件配置文件├─index.html      // 页面入口文件├─package-lock.json   // 项目包管控文件├─package.json     // 项目配置└─README.md       // 项目说明书

结构解析

build

dev-server.js

首先来看执行"npm run dev"时候最先执行的build/dev-server.js文件。该文件主要完成下面几件事情:

  • 检查node和npm的版本、引入相关插件和配置

  • webpack对源码进行编译打包并返回compiler对象

  • 创建express服务器

  • 配置开发中间件(webpack-dev-middleware)和+ 热重载中间件(webpack-hot-middleware)

  • 挂载代理服务和中间件

  • 配置静态资源

  • 启动服务器监听特定端口(8080)

  • 自动打开浏览器并打开特定网址(localhost:8080)

说明: express服务器提供静态文件服务,不过它还使用了http-proxy-middleware,一个http请求代理的中间件。前端开发过程中需要使用到后台的API的话,可以通过配置proxyTable来将相应的后台请求代理到专用的API服务器。

// 检查NodeJS和npm的版本require('./check-versions')()// 获取基本配置var config = require('../config')// 如果Node的环境变量中没有设置当前的环境(NODE_ENV),则使用config中的dev环境配置作为当前的环境if (!process.env.NODE_ENV) { process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)}// opn是一个可以调用默认软件打开网址、图片、文件等内容的插件// 这里用它来调用默认浏览器打开dev-server监听的端口,例如:localhost:8080var opn = require('opn')var path = require('path')var express = require('express')var webpack = require('webpack')// http-proxy-middleware是一个express中间件,用于将http请求代理到其他服务器// 例:localhost:8080/api/xxx --> localhost:3000/api/xxx// 这里使用该插件可以将前端开发中涉及到的请求代理到提供服务的后台服务器上,方便与服务器对接var proxyMiddleware = require('http-proxy-middleware')// 开发环境下的webpack配置var webpackConfig = require('./webpack.dev.conf')// dev-server 监听的端口,如果没有在命令行传入端口号,则使用config.dev.port设置的端口,例如8080var port = process.env.PORT || config.dev.port// 用于判断是否要自动打开浏览器的布尔变量,当配置文件中没有设置自动打开浏览器的时候其值为 falsevar autoOpenBrowser = !!config.dev.autoOpenBrowser// HTTP代理表,指定规则,将某些API请求代理到相应的服务器var proxyTable = config.dev.proxyTable// 创建express服务器var app = express()// webpack根据配置开始编译打包源码并返回compiler对象var compiler = webpack(webpackConfig)// webpack-dev-middleware将webpack编译打包后得到的产品文件存放在内存中而没有写进磁盘// 将这个中间件挂到express上使用之后即可提供这些编译后的产品文件服务var devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: webpackConfig.output.publicPath, // 设置访问路径为webpack配置中的output里面所对应的路径 quiet: true // 设置为true,使其不要在控制台输出日志})// webpack-hot-middleware,用于实现热重载功能的中间件var hotMiddleware = require('webpack-hot-middleware')(compiler, { log: false, // 关闭控制台的日志输出 heartbeat: 2000 // 发送心跳包的频率})// webpack(重新)编译打包完成后并将js、css等文件inject到html文件之后,通过热重载中间件强制页面刷新compiler.plugin('compilation', function (compilation) { compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {  hotMiddleware.publish({ action: 'reload' })  cb() })})// 根据 proxyTable 中的代理请求配置来设置express服务器的http代理规则Object.keys(proxyTable).forEach(function (context) { var options = proxyTable[context] // 格式化options,例如将'www.example.com'变成{ target: 'www.example.com' } if (typeof options === 'string') {  options = { target: options } } app.use(proxyMiddleware(options.filter || context, options))})// handle fallback for HTML5 history API// 重定向不存在的URL,用于支持SPA(单页应用)// 例如使用vue-router并开启了history模式app.use(require('connect-history-api-fallback')())// serve webpack bundle output// 挂载webpack-dev-middleware中间件,提供webpack编译打包后的产品文件服务app.use(devMiddleware)// enable hot-reload and state-preserving// compilation error display// 挂载热重载中间件app.use(hotMiddleware)// serve pure static assets// 提供static文件夹上的静态文件服务var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)app.use(staticPath, express.static('./static'))// 访问链接var uri = 'http://localhost:' + port// 创建promise,在应用服务启动之后resolve// 便于外部文件require了这个dev-server之后的代码编写var _resolvevar readyPromise = new Promise(resolve => { _resolve = resolve})console.log('> Starting dev server...')// webpack-dev-middleware等待webpack完成所有编译打包之后输出提示语到控制台,表明服务正式启动// 服务正式启动才自动打开浏览器进入页面devMiddleware.waitUntilValid(() => { console.log('> Listening at ' + uri + '\n') // when env is testing, don't need open it if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {  opn(uri) } _resolve()})// 启动express服务器并监听相应的端口var server = app.listen(port)// 暴露本模块的功能给外部使用,例如下面这种用法// var devServer = require('./build/dev-server')// devServer.ready.then(() => {...})// if (...) { devServer.close() }module.exports = { ready: readyPromise, close: () => {  server.close() }}

webpack.base.conf.js

从代码中看到,dev-server使用的webpack配置来自build/webpack.dev.conf.js文件(测试环境下使用的是build/webpack.prod.conf.js,这里暂时不考虑测试环境)。而build/webpack.dev.conf.js中又引用了webpack.base.conf.js,所以这里我先分析webpack.base.conf.js。

webpack.base.conf.js主要完成了下面这些事情:

  • 配置webpack编译入口

  • 配置webpack输出路径和命名规则

  • 配置模块resolve规则

  • 配置不同类型模块的处理规则

说明: 这个配置里面只配置了.js、.vue、图片、字体等几类文件的处理规则,如果需要处理其他文件可以在module.rules里面另行配置。

var path = require('path')var fs = require('fs')var utils = require('./utils')var config = require('../config')var vueLoaderConfig = require('./vue-loader.conf')// 获取绝对路径function resolve (dir) { return path.join(__dirname, '..', dir)}module.exports = { // webpack入口文件 entry: {  app: './src/main.js' }, // webpack输出路径和命名规则 output: {  // webpack输出的目标文件夹路径(例如:/dist)  path: config.build.assetsRoot,  // webpack输出bundle文件命名格式  filename: '[name].js',  // webpack编译输出的发布路径(例如'//cdn.xxx.com/app/')  publicPath: process.env.NODE_ENV === 'production'   ? config.build.assetsPublicPath   : config.dev.assetsPublicPath }, // 模块resolve的规则 resolve: {  extensions: ['.js', '.vue', '.json'],  // 别名,方便引用模块,例如有了别名之后,  // import Vue from 'vue/dist/vue.common.js'可以写成 import Vue from 'vue'  alias: {   'vue$': 'vue/dist/vue.esm.js',   '@': resolve('src'),  },  symlinks: false }, // 不同类型模块的处理规则 module: {  rules: [   {// 对src和test文件夹下的.js和.vue文件使用eslint-loader进行代码规范检查    test: /\.(js|vue)$/,    loader: 'eslint-loader',    enforce: 'pre',    include: [resolve('src'), resolve('test')],    options: {     formatter: require('eslint-friendly-formatter')    }   },   {// 对所有.vue文件使用vue-loader进行编译    test: /\.vue$/,    loader: 'vue-loader',    options: vueLoaderConfig   },   {// 对src和test文件夹下的.js文件使用babel-loader将es6+的代码转成es5    test: /\.js$/,    loader: 'babel-loader',    include: [resolve('src'), resolve('test')]   },   {// 对图片资源文件使用url-loader    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,    loader: 'url-loader',    options: {     // 小于10K的图片转成base64编码的dataURL字符串写到代码中     limit: 10000,     // 其他的图片转移到静态资源文件夹     name: utils.assetsPath('img/[name].[hash:7].[ext]')    }   },   {// 对多媒体资源文件使用url-loader    test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,    loader: 'url-loader',    options: {     // 小于10K的资源转成base64编码的dataURL字符串写到代码中     limit: 10000,     // 其他的资源转移到静态资源文件夹     name: utils.assetsPath('media/[name].[hash:7].[ext]')    }   },   {// 对字体资源文件使用url-loader    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,    loader: 'url-loader',    options: {     // 小于10K的资源转成base64编码的dataURL字符串写到代码中     limit: 10000,     // 其他的资源转移到静态资源文件夹     name: utils.assetsPath('fonts/[name].[hash:7].[ext]')    }   }  ] }}

webpack.dev.conf.js

接下来看webpack.dev.conf.js,这里面在webpack.base.conf的基础上增加完善了开发环境下面的配置,主要包括下面几件事情:

  • 将webpack的热重载客户端代码添加到每个entry对应的应用

  • 合并基础的webpack配置

  • 配置样式文件的处理规则,styleLoaders

  • 配置Source Maps

  • 配置webpack插件

var utils = require('./utils')var webpack = require('webpack')var config = require('../config')// webpack-merge是一个可以合并数组和对象的插件var merge = require('webpack-merge')var baseWebpackConfig = require('./webpack.base.conf')// html-webpack-plugin用于将webpack编译打包后的产品文件注入到html模板中// 即自动在index.html里面加上




0