https://juejin.im/post/5c3599386fb9a049db7351a8

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:8080
var 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设置的端口,例如8080
var port = process.env.PORT ||config.dev.port//用于判断是否要自动打开浏览器的布尔变量,当配置文件中没有设置自动打开浏览器的时候其值为 false
var 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 itif (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+的代码转成es5test: /\.js$/,loader:'babel-loader',include: [resolve('src'), resolve('test')]},{//对图片资源文件使用url-loadertest: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader:'url-loader',options: {//小于10K的图片转成base64编码的dataURL字符串写到代码中limit: 10000,//其他的图片转移到静态资源文件夹name: utils.assetsPath('img/[name].[hash:7].[ext]')}},{//对多媒体资源文件使用url-loadertest: /\.(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-loadertest: /\.(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里面加上<link>和<script>标签引用webpack打包后的文件
var HtmlWebpackPlugin = require('html-webpack-plugin')//friendly-errors-webpack-plugin用于更友好地输出webpack的警告、错误等信息
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')//add hot-reload related code to entry chunks//给每个入口页面(应用)加上dev-client,用于跟dev-server的热重载插件通信,实现热更新
Object.keys(baseWebpackConfig.entry).forEach(function (name) {baseWebpackConfig.entry[name]= ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})module.exports=merge(baseWebpackConfig, {module: {//样式文件的处理规则,对css/sass/scss等不同内容使用相应的styleLoaders//由utils配置出各种类型的预处理语言所需要使用的loader,例如sass需要使用sass-loader
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })},//cheap-module-eval-source-map is faster for development//使用这种source-map更快devtool: '#cheap-module-eval-source-map',//webpack插件
plugins: [newwebpack.DefinePlugin({'process.env': config.dev.env}),//开启webpack热更新功能newwebpack.HotModuleReplacementPlugin(),//webpack编译过程中出错的时候跳过报错阶段,不会阻塞编译,在编译结束后报错newwebpack.NoEmitOnErrorsPlugin(),//自动将依赖注入html模板,并输出最终的html文件到目标文件夹newHtmlWebpackPlugin({filename:'index.html',template:'index.html',inject:true}),newFriendlyErrorsPlugin()]
})
复制代码
utils
此配置文件是vue开发环境的wepack相关配置文件,主要用来处理css-loader和vue-style-loader//引入nodejs路径模块
var path = require('path')//引入config目录下的index.js配置文件
var config = require('../config')//引入extract-text-webpack-plugin插件,用来将css提取到单独的css文件中//详情请看(1)
var ExtractTextPlugin = require('extract-text-webpack-plugin')//exports其实就是一个对象,用来导出方法的最终还是使用module.exports,此处导出assetsPath
exports.assetsPath =function (_path) {//如果是生产环境assetsSubDirectory就是'static',否则还是'static',哈哈哈var assetsSubDirectory = process.env.NODE_ENV === 'production'?config.build.assetsSubDirectory: config.dev.assetsSubDirectory//path.join和path.posix.join的区别就是,前者返回的是完整的路径,后者返回的是完整路径的相对根路径//也就是说path.join的路径是C:a/a/b/xiangmu/b,那么path.posix.join就是breturnpath.posix.join(assetsSubDirectory, _path)//所以这个方法的作用就是返回一个干净的相对根路径
}//下面是导出cssLoaders的相关配置
exports.cssLoaders =function (options) {//options如果没值就是空对象options = options ||{}//cssLoader的基本配置var cssLoader ={loader:'css-loader',options: {//options是用来传递参数给loader的//minimize表示压缩,如果是生产环境就压缩css代码minimize: process.env.NODE_ENV === 'production',//是否开启cssmap,默认是false
sourceMap: options.sourceMap}}//generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {//将上面的基础cssLoader配置放在一个数组里面var loaders =[cssLoader]//如果该函数传递了单独的loader就加到这个loaders数组里面,这个loader可能是less,sass之类的if(loader) {loaders.push({//加载对应的loaderloader: loader + '-loader',//Object.assign是es6的方法,主要用来合并对象的,浅拷贝
options: Object.assign({}, loaderOptions, {sourceMap: options.sourceMap})})}//Extract CSS when that option is specified//(which is the case during production build)//注意这个extract是自定义的属性,可以定义在options里面,主要作用就是当配置为true就把文件单独提取,false表示不单独提取,这个可以在使用的时候单独配置,瞬间觉得vue作者好牛逼if(options.extract) {returnExtractTextPlugin.extract({use: loaders,fallback:'vue-style-loader'})}else{return ['vue-style-loader'].concat(loaders)}//上面这段代码就是用来返回最终读取和导入loader,来处理对应类型的文件
}// https://vue-loader.vuejs.org/en/configurations/extract-css.htmlreturn{css: generateLoaders(),//css对应 vue-style-loader 和 css-loaderpostcss: generateLoaders(), //postcss对应 vue-style-loader 和 css-loaderless: generateLoaders('less'), //less对应 vue-style-loader 和 less-loadersass: generateLoaders('sass', { indentedSyntax: true }), //sass对应 vue-style-loader 和 sass-loaderscss: generateLoaders('sass'), //scss对应 vue-style-loader 和 sass-loaderstylus: generateLoaders('stylus'), //stylus对应 vue-style-loader 和 stylus-loaderstyl: generateLoaders('stylus') //styl对应 vue-style-loader 和 styl-loader
}
}//Generate loaders for standalone style files (outside of .vue)//下面这个主要处理import这种方式导入的文件类型的打包,上面的exports.cssLoaders是为这一步服务的
exports.styleLoaders =function (options) {var output =[]//下面就是生成的各种css文件的loader对象var loaders =exports.cssLoaders(options)for (var extension inloaders) {//把每一种文件的laoder都提取出来var loader =loaders[extension]output.push({//把最终的结果都push到output数组中,大事搞定test: new RegExp('\\.' + extension + '$'),use: loader})}returnoutput
}
复制代码
extract-text-webpack-plugin插件是用来将文本从bundle中提取到一个单独的文件中const ExtractTextPlugin = require("extract-text-webpack-plugin");module.exports={module: {rules: [{test:/\.css$/, //主要用来处理css文件
use: ExtractTextPlugin.extract({fallback:"style-loader", //fallback表示如果css文件没有成功导入就使用style-loader导入use: "css-loader" //表示使用css-loader从js读取css文件
})}],plugins: [new ExtractTextPlugin("styles.css") //表示生成styles.css文件
]}}
复制代码
vue-loader.conf.jsvar utils = require('./utils')var config = require('../config')var isProduction = process.env.NODE_ENV === 'production'module.exports={//处理.vue文件中的样式
loaders: utils.cssLoaders({//是否打开source-map
sourceMap: isProduction?config.build.productionSourceMap: config.dev.cssSourceMap,//是否提取样式到单独的文件
extract: isProduction}),transformToRequire: {video:'src',source:'src',img:'src',image:'xlink:href'}
}
复制代码
dev-client.js
dev-client.js里面主要写了浏览器端代码,用于实现webpack的热更新。/*eslint-disable*/
//实现浏览器端的EventSource,用于跟服务器双向通信//webpack热重载客户端跟dev-server上的热重载插件之间需要进行双向通信//服务端webpack重新编译后,会向客户端推送信息,告诉客户端进行更新
require('eventsource-polyfill')//webpack热重载客户端
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')//客户端收到更新动作,执行页面刷新
hotClient.subscribe(function (event) {if (event.action === 'reload') {window.location.reload()}
})
复制代码
build.js
执行”npm run build”的时候首先执行的是build/build.js文件,build.js主要完成下面几件事:loading动画
删除目标文件夹
执行webpack构建
输出信息
说明: webpack编译之后会输出到配置里面指定的目标文件夹;删除目标文件夹之后再创建是为了去除旧的内容,以免产生不可预测的影响。//检查NodeJS和npm的版本
require('./check-versions')()process.env.NODE_ENV= 'production'//ora,一个可以在终端显示spinner的插件
var ora = require('ora')//rm,用于删除文件或文件夹的插件
var rm = require('rimraf')var path = require('path')//chalk,用于在控制台输出带颜色字体的插件
var chalk = require('chalk')var webpack = require('webpack')var config = require('../config')var webpackConfig = require('./webpack.prod.conf')var spinner = ora('building for production...')
spinner.start()//开启loading动画//首先将整个dist文件夹以及里面的内容删除,以免遗留旧的没用的文件//删除完成后才开始webpack构建打包
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err =>{if (err) throwerr//执行webpack构建打包,完成之后在终端输出构建完成的相关信息或者输出报错信息并退出程序
webpack(webpackConfig, function (err, stats) {spinner.stop()if (err) throwerrprocess.stdout.write(stats.toString({colors:true,modules:false,children:false,chunks:false,chunkModules:false})+ '\n\n')if(stats.hasErrors()) {console.log(chalk.red('Build failed with errors.\n'))process.exit(1)}console.log(chalk.cyan('Build complete.\n'))console.log(chalk.yellow('Tip: built files are meant to be served over an HTTP server.\n' +'Opening index.html over file:// won\'t work.\n'))})
})复制代码
webpack.prod.conf.js
构建的时候用到的webpack配置来自webpack.prod.conf.js,该配置同样是在webpack.base.conf基础上的进一步完善。主要完成下面几件事情:合并基础的webpack配置
配置样式文件的处理规则,styleLoaders
配置webpack的输出
配置webpack插件
gzip模式下的webpack插件配置
webpack-bundle分析
说明: webpack插件里面多了丑化压缩代码以及抽离css文件等插件。var path = require('path')var utils = require('./utils')var webpack = require('webpack')var config = require('../config')var merge = require('webpack-merge')var baseWebpackConfig = require('./webpack.base.conf')//copy-webpack-plugin,用于将static中的静态文件复制到产品文件夹dist
var CopyWebpackPlugin = require('copy-webpack-plugin')var HtmlWebpackPlugin = require('html-webpack-plugin')var ExtractTextPlugin = require('extract-text-webpack-plugin')//optimize-css-assets-webpack-plugin,用于优化和最小化css资源
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')var env =config.build.envvar webpackConfig =merge(baseWebpackConfig, {module: {//样式文件的处理规则,对css/sass/scss等不同内容使用相应的styleLoaders//由utils配置出各种类型的预处理语言所需要使用的loader,例如sass需要使用sass-loader
rules: utils.styleLoaders({sourceMap: config.build.productionSourceMap,extract:true})},//是否使用source-mapdevtool: config.build.productionSourceMap ? '#source-map' : false,//webpack输出路径和命名规则
output: {path: config.build.assetsRoot,filename: utils.assetsPath('js/[name].[chunkhash].js'),chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')},//webpack插件
plugins: [// http://vuejs.github.io/vue-loader/en/workflow/production.htmlnewwebpack.DefinePlugin({'process.env': env}),//丑化压缩JS代码newwebpack.optimize.UglifyJsPlugin({compress: {warnings:false},sourceMap:true}),//extract css into its own file//将css提取到单独的文件newExtractTextPlugin({filename: utils.assetsPath('css/[name].[contenthash].css')}),//Compress extracted CSS. We are using this plugin so that possible//duplicated CSS from different components can be deduped.//优化、最小化css代码,如果只简单使用extract-text-plugin可能会造成css重复//具体原因可以看npm上面optimize-css-assets-webpack-plugin的介绍newOptimizeCSSPlugin({cssProcessorOptions: {safe:true}}),//generate dist index.html with correct asset hash for caching.//you can customize output by editing /index.html//seehttps://github.com/ampedandwired/html-webpack-plugin//将产品文件的引用注入到index.htmlnewHtmlWebpackPlugin({filename: config.build.index,template:'index.html',inject:true,minify: {//删除index.html中的注释removeComments: true,//删除index.html中的空格collapseWhitespace: true,//删除各种html标签属性值的双引号removeAttributeQuotes: true//more options:// https://github.com/kangax/html-minifier#options-quick-reference
},//necessary to consistently work with multiple chunks via CommonsChunkPlugin//注入依赖的时候按照依赖先后顺序进行注入,比如,需要先注入vendor.js,再注入app.jschunksSortMode: 'dependency'}),//keep module.id stable when vender modules does not changenewwebpack.HashedModuleIdsPlugin(),//split vendor js into its own file//将所有从node_modules中引入的js提取到vendor.js,即抽取库文件newwebpack.optimize.CommonsChunkPlugin({name:'vendor',minChunks: function (module, count) {//any required modules inside node_modules are extracted to vendorreturn(module.resource&&/\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname,'../node_modules'))=== 0)}}),//extract webpack runtime and module manifest to its own file in order to//prevent vendor hash from being updated whenever app bundle is updated//从vendor中提取出manifest,原因如上newwebpack.optimize.CommonsChunkPlugin({name:'manifest',chunks: ['vendor']}),//copy custom static assets//将static文件夹里面的静态资源复制到dist/staticnewCopyWebpackPlugin([{from: path.resolve(__dirname, '../static'),to: config.build.assetsSubDirectory,ignore: ['.*']}])]
})//如果开启了产品gzip压缩,则利用插件将构建后的产品文件进行压缩
if(config.build.productionGzip) {//一个用于压缩的webpack插件var CompressionWebpackPlugin = require('compression-webpack-plugin')webpackConfig.plugins.push(newCompressionWebpackPlugin({asset:'[path].gz[query]',//压缩算法algorithm: 'gzip',test:newRegExp('\\.(' +config.build.productionGzipExtensions.join('|') +')$'),threshold:10240,minRatio:0.8}))
}//如果启动了report,则通过插件给出webpack构建打包后的产品文件分析报告
if(config.build.bundleAnalyzerReport) {var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginwebpackConfig.plugins.push(newBundleAnalyzerPlugin())
}module.exports=webpackConfig复制代码
check-versions.js//chalk, 用于在控制台输出带颜色字体的插件
var chalk = require('chalk')//semver, 语义化版本检查插件(The semantic version parser used by npm)
var semver = require('semver')var packageConfig = require('../package.json')//shelljs, 执行Unix命令行的插件
var shell = require('shelljs')//开辟子进程执行指令cmd并返回结果
function exec (cmd) {return require('child_process').execSync(cmd).toString().trim()
}//node和npm版本需求
var versionRequirements =[{name:'node',currentVersion: semver.clean(process.version),versionRequirement: packageConfig.engines.node}
]if (shell.which('npm')) {versionRequirements.push({name:'npm',currentVersion: exec('npm --version'),versionRequirement: packageConfig.engines.npm})
}module.exports=function () {var warnings =[]//依次判断版本是否符合要求for (var i = 0; i < versionRequirements.length; i++) {var mod =versionRequirements[i]if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {warnings.push(mod.name+ ':' +chalk.red(mod.currentVersion)+ 'should be' +chalk.green(mod.versionRequirement))}}//如果有警告则将其输出到控制台if(warnings.length) {console.log('')console.log(chalk.yellow('To use this template, you must update following to modules:'))console.log()for (var i = 0; i < warnings.length; i++) {var warning =warnings[i]console.log('  ' +warning)}console.log()process.exit(1)}
}复制代码
config
index.js
config文件夹下最主要的文件就是index.js了,在这里面描述了开发和构建两种环境下的配置,前面的build文件夹下也有不少文件引用了index.js里面的配置//seehttp://vuejs-templates.github.io/webpackfor documentation.
var path = require('path')module.exports={//构建产品时使用的配置
build: {//环境变量env: require('./prod.env'),//html入口文件index: path.resolve(__dirname, '../dist/index.html'),//产品文件的存放路径assetsRoot: path.resolve(__dirname, '../dist'),//二级目录,存放静态资源文件的目录,位于dist文件夹下assetsSubDirectory: 'static',//发布路径,如果构建后的产品文件有用于发布CDN或者放到其他域名的服务器,可以在这里进行设置//设置之后构建的产品文件在注入到index.html中的时候就会带上这里的发布路径assetsPublicPath: '/',//是否使用source-mapproductionSourceMap: true,//Gzip off by default as many popular static hosts such as//Surge or Netlify already gzip all static assets for you.//Before setting to `true`, make sure to://npm install --save-dev compression-webpack-plugin//是否开启gzip压缩productionGzip: false,//gzip模式下需要压缩的文件的扩展名,设置js、css之后就只会对js和css文件进行压缩productionGzipExtensions: ['js', 'css'],//Run the build command with an extra argument to//View the bundle analyzer report after build finishes://`npm run build --report`//Set to `true` or `false` to always turn it on or off//是否展示webpack构建打包之后的分析报告
bundleAnalyzerReport: process.env.npm_config_report},//开发过程中使用的配置
dev: {//环境变量env: require('./dev.env'),//dev-server监听的端口port: 8080,//是否自动打开浏览器autoOpenBrowser: true,//静态资源文件夹assetsSubDirectory: 'static',//发布路径assetsPublicPath: '/',//代理配置表,在这里可以配置特定的请求代理到对应的API接口//例如将'localhost:8080/api/xxx'代理到'www.example.com/api/xxx'
proxyTable: {},//CSS Sourcemaps off by default because relative paths are "buggy"//with this option, according to the CSS-Loader README//(https://github.com/webpack/css-loader#sourcemaps)//In our experience, they generally work as expected,//just be aware of this issue when enabling this option.//是否开启 cssSourceMapcssSourceMap: false}
}
复制代码'use strict'
const path = require('path')module.exports={dev: {//开发环境下面的配置assetsSubDirectory: 'static',//子目录,一般存放css,js,image等文件assetsPublicPath: '/',//根目录proxyTable: {},//可利用该属性解决跨域的问题host: 'localhost', //地址port: 8080, //端口号设置,端口号占用出现问题可在此处修改autoOpenBrowser: false,//是否在编译(输入命令行npm run dev)后打开http://localhost:8080/页面,以前配置为true,近些版本改为false,个人偏向习惯自动打开页面errorOverlay: true,//浏览器错误提示notifyOnErrors: true,//跨平台错误提示poll: false, //使用文件系统(file system)获取文件改动的通知devServer.watchOptionsdevtool: 'cheap-module-eval-source-map',//增加调试,该属性为原始源代码(仅限行)不可在生产环境中使用cacheBusting: true,//使缓存失效cssSourceMap: true//代码压缩后进行调bug定位将非常困难,于是引入sourcemap记录压缩前后的位置信息记录,当产生错误时直接定位到未压缩前的位置,将大大的方便我们调试
},build: {//生产环境下面的配置index: path.resolve(__dirname, '../dist/index.html'),//index编译后生成的位置和名字,根据需要改变后缀,比如index.phpassetsRoot: path.resolve(__dirname, '../dist'),//编译后存放生成环境代码的位置assetsSubDirectory: 'static',//js,css,images存放文件夹名assetsPublicPath: '/',//发布的根目录,通常本地打包dist后打开文件会报错,此处修改为./。如果是上线的文件,可根据文件存放位置进行更改路径productionSourceMap: true,devtool:'#source-map',////unit的gzip命令用来压缩文件,gzip模式下需要压缩的文件的扩展名有js和cssproductionGzip: false,productionGzipExtensions: ['js', 'css'],bundleAnalyzerReport: process.env.npm_config_report}
}
复制代码
prod.env.js
当开发是调取dev.env.js的开发环境配置,发布时调用prod.env.js的生产环境配置'use strict'module.exports={NODE_ENV:'"production"'}
复制代码
dev.env.js
config内的文件其实是服务于build的,大部分是定义一个变量export出去。'use strict'//采用严格模式
const merge = require('webpack-merge')//
const prodEnv = require('./prod.env')//webpack-merge提供了一个合并函数,它将数组和合并对象创建一个新对象。//如果遇到函数,它将执行它们,通过算法运行结果,然后再次将返回的值封装在函数中.这边将dev和prod进行合并
module.exports =merge(prodEnv, {NODE_ENV:'"development"'})
复制代码
src
①、assets文件:脚手架自动会放入一个图片在里面作为初始页面的logo。平常我们使用的时候会在里面建立js,css,img,fonts等文件夹,作为静态资源调用②、components文件夹:用来存放组件,合理地使用组件可以高效地实现复用等功能,从而更好地开发项目。一般情况下比如创建头部组件的时候,我们会新建一个header的文件夹,然后再新建一个header.vue的文件③、router文件夹:该文件夹下有一个叫index.js文件,用于实现页面的路由跳转,具体使用请点击→vue-router传送门④、App.vue:作为我们的主组件,可通过使用开放入口让其他的页面组件得以显示。⑤、main.js:作为我们的入口文件,主要作用是初始化vue实例并使用需要的插件,小型项目省略router时可放在该处.babelrc
{//制定转码的规则"presets": [//env是使用babel-preset-env插件将js进行转码成es5,并且设置不转码的AMD,COMMONJS的模块文件,制定浏览器的兼容["env", {"modules": false,"targets": {"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]}}],"stage-2"],"plugins": ["transform-vue-jsx", "transform-runtime"]//
}
复制代码
.postcessrc.js
.postcssrc.js文件其实是postcss-loader包的一个配置,在webpack的旧版本可以直接在webpack.config.js中配置,现版本中postcss的文档示例独立出.postcssrc.js,里面写进去需要使用到的插件module.exports={"plugins": {"postcss-import": {},//"postcss-url": {},//"autoprefixer": {}//
}
}
复制代码
package.json
package.json来制定名单,需要哪些npm包来参与到项目中来,npm install命令根据这个配置文件增减来管理本地的安装包{//从name到private都是package的配置信息,也就是我们在脚手架搭建中输入的项目描述"name": "shop",//项目名称:不能以.(点)或者_(下划线)开头,不能包含大写字母,具有明确的的含义与现有项目名字不重复"version": "1.0.0",//项目版本号:遵循“大版本.次要版本.小版本”"description": "A Vue.js project",//项目描述"author": "qietuniu",//作者名字"private": true,//是否私有//scripts中的子项即是我们在控制台运行的脚本的缩写"scripts": {//①webpack-dev-server:启动了http服务器,实现实时编译;//inline模式会在webpack.config.js入口配置中新增webpack-dev-server/client?http://localhost:8080/的入口,使得我们访问路径为localhost:8080/index.html(相应的还有另外一种模式Iframe);//progress:显示打包的进度"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js","start": "npm run dev",//与npm run dev相同,直接运行开发环境"build": "node build/build.js"//使用node运行build文件
},//②dependencies(项目依赖库):在安装时使用--save则写入到dependencies"dependencies": {"vue": "^2.5.2",//vue.js"vue-router": "^3.0.1"//vue的路由插件
},//和devDependencies(开发依赖库):在安装时使用--save-dev将写入到devDependencies"devDependencies": {"autoprefixer": "^7.1.2",//autoprefixer作为postcss插件用来解析CSS补充前缀,例如 display: flex会补充为display:-webkit-box;display: -webkit-flex;display: -ms-flexbox;display: flex。//babel:以下几个babel开头的都是针对es6解析的插件。用最新标准编写的 JavaScript 代码向下编译成可以在今天随处可用的版本"babel-core": "^6.22.1",//babel的核心,把 js 代码分析成 ast ,方便各个插件分析语法进行相应的处理。"babel-helper-vue-jsx-merge-props": "^2.0.3",//预制babel-template函数,提供给vue,jsx等使用"babel-loader": "^7.1.1",//使项目运行使用Babel和webpack来传输js文件,使用babel-core提供的api进行转译"babel-plugin-syntax-jsx": "^6.18.0",//支持jsx"babel-plugin-transform-runtime": "^6.22.0",//避免编译输出中的重复,直接编译到build环境中"babel-plugin-transform-vue-jsx": "^3.5.0",//babel转译过程中使用到的插件,避免重复"babel-preset-env": "^1.3.2",//转为es5,transform阶段使用到的插件之一"babel-preset-stage-2": "^6.22.0",//ECMAScript第二阶段的规范"chalk": "^2.0.1",//用来在命令行输出不同颜色文字"copy-webpack-plugin": "^4.0.1",//拷贝资源和文件"css-loader": "^0.28.0",//webpack先用css-loader加载器去解析后缀为css的文件,再使用style-loader生成一个内容为最终解析完的css代码的style标签,放到head标签里"extract-text-webpack-plugin": "^3.0.0",//将一个以上的包里面的文本提取到单独文件中"file-loader": "^1.1.4",//③打包压缩文件,与url-loader用法类似"friendly-errors-webpack-plugin": "^1.6.1",//识别某些类别的WebPACK错误和清理,聚合和优先排序,以提供更好的开发经验"html-webpack-plugin": "^2.30.1",//简化了HTML文件的创建,引入了外部资源,创建html的入口文件,可通过此项进行多页面的配置"node-notifier": "^5.1.2",//支持使用node发送跨平台的本地通知"optimize-css-assets-webpack-plugin": "^3.2.0",//压缩提取出的css,并解决ExtractTextPlugin分离出的js重复问题(多个文件引入同一css文件)"ora": "^1.2.0",//加载(loading)的插件"portfinder": "^1.0.13",//查看进程端口"postcss-import": "^11.0.0",//可以消耗本地文件、节点模块或web_modules"postcss-loader": "^2.0.8",//用来兼容css的插件"postcss-url": "^7.2.1",//URL上重新定位、内联或复制"rimraf": "^2.6.0",//节点的UNIX命令RM—RF,强制删除文件或者目录的命令"semver": "^5.3.0",//用来对特定的版本号做判断的"shelljs": "^0.7.6",//使用它来消除shell脚本在UNIX上的依赖性,同时仍然保留其熟悉和强大的命令,即可执行Unix系统命令"uglifyjs-webpack-plugin": "^1.1.1",//压缩js文件"url-loader": "^0.5.8",//压缩文件,可将图片转化为base64"vue-loader": "^13.3.0",//VUE单文件组件的WebPACK加载器"vue-style-loader": "^3.0.1",//类似于样式加载程序,您可以在CSS加载器之后将其链接,以将CSS动态地注入到文档中作为样式标签"vue-template-compiler": "^2.5.2",//这个包可以用来预编译VUE模板到渲染函数,以避免运行时编译开销和CSP限制"webpack": "^3.6.0",//打包工具"webpack-bundle-analyzer": "^2.9.0",//可视化webpack输出文件的大小"webpack-dev-server": "^2.9.1",//提供一个提供实时重载的开发服务器"webpack-merge": "^4.1.0"//它将数组和合并对象创建一个新对象。如果遇到函数,它将执行它们,通过算法运行结果,然后再次将返回的值封装在函数中
},//engines是引擎,指定node和npm版本"engines": {"node": ">= 6.0.0","npm": ">= 3.0.0"},//限制了浏览器或者客户端需要什么版本才可运行"browserslist": ["> 1%","last 2 versions","not ie <= 8"]
}
复制代码
注释:①、点这里→webpack运行时的配置文档传送门②、devDependencies和dependencies的区别: devDependencies里面的插件只用于开发环境,不用于生产环境,即辅助作用,打包的时候需要,打包完成就不需要了。而dependencies是需要发布到生产环境的,自始至终都在。比如wepack等只是在开发中使用的包就写入到devDependencies,而像vue这种项目全程依赖的包要写入到dependencies点这里→更多安装包文档搜索页传送门③、file-loader和url-loader的区别:以图片为例,file-loader可对图片进行压缩,但是还是通过文件路径进行引入,当http请求增多时会降低页面性能,而url-loader通过设定limit参数,小于limit字节的图片会被转成base64的文件,大于limit字节的将进行图片压缩的操作。总而言之,url-loader是file-loader的上层封装。点这里→file-loader 和 url-loader详解点这里→file-loader文档传送门点这里→url-loader文档传送门其他文件
①、.editorconfig:编辑器的配置文件②、.gitignore:忽略git提交的一个文件,配置之后提交时将不会加载忽略的文件③、index.html:页面入口,经过编译之后的代码将插入到这来。④、package.lock.json:锁定安装时的包的版本号,并且需要上传到git,以保证其他人在npm install时大家的依赖能保证一致⑤、README.md:可此填写项目介绍⑥、node_modules:根据package.json安装时候生成的的依赖(安装包)其他好的博客笔记
vue-cli的webpack模板项目配置文件分析vue-cli脚手架中webpack配置基础文件详解

转载于:https://www.cnblogs.com/Jeely/p/11230737.html

vue-cli 目录结构详细讲解相关推荐

  1. Vue项目目录结构介绍讲解

    1.Vue单文件组件 node_modules:依赖的node工具包目录 public: 一般用于存放一些静态资源文件,例如图片,视频,音频等资源文件.需要特别注意的是webpack在进行打包的时候, ...

  2. Vue项目目录结构介绍(三)

    前言 本章我们会对一个 Vue 项目的目录结构进行讲解,解释各子目录以及文件的作用,前端的模块化,Vue 单文件组件规范等. 1.基础目录和文件介绍 在上一章,我们通过 vue-cli 创建了一个新的 ...

  3. 【Vue前端开发学习】第2章,Vue项目目录结构

    文章目录 前言 一.新增router文件夹及其配置方法 二.新增store文件夹及其配置方法 三.index.html.App.vue.main.js三者之间的联系 前言   上一章节,通过Pycha ...

  4. Vue模仿todo超详细讲解(附源码)

    Vue模仿todo超详细讲解(附源码) 一.todo基本DOM结构 二.todo功能需求分析 1.新增任务 2.点击变成完成状态 3.点击删除 4.双击进入编辑以及修改保存 5.底部的状态筛选 6.l ...

  5. Vue基础 目录结构与代码

    作者简介:一名计算机萌新.前来进行学习VUE,让我们一起进步吧.   座右铭:低头赶路,敬事如仪 个人主页:我叫于豆豆吖的主页 目录 前言 一.Vue.js 目录结构 1.目录解析 二.Vue.js ...

  6. Vue CLI安装的详细步骤

    Vue CLI安装的详细步骤 为了以后安装方便,写一个具体的步骤. 1.首先,打开vue官网,在生态系统的工具里找到Vue CLI,点击安装,先全局安装,直接打开cmd命令,执行以下命令.(我选的第一 ...

  7. tomcat的服务器目录在哪个文件夹,Tomcat目录结构详细介绍

    打开tomcat的解压之后的目录可以看到如下的目录结构: 1.Tomcat的bin目录: bin目录主要是用来存放tomcat的命令,主要有两大类,一类是以.sh结尾的(linux命令),另一类是以. ...

  8. vue中computed的详细讲解

    vue中computed的详细讲解 1.定义 2.用法 3.computed的响应式依赖(缓存) 4.应用场景 1.定义 computed是vue的计算属性,是根据依赖关系进行缓存的计算,只有在它的相 ...

  9. vue php 架构目录,Vue.js 目录结构

    Vue.js 目录结构 上一章节中我们使用了 npm 安装项目,我们在 IDE(Eclipse.Atom等) 中打开该目录,结构如下所示: 目录解析目录/文件说明build项目构建(webpack)相 ...

最新文章

  1. mysql的limit性能优化
  2. 框架源码系列四:手写Spring-配置(为什么要提供配置的方法、选择什么样的配置方式、配置方式的工作过程是怎样的、分步骤一个一个的去分析和设计)...
  3. B16_NumPy线性代数(dot,vdot,inner,matmul,determinant,solve,inv)
  4. php -q poller.php --force,cacti 安装后没有图像
  5. linux+显卡+停止运行,Linux secure boot(安全启动)时添加Nvidia显卡驱动
  6. TensorFlow 之快速上手详解
  7. apache-commons pool使用
  8. python列表转化为元组、集合_如何在Python中将元组列表更改为集合?
  9. asp.net mvc在Model中控制日期格式
  10. 微信小程序开发--【Hello World 及代码结构】(二)
  11. python读取dbf并导出excel格式_Python导出DBF文件到Excel的方法
  12. 机架式服务器可以安装win7系统,Win7 32位系统怎么安装电音
  13. ubuntu20.04系统安装u盘制作方法
  14. 技术贴 - 收藏集 - 掘金
  15. 四象限法推导lm曲线_SEM数据分析四象限方法
  16. idea maven parent飘红
  17. 《数字图像处理》手动实现最佳陷波滤波
  18. http网站怎么配置https防劫持
  19. linux下常用alias
  20. 第十一课_编程语言发展史

热门文章

  1. 读书|《第七感》:权力、财富与这个世界的生存法则
  2. 三星电视三星服务器没响应,三星液晶电视的常见故障有哪些
  3. 大度是人生不可缺少的高贵品质
  4. jmeter并发测试教程_Jmeter多用户并发压力测试过程图解
  5. linux解压jar
  6. [日推荐]『法条大全』小程序成法庭利器!
  7. vue echarts地图省市区下钻
  8. 基于VisualSFM的三维重建(一)
  9. 【IC 10】差分输入;仪表放大器和运算放大器的区别 - 仪表放大器和运算放大器优缺点对比
  10. java log4j 路径配置_log4j配置文件中路径配置一般有三种方法: