目录 一级 二级 bulid 项目构建的一些 js 文件 config 配置文件项,index.js 比较重要,打包上线需要修改配置 dist 项目打包后的文件 node_modules npm安装包位置 src 项目的开发目录 - assets 图片、字体等资源 - components 公共组件部分 - config 开发分支和生产分支的切换配置,以及 fetch.js 对于前后台数据交互的封装 - plugin 第三方插件 - views 页面部分 - server ajax、axios等请求数据集中处理 - router 路由 - store 状态管理 - App.vue 项目入口文件,我们也可以直接将组建写这里,而不使用 components 目录 - main.js 项目的核心文件 index.html html文件 test 测试项目 package.json 项目配置项文件 
基础库: vue.js、vue-router、vuex、whatwg-fetch
编译/打包工具:webpack、babel、node-sass
单元测试工具:karma、mocha、sinon-chai
本地服务器:express目录结构
README.md            项目介绍
index.html           入口页面
build                构建脚本目录build-server.js           运行本地构建服务器,可以访问构建后的页面build.js                  生产环境构建脚本dev-client.js             开发服务器热重载脚本,主要用来实现开发阶段的页面自动刷新dev-server.js          	  运行本地开发服务器utils.js                  构建相关工具方法webpack.base.conf.js      wabpack基础配置webpack.dev.conf.js       wabpack开发环境配置webpack.prod.conf.js      wabpack生产环境配置
config                	   项目配置dev.env.js             开发环境变量index.js               项目配置文件prod.env.js            生产环境变量test.env.js            测试环境变量
mock              	 	   mock数据目录hello.js
package.json          	   npm包配置文件,里面定义了项目的npm脚本,依赖包等信息
src                        源码目录 main.js                入口js文件app.vue                根组件components             公共组件目录title.vueassets                 资源目录,这里的资源会被wabpack构建imageslogo.pngroutes         	       前端路由index.jsstore                  应用级数据(state)index.jsviews                  页面目录hello.vue
static             		   纯静态资源,不会被wabpack构建。
test               		   测试文件目录(unit& e2e)unit              	   单元测试index.js           入口脚本karma.conf.js          karma配置文件specs                  单测case目录Hello.spec.js
1. build文件夹 
( 1 ) build. js'use strict'                                     
require ( './check-versions' ) ( )                    process. env. NODE_ENV  =  'production'              
const  ora =  require ( 'ora' )  
const  rm =  require ( 'rimraf' )  
const  path =  require ( 'path' )  
const  chalk =  require ( 'chalk' )  
const  webpack =  require ( 'webpack' )  
const  config =  require ( '../config' )  
const  webpackConfig =  require ( './webpack.prod.conf' )  
const  spinner =  ora ( 'building for production...' ) 
spinner. start ( ) 
rm ( path. join ( config. build. assetsRoot,  config. build. assetsSubDirectory) ,  err =>  { if  ( err)  throw  errwebpack ( webpackConfig,  ( err,  stats)  =>  { spinner. stop ( ) if  ( err)  throw  errprocess. 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' ) ) } ) 
} ) ( 2 ) check- versions. js     node和npm的版本检测,  实现版本依赖
'use strict'                                             
const  chalk =  require ( 'chalk' ) 
const  semver =  require ( 'semver' )  
const  packageConfig =  require ( '../package.json' ) 
const  shell =  require ( 'shelljs' )  function  exec  ( cmd)  { return  require ( 'child_process' ) . execSync ( cmd) . toString ( ) . trim ( ) 
} 
const  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  ( )  { const  warnings =  [ ] for  ( let  i =  0 ;  i <  versionRequirements. length;  i++ )  { const  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  ( let  i =  0 ;  i <  warnings. length;  i++ )  { const  warning =  warnings[ i] console . log ( '  '  +  warning) } console . log ( ) process. exit ( 1 ) } 
} ( 3 ) utils. js   utils是工具的意思,是一个用来处理css的文件,这个文件包含了三个工具函数: 
生成静态资源的路径
生成 ExtractTextPlugin对象或loader字符串
生成 style- loader的配置
'use strict' 
const  path =  require ( 'path' ) 
const  config =  require ( '../config' )                                  
const  ExtractTextPlugin =  require ( 'extract-text-webpack-plugin' )     
const  packageConfig =  require ( '../package.json' ) 
exports. assetsPath  =  function  ( _path)  { const  assetsSubDirectory =  process. env. NODE_ENV  ===  'production' ?  config. build. assetsSubDirectory:  config. dev. assetsSubDirectory
return  path. posix. join ( assetsSubDirectory,  _path)                  
} 
exports. cssLoaders  =  function  ( options)  { options =  options ||  { } const  cssLoader =  { loader:  'css-loader' , options:  { sourceMap:  options. sourceMap} } const  postcssLoader =  { loader:  'postcss-loader' , options:  { sourceMap:  options. sourceMap} } function  generateLoaders  ( loader,  loaderOptions)  { const  loaders =  options. usePostCSS ?  [ cssLoader,  postcssLoader]  :  [ cssLoader] if  ( loader)  { loaders. push ( { loader:  loader +  '-loader' , options:  Object. assign ( { } ,  loaderOptions,  { sourceMap:  options. sourceMap} ) } ) } if  ( options. extract)  { return  ExtractTextPlugin. extract ( { use:  loaders, fallback:  'vue-style-loader' } ) }  else  { return  [ 'vue-style-loader' ] . concat ( loaders) } } return  { css:  generateLoaders ( ) , postcss:  generateLoaders ( ) , less:  generateLoaders ( 'less' ) , sass:  generateLoaders ( 'sass' ,  {  indentedSyntax:  true  } ) , scss:  generateLoaders ( 'sass' ) , stylus:  generateLoaders ( 'stylus' ) , styl:  generateLoaders ( 'stylus' ) } 
} 
exports. styleLoaders  =  function  ( options)  { const  output =  [ ] const  loaders =  exports. cssLoaders ( options) 
for  ( const  extension in  loaders)  { const  loader =  loaders[ extension] output. push ( { test:  new  RegExp ( '\\.'  +  extension +  '$' ) , use:  loader} ) } return  output
} exports. createNotifierCallback  =  ( )  =>  { const  notifier =  require ( 'node-notifier' ) return  ( severity,  errors)  =>  { if  ( severity !==  'error' )  return const  error =  errors[ 0 ] const  filename =  error. file &&  error. file. split ( '!' ) . pop ( ) notifier. notify ( { title:  packageConfig. name, message:  severity +  ': '  +  error. name, subtitle:  filename ||  '' , icon:  path. join ( __dirname,  'logo.png' ) } ) } 
} ( 4 ) vue- loader. conf. js 处理. vue文件,解析这个文件中的每个语言块(template、script、style) ,转换成js可用的js模块
'use strict' 
const  utils =  require ( './utils' ) 
const  config =  require ( '../config' ) 
const  isProduction =  process. env. NODE_ENV  ===  'production' 
const  sourceMapEnabled =  isProduction?  config. build. productionSourceMap:  config. dev. cssSourceMap
module . exports =  { loaders:  utils. cssLoaders ( { sourceMap:  sourceMapEnabled, extract:  isProduction} ) , cssSourceMap:  sourceMapEnabled, cacheBusting:  config. dev. cacheBusting, transformToRequire:  { video:  [ 'src' ,  'poster' ] , source:  'src' , img:  'src' , image:  'xlink:href' } 
} ( 5 ) webpack. base. conf. js:开发、测试、生产环境的公共基础配置文件,配置输出环境,配置模块resolve和插件等
'use strict' 
const  path =  require ( 'path' ) 
const  utils =  require ( './utils' ) 
const  config =  require ( '../config' ) 
const  vueLoaderConfig =  require ( './vue-loader.conf' ) 
function  resolve ( dir)  { return  path. join ( __dirname,  '..' ,  dir) 
} module . exports =  { context:  path. resolve ( __dirname,  '../' ) , entry:  { app:  './src/main.js' } , output:  { path:  config. build. assetsRoot, filename:  '[name].js' , publicPath:  process. env. NODE_ENV  ===  'production' ?  config. build. assetsPublicPath:  config. dev. assetsPublicPath} , resolve:  { extensions:  [ '.js' ,  '.vue' ,  '.json' ] , alias:  { 'vue$' :  'vue/dist/vue.esm.js' , '@' :  resolve ( 'src' ) , } } , module :  { rules:  [ { test:  /\.vue$/ , loader:  'vue-loader' , options:  vueLoaderConfig} , { test:  /\.js$/ , loader:  'babel-loader' , include:  [ resolve ( 'src' ) ,  resolve ( 'test' ) ,  resolve ( 'node_modules/webpack-dev-server/client' ) ] } , { test:  /\.(png|jpe?g|gif|svg)(\?.*)?$/ , loader:  'url-loader' , options:  { limit:  10000 , name:  utils. assetsPath ( 'img/[name].[hash:7].[ext]' ) } } , { test:  /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/ , loader:  'url-loader' , options:  { limit:  10000 , name:  utils. assetsPath ( 'media/[name].[hash:7].[ext]' ) } } , { test:  /\.(woff2?|eot|ttf|otf)(\?.*)?$/ , loader:  'url-loader' , options:  { limit:  10000 , name:  utils. assetsPath ( 'fonts/[name].[hash:7].[ext]' ) } } ] } , node:  { setImmediate:  false , dgram:  'empty' , fs:  'empty' , net:  'empty' , tls:  'empty' , child_process:  'empty' } 
} 
(6 )webpack. dev. conf. js:webpack配置开发环境中的入口
'use strict' 
const  utils =  require ( './utils' ) 
const  webpack =  require ( 'webpack' ) 
const  config =  require ( '../config' ) 
const  merge =  require ( 'webpack-merge' ) 
const  path =  require ( 'path' ) 
const  baseWebpackConfig =  require ( './webpack.base.conf' ) 
const  CopyWebpackPlugin =  require ( 'copy-webpack-plugin' ) 
const  HtmlWebpackPlugin =  require ( 'html-webpack-plugin' ) 
const  FriendlyErrorsPlugin =  require ( 'friendly-errors-webpack-plugin' ) 
const  portfinder =  require ( 'portfinder' ) const  HOST  =  process. env. HOST 
const  PORT  =  process. env. PORT  &&  Number ( process. env. PORT ) const  devWebpackConfig =  merge ( baseWebpackConfig,  { module :  { rules:  utils. styleLoaders ( {  sourceMap:  config. dev. cssSourceMap,  usePostCSS:  true  } ) } , devtool:  config. dev. devtool, devServer:  { clientLogLevel:  'warning' , historyApiFallback:  { rewrites:  [ {  from :  /.*/ ,  to:  path. posix. join ( config. dev. assetsPublicPath,  'index.html' )  } , ] , } , hot:  true , contentBase:  false ,  compress:  true , host:  HOST  ||  config. dev. host, port:  PORT  ||  config. dev. port, open:  config. dev. autoOpenBrowser, overlay:  config. dev. errorOverlay?  {  warnings:  false ,  errors:  true  } :  false , publicPath:  config. dev. assetsPublicPath, proxy:  config. dev. proxyTable, quiet:  true ,  watchOptions:  { poll:  config. dev. poll, } } , plugins:  [ new  webpack. DefinePlugin ( { 'process.env' :  require ( '../config/dev.env' ) } ) , new  webpack. HotModuleReplacementPlugin ( ) , new  webpack. NamedModulesPlugin ( ) ,  new  webpack. NoEmitOnErrorsPlugin ( ) , new  HtmlWebpackPlugin ( { filename:  'index.html' , template:  'index.html' , inject:  true } ) , new  CopyWebpackPlugin ( [ { from :  path. resolve ( __dirname,  '../static' ) , to:  config. dev. assetsSubDirectory, ignore:  [ '.*' ] } ] ) ] 
} ) module . exports =  new  Promise ( ( resolve,  reject)  =>  { portfinder. basePort =  process. env. PORT  ||  config. dev. portportfinder. getPort ( ( err,  port)  =>  {  if  ( err)  { reject ( err) }  else  { process. env. PORT  =  portdevWebpackConfig. devServer. port =  portdevWebpackConfig. plugins. push ( new  FriendlyErrorsPlugin ( { compilationSuccessInfo:  { messages:  [ `Your application is running here: http:// ${ devWebpackConfig. devServer. host} : ${ port} ` ] , } , onErrors:  config. dev. notifyOnErrors?  utils. createNotifierCallback ( ) :  undefined} ) ) resolve ( devWebpackConfig) } } ) 
} ) (7 )webpack. dev. prod. js:webpack配置生产环境中的入口'use strict' 
const  path =  require ( 'path' ) 
const  utils =  require ( './utils' ) 
const  webpack =  require ( 'webpack' ) 
const  config =  require ( '../config' ) 
const  merge =  require ( 'webpack-merge' ) 
const  baseWebpackConfig =  require ( './webpack.base.conf' ) 
const  CopyWebpackPlugin =  require ( 'copy-webpack-plugin' ) 
const  HtmlWebpackPlugin =  require ( 'html-webpack-plugin' ) 
const  ExtractTextPlugin =  require ( 'extract-text-webpack-plugin' ) 
const  OptimizeCSSPlugin =  require ( 'optimize-css-assets-webpack-plugin' ) 
const  UglifyJsPlugin =  require ( 'uglifyjs-webpack-plugin' ) const  env =  require ( '../config/prod.env' ) const  webpackConfig =  merge ( baseWebpackConfig,  { module :  { rules:  utils. styleLoaders ( { sourceMap:  config. build. productionSourceMap, extract:  true , usePostCSS:  true } ) } , devtool:  config. build. productionSourceMap ?  config. build. devtool :  false , output:  { path:  config. build. assetsRoot, filename:  utils. assetsPath ( 'js/[name].[chunkhash].js' ) , chunkFilename:  utils. assetsPath ( 'js/[id].[chunkhash].js' ) } , plugins:  [ new  webpack. DefinePlugin ( { 'process.env' :  env} ) , new  UglifyJsPlugin ( { uglifyOptions:  { compress:  { warnings:  false } } , sourceMap:  config. build. productionSourceMap, parallel:  true } ) , new  ExtractTextPlugin ( { filename:  utils. assetsPath ( 'css/[name].[contenthash].css' ) , allChunks:  true , } ) , new  OptimizeCSSPlugin ( { cssProcessorOptions:  config. build. productionSourceMap?  {  safe:  true ,  map:  {  inline:  false  }  } :  {  safe:  true  } } ) , new  HtmlWebpackPlugin ( {  filename:  config. build. index, template:  'index.html' , inject:  true , minify:  { removeComments:  true , collapseWhitespace:  true , removeAttributeQuotes:  true } , chunksSortMode:  'dependency' } ) , new  webpack. HashedModuleIdsPlugin ( ) , new  webpack. optimize. ModuleConcatenationPlugin ( ) , new  webpack. optimize. CommonsChunkPlugin ( {   name:  'vendor' , minChunks  ( module )  { return  ( module . resource && /\.js$/ . test ( module . resource)  && module . resource. indexOf ( path. join ( __dirname,  '../node_modules' ) )  ===  0 ) } } ) , new  webpack. optimize. CommonsChunkPlugin ( { name:  'manifest' , minChunks:  Infinity } ) , new  webpack. optimize. CommonsChunkPlugin ( { name:  'app' , async :  'vendor-async' , children:  true , minChunks:  3 } ) , new  CopyWebpackPlugin ( [ { from :  path. resolve ( __dirname,  '../static' ) , to:  config. build. assetsSubDirectory, ignore:  [ '.*' ] } ] ) ] 
} ) if  ( config. build. productionGzip)  { const  CompressionWebpackPlugin =  require ( 'compression-webpack-plugin' ) webpackConfig. plugins. push ( new  CompressionWebpackPlugin ( { asset:  '[path].gz[query]' , algorithm:  'gzip' , test:  new  RegExp ( '\\.('  + config. build. productionGzipExtensions. join ( '|' )  + ')$' ) , threshold:  10240 , minRatio:  0.8 } ) ) 
} if  ( config. build. bundleAnalyzerReport)  { const  BundleAnalyzerPlugin =  require ( 'webpack-bundle-analyzer' ) . BundleAnalyzerPluginwebpackConfig. plugins. push ( new  BundleAnalyzerPlugin ( ) ) 
} module . exports =  webpackConfig2. config文件夹
(1 ) dev. env. js和prod. env. js:分别配置:开发环境和生产环境。这个可以根据公司业务结合后端需求配置需要区分开发环境和测试环境的属性
'use strict' 
const  merge =  require ( 'webpack-merge' ) 
const  prodEnv =  require ( './prod.env' ) module . exports =  merge ( prodEnv,  { NODE_ENV :  '"development"' 
} ) ps:webpack- merge用于实现合并类似于ES6 的Object. assign ( ) 'use strict' 
module . exports =  { NODE_ENV :  '"production"' 
} 
(* 注意属性值要用“‘'”双层引住),访问(获取值)时直接用:process. env. 属性名ps:process(进程)是nodejs的一个全局变量,process. env 属性返回一个用户环境信息的对象(2 )index. js配置解析:'use strict' ; 
const  path =  require ( 'path' ) ; module . exports =  { dev:  { assetsSubDirectory:  'static' , assetsPublicPath:  '/' , proxyTable:  { } , host:  'localhost' ,  port:  3030 ,  autoOpenBrowser:  true , errorOverlay:  true , notifyOnErrors:  true , poll:  false ,  devtool:  'cheap-module-eval-source-map' , cacheBusting:  true , cssSourceMap:  true  } , build:  { index:  path. resolve ( __dirname,  '../dist/index.html' ) , assetsRoot:  path. resolve ( __dirname,  '../dist' ) , assetsSubDirectory:  'static' , assetsPublicPath:  '/' , productionSourceMap:  true , devtool:  '#source-map' , productionGzip:  false , productionGzipExtensions:  [ 'js' ,  'css' ] , bundleAnalyzerReport:  process. env. npm_config_report } 
} ; 3 、node_modules文件夹:
存放npm install时根据package . json配置生成的npm安装包的文件夹4 、src文件夹:
我们需要在src文件夹中开发代码,打包时webpack会根据build中的规则(build规则依赖于config中的配置)将src打包压缩到dist文件夹在浏览器中运行
(1 )assets文件:用于存放静态资源(css、image),assets打包时路径会经过webpack中的file- loader编译(因此,assets需要使用绝对路径)成js
(2 )components文件夹:用来存放 . vue 组件 ( 实现复用等功能,如:过滤器,列表项等) 
(3 )router文件夹:在router/ index. js文件中配置页面路由
(4 )App. vue:是整个项目的主组件,所有页面都是通过使用< router- view/ > 开放入口在App. vue下进行切换的(所有的路由都是App. vue的子组件)
(5 )main. js:入口js文件(全局js,你可以在这里:初始化vue实例、require / import 需要的插件、注入router路由、引入store状态管理)5 、static 文件夹:
webpack默认存放静态资源(css、image)的文件夹,与assets不同的是:static 在打包时会直接复制一个同名文件夹到dist文件夹里(不会经过编译,可使用相对路径)6 、其他文件:
(1 ). babelrc:浏览器解析的兼容配置,该文件主要是对预设(presets)和插件(plugins)进行配置,因此不同的转译器作用不同的配置项,大致可分为:语法转义器、补丁转义器、sx和flow插件
(2 ). editorconfig:用于配置代码格式(配合代码检查工具使用,如:ESLint,团队开发时可统一代码风格),这里配置的代码规范规则优先级高于编辑器默认的代码格式化规则 。
(3 ). gitignore:配置git提交时需要忽略的文件
(4 )postcssrc. js: autoprefixer(自动补全css样式的浏览器前缀);postcss- import (@import 引入语法)、CSS  Modules(规定样式作用域)
(5 )index. html:项目入口页面,编译之后所有代码将插入到这来
(6 )package . json:npm的配置文件(npm install根据package . json下载对应版本的安装包)
(7 )package . lock. json:npm install(安装)时锁定各包的版本号
(8 )README . md:项目使用说明