vue-cli脚手架目录一览
最近在学习vue,看的稀里糊涂。今天从头开始,把cli配置的vue项目目录和配置文件搞清楚。

先看看整个项目目录结构:

vue2 全局安装yarn vue-cli全局安装_json


再看看build文件夹下相关文件及目录:

vue2 全局安装yarn vue-cli全局安装_配置文件_02

config文件夹下目录和文件:

vue2 全局安装yarn vue-cli全局安装_json_03


接下来说说vue-cli项目中页面相关的主要文件o

首先是index.html:
说明:一般只定义一个空的根节点,在main.js里面定义的实例将挂载在#app节点下,内容通过vue组件填充。

vue2 全局安装yarn vue-cli全局安装_css_04


App.vue文件:

说明:app.vue是项目的主组件,所有页面都是在app.vue下切换的。一个标准的vue文件,分为三部分。

第一装写html代码在中,一般在此下面只能定义一个根节点;

第二标签;

第三用来写样式,其中scoped表示。该style作用于只在当前组件的节点及其子节点,但是不包含子组件呦。

是子路由视图,后面的路由页面都显示在此处,相当于一个指示标,指引显示哪个页面。

vue2 全局安装yarn vue-cli全局安装_css_05

main.js:

说明:入口文件来着,主要作用是初始化vue实例并使用需要的插件。比如下面引用了4个插件,但只用了app(components里面是引用的插件)。

vue2 全局安装yarn vue-cli全局安装_json_06

router下面的index.js文件:路由配置文件。

说明:定义了三个路由,分别是路径为/,路径为/msg,路径为/detail。后续会详细说明,因为我也是才学好多东西不懂,囧。

vue2 全局安装yarn vue-cli全局安装_配置文件_07


build.js作用:命令npm run build的入口配置文件,主要用于生产环境。

vue2 全局安装yarn vue-cli全局安装_vue-cli目录详解_08


build.js中具体含义标注(vue-cli脚手架官方文件解释,大家可自行定制这里面的内容):

vue2 全局安装yarn vue-cli全局安装_配置文件_09

check-version.js,文件有点点长这里直接贴代码:

‘use strict’ //js严格运行模式
 const chalk = require(‘chalk’) //导入chalk模块,const声明一个常量
 const semver = require(‘semver’) //同上
 const packageConfig = require(’…/package.json’) //导入package.json文件 const shell = require(‘shelljs’)//shelljs插件,执行unix系统命令function exec (cmd) {
 //脚本可以通过child_process模块新建子进程,从而执行Unix系统命令
 return require(‘child_process’).execSync(cmd).toString().trim()//将cmd参数传递的值转换成前后没有空格的字符串,也就是版本号
 }
 //声明常量数组,数组内容为有关node相关信息的对象
 const versionRequirements = [
 {
 name: ‘node’,//对象名称为node
 currentVersion: semver.clean(process.version),//使用semver插件,把版本信息转换成规定格式
 versionRequirement: packageConfig.engines.node//规定package.json中engines选项的node版本信息
 }
 ]if (shell.which(‘npm’)) {//which为linux指令,在$path规定的路径下查找符合条件的文件
 versionRequirements.push({
 name: ‘npm’,
 currentVersion: exec(‘npm --version’),//调用npm --version命令,并且把参数返回给exec函数获取纯净版本
 versionRequirement: packageConfig.engines.npm//规定package.json中engines选项的node版本信息
 })
 }module.exports = function () {
 const warnings = []for (let i = 0; i < versionRequirements.length; i++) {
 const mod = versionRequirements[i]
   //如果版本号不符合package.json文件中指定的版本号,就执行warning.push…
 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)
}
 }utils.js还是需要贴代码,太长了:
‘use strict’//js严格模式执
 const path = require(‘path’)//导入path模
 const config = require(’…/config’)//引入config目录下的index.js配置文件 const ExtractTextPlugin = require(‘extract-text-webpack-plugin’)//一个插件,抽离css样式,防止将样式打包在js中引起样式加载错乱
 const packageConfig = require(’…/package.json’)
 //导出assetsPath
 exports.assetsPath = function (_path) {
 //如果是生产环境,则assetsSubDirectory的值为index.js文件中的assetsSubDirectory的值,否则…
 const assetsSubDirectory = process.env.NODE_ENV === ‘production’
 ? config.build.assetsSubDirectory
 : config.dev.assetsSubDirectoryreturn path.posix.join(assetsSubDirectory, _path)//path.join返回绝对路径(在电脑上的实际位置);path.posix.join返回相对路径
 }
 //cssloaders相关配置
 exports.cssLoaders = function (options) {
 options = options || {}const cssLoader = {
 loader: ‘css-loader’,//loader还是看看webpack官方解释,处理除js之外的文件?
 options: {//传递参数给loader
 sourceMap: options.sourceMap//是否开启cssmap,默认为false
 }
 }
 //postcss-loader相关
 const postcssLoader = {
 loader: ‘postcss-loader’,
 options: {
 sourceMap: options.sourceMap
 }
 }// generate loader string to be used with extract text plugin
 function generateLoaders (loader, loaderOptions) {
 const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]//是否使用postCssif (loader) {
  loaders.push({
    loader: loader + '-loader',//加载对应loader
    options: Object.assign({}, loaderOptions, {//object.assign浅拷贝合并对象
      sourceMap: options.sourceMap
    })
  })
}

// Extract CSS when that option is specified
//
if (options.extract) {
  return ExtractTextPlugin.extract({
    use: loaders,
    fallback: 'vue-style-loader'
  })
} else {
  return ['vue-style-loader'].concat(loaders)
}//返回最终读取和导入loader
 }// https://vue-loader.vuejs.org/en/configurations/extract-css.html return {
 css: generateLoaders(),//css对应vue-style-loader和css-loader
 postcss: generateLoaders(),//postcss对应vue-style-loader和less-loader
 less: generateLoaders(‘less’),//less对应…(同上)
 sass: generateLoaders(‘sass’, { indentedSyntax: true }),
 scss: generateLoaders(‘sass’),
 stylus: generateLoaders(‘stylus’),
 styl: generateLoaders(‘stylus’)
 }
 }// Generate loaders for standalone style files (outside of .vue)
 exports.styleLoaders = function (options) {
 const output = []
 const loaders = exports.cssLoaders(options)
 //生成的各种css文件的loader对象
 for (const extension in loaders) {
 const loader = loaders[extension]//提取每一种文件的loader
 output.push({
 test: new RegExp(’\.’ + extension + ‘$’),
 use: loader
 })
 }return output
 }exports.createNotifierCallback = () => {
 const notifier = require(‘node-notifier’)//导入模块,用于node.js模块发送跨平台系统通知return (severity, errors) => {
 if (severity !== ‘error’) returnconst 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')//发生错误时的通知图标
})}
 }vue-loader.config.js

vue2 全局安装yarn vue-cli全局安装_配置文件_10


webpack.base.conf.js:配置vue开发环境的webpack配置,处理各种文件(js啊、css啊、html啊…)
 ‘use strict’//js严格模式执行
 const path = require(‘path’)//引入node.js路径模块 const utils = require(’./utils’)//引入utils工具模块,主要处理css-loader和vue-style-loader
 const config = require(’…/config’)//引入config文件夹下的index.js文件
 const vueLoaderConfig = require(’./vue-loader.conf’)//引入vue-loader工具模块
function resolve (dir) {//返回当前目录的平行目录的路径
 return path.join(__dirname, ‘…’, dir)
 }module.exports = {
 context: path.resolve(__dirname, ‘…/’),
 entry: {//输入
 app: ‘./src/main.js’//入口文件为main.js },
 output: {//输出
 path: config.build.assetsRoot,//打包后文件输出路径,看看自己的index.js中build配置中的assetsRoot是啥目录
 filename: ‘[name].js’,//输出文件名称默认使用原名
 publicPath: process.env.NODE_ENV === ‘production’//真正的文件引用路径,请看自己的index.js中build配置中写的啥
 ? config.build.assetsPublicPath
 : config.dev.assetsPublicPath
 },
 resolve: {//决定要做的事情
 extensions: [’.js’, ‘.vue’, ‘.json’],//省略扩展名,也就是说当使用.js .vue .json文件导入可以省略后缀名
 alias: {
 'vue符号指精确匹配,路径和文件名要详细
 ‘@’: resolve(‘src’),//resolve('src‘)//resolve(‘src’)指的是项目根目录中的src文件夹目录,导入文件的时候路径可以这样简写 import somejs from "@/some.js"就可以导入指定文件
 }
 },
 //用来解析不同模块
 module: {
 rules: [
 {
 test: /.vueKaTeX parse error: Expected 'EOF', got '\/' at position 78: …结尾处哦,否则要使用/就得转义\̲/̲;\.表示.,此处的\将.标记…是正则表达式的结束?这个我不知道…)
 loader: ‘vue-loader’,//对vue文件使用vue-loader,该loader是vue单文件组件的实现核心,解析.vue文件
 options: vueLoaderConfig//将vueLoaderConfig当做参数传递给vue-loader,解析css相关文件
 },
 {
 test: /.jsKaTeX parse error: Expected 'EOF', got '}' at position 225: …用该loader }̲, { …/,//这些格式结尾的图片文件
 loader: ‘url-loader’,//图片文件使用url-loader插件,将图片转为base64格式字符串
 options: {
 limit: 10000,//10000个字节以下的文件才用来转为dataUrl
 name: utils.assetsPath(‘img/[name].[hash:7].[ext]’)//超过10000字节的图片,就按照制定规则设置生成的图片名称,可以看到用了7位hash码来标记,.ext文件是一种索引式文件系统
 }
 },
 {
 test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.)?KaTeX parse error: Expected 'EOF', got '}' at position 237: … } }̲, { …/,//处理字体相关
 loader: ‘url-loader’,
 options: {
 limit: 10000,
 name: utils.assetsPath(‘fonts/[name].[hash:7].[ext]’)
 }
 },
 /添加sass开始/
 {
 test:/.(woff2?|eot|ttf|otf)(?.)?$/,//这个可以在vue组件中用sass scss等…
 loaders:[‘style’,‘css’,‘sass’],
 }
 /添加sass结束/
 ]
 },
 node: {//一个对象,每个属性都是node.js全局变量或模块的名称,value为empty表示提供空对象
 // prevent webpack from injecting useless setImmediate polyfill because Vue
 // source contains it (although only uses it if it’s native).
 setImmediate: false,//false表示什么都不提供,话说参数setImmediate表示异步递归???需要查阅node文档了
 // prevent webpack from injecting mocks to Node native modules
 // that does not make sense for the client
 dgram: ‘empty’,
 fs: ‘empty’,
 net: ‘empty’,
 tls: ‘empty’,
 child_process: ‘empty’
 }
 }webpack.dev.conf.js 开发环境模式配置文件:
‘use strict’//js按照严格模式执行
 const utils = require(’./utils’)//导入utils.js const webpack = require(‘webpack’)//使用webpack来使用webpack内置插件
 const config = require(’…/config’)//config文件夹下index.js文件
 const merge = require(‘webpack-merge’)//引入webpack-merge插件用来合并webpack配置对象,也就是说可以把webpack配置文件拆分成几个小的模块,然后合并
 const path = require(‘path’)
 const baseWebpackConfig = require(’./webpack.base.conf’)//导入webpack基本配置
 const CopyWebpackPlugin = require(‘copy-webpack-plugin’)
 const HtmlWebpackPlugin = require(‘html-webpack-plugin’)//生成html文件
 const FriendlyErrorsPlugin = require(‘friendly-errors-webpack-plugin’)
 const portfinder = require(‘portfinder’)//获取portconst HOST = process.env.HOST//process.env属性返回一个对象,包含了当前shell的所有环境变量。这句取其中的host文件?
 const PORT = process.env.PORT && Number(process.env.PORT)//获取所有环境变量下的端口?//合并模块,第一个参数是webpack基本配置文件webpack.base.conf.js中的配置
 const devWebpackConfig = merge(baseWebpackConfig, {
 module: {
 rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })//创建模块时匹配请求的规则数组,这里调用了utils中的配置模板styleLoaders
 },
 // cheap-module-eval-source-map is faster for development
 devtool: config.dev.devtool,//debtool是开发工具选项,用来指定如何生成sourcemap文件,cheap-module-eval-source-map此款soucemap文件性价比最高// these devServer options should be customized in /config/index.js
 devServer: {//webpack服务器配置
 clientLogLevel: ‘warning’,//使用内联模式时,在开发工具的控制台将显示消息,可取的值有none error warning info
 historyApiFallback: {//当使用h5 history api时,任意的404响应都可能需要被替代为index.html,通过historyApiFallback:true控制;通过传入一个对象,比如使用rewrites这个选项进一步控制
 rewrites: [
 { from: /./, to: path.posix.join(config.dev.assetsPublicPath, ‘index.html’) },
 ],
 },
 hot: true,//是否启用webpack的模块热替换特性。这个功能主要是用于开发过程中,对生产环境无帮助。效果上就是界面无刷新更新。
 contentBase: false, // since we use CopyWebpackPlugin.这里禁用了该功能。本来是告诉服务器从哪里提供内容,一半是本地静态资源。
 compress: true,//一切服务是否都启用gzip压缩
 host: HOST || config.dev.host,//指定一个host,默认是localhost。如果有全局host就用全局,否则就用index.js中的设置。
 port: PORT || config.dev.port,//指定端口
 open: config.dev.autoOpenBrowser,//是否在浏览器开启本dev server
 overlay: config.dev.errorOverlay//当有编译器错误时,是否在浏览器中显示全屏覆盖。
 ? { warnings: false, errors: true }
 : false,
 publicPath: config.dev.assetsPublicPath,//此路径下的打包文件可在浏览器中访问
 proxy: config.dev.proxyTable,//如果你有单独的后端开发服务器api,并且希望在同域名下发送api请求,那么代理某些URL会很有用。
 quiet: true, // necessary for FriendlyErrorsPlugin 启用 quiet 后,除了初始启动信息之外的任何内容都不会被打印到控制台。这也意味着来自 webpack 的错误或警告在控制台不可见。
 watchOptions: {//webpack 使用文件系统(file system)获取文件改动的通知。在某些情况下,不会正常工作。例如,当使用 Network File System (NFS) 时。Vagrant 也有很多问题。在这些情况下使用轮询


poll: config.dev.poll,//是否使用轮询
 }
 },
 plugins: [
 new webpack.DefinePlugin({
 ‘process.env’: require(’…/config/dev.env’)
 }),
 new webpack.HotModuleReplacementPlugin(),
 new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
 new webpack.NoEmitOnErrorsPlugin(),
 // https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({//模块HtmlWebpackPlugin
 filename: ‘index.html’,//生成的文件的名称
 template: ‘index.html’,//可以指定模块html文件
 inject: true//在文档上没查到这个选项 不知道干嘛的。。。
 }),
 // copy custom static assets
 new CopyWebpackPlugin([//模块CopyWebpackPlugin 将单个文件或整个文件复制到构建目录
 {
 from: path.resolve(__dirname, ‘…/static’),//将static文件夹及其子文件复制到
 to: config.dev.assetsSubDirectory,
 ignore: [’.’]//这个没翻译好,百度翻译看不懂,请自己查文档。。。
 }
 ])
 ]
 })
 //webpack将运行由配置文件导出的函数,并且等待promise返回,便于需要异步地加载所需的配置变量。
 module.exports = new Promise((resolve, reject) => {
 portfinder.basePort = process.env.PORT || config.dev.port
 portfinder.getPort((err, port) => {
 if (err) {
 reject(err)
 } else {
 // publish the new Port, necessary for e2e tests
 process.env.PORT = port
 // add port to devServer config
 devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
  devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({//出错友好处理插件
    compilationSuccessInfo: {//build成功的话会执行者块
      messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
    },
    onErrors: config.dev.notifyOnErrors//如果出错就执行这块,其实是utils里面配置好的提示信息
    ? utils.createNotifierCallback()
    : undefined
  }))

  resolve(devWebpackConfig)
}
})
 })webpack.prod.conf.js 生产环境配置文件:
‘use strict’//js严格模式执行
 const path = require(‘path’)//这个模块是发布到NPM注册中心的NodeJS“路径”模块的精确副本
 const utils = require(’./utils’)//utils.js文件 const webpack = require(‘webpack’)//webpack模块
 const config = require(’…/config’)//config文件夹下的index.js 是不是很神奇?
 const merge = require(‘webpack-merge’)//合并数组、对象为一个新的对象的模块
 const baseWebpackConfig = require(’./webpack.base.conf’)//webpack.base.conf.js
 const CopyWebpackPlugin = require(‘copy-webpack-plugin’)//拷贝文件和文件夹模块
 const HtmlWebpackPlugin = require(‘html-webpack-plugin’)//为html文件中引入的外部资源(比如script/link等)动态添加每次compile后的hash,保证文件名不重复的好处是防止引用缓存文件导致修改暂未生效;可生成创建html入口文件
 const ExtractTextPlugin = require(‘extract-text-webpack-plugin’)//抽离css样式,防止将样式打包到js中引起加载错乱
 const OptimizeCSSPlugin = require(‘optimize-css-assets-webpack-plugin’)//压缩css插件
 const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’)//压缩js代码。const env = require(’…/config/prod.env’)//设置为生产环境production
 //merge方法合并模块对象,在这个文件里是将基础配置webpack.base.conf.js和生产环境配置合并
 const webpackConfig = merge(baseWebpackConfig, {
 module: {//模块配置
 rules: utils.styleLoaders({//原版注释Generate loaders for standalone style files (outside of .vue)生成独立的样式文件装载机
 sourceMap: config.build.productionSourceMap,//设置sourceMap
 extract: true,//
 usePostCSS: true
 })
 },
 devtool: config.build.productionSourceMap ? config.build.devtool : false,//指定是否使用sourceMap
 output: {//指定输出
 path: config.build.assetsRoot,
 filename: utils.assetsPath(‘js/[name].[chunkhash].js’),//编译输出的js文件存放在js文件夹下,命名规则添加hash计算
 /**
 * 打包require.ensure方法中引入的模块,如果该方法中没有引入任何模块则不会生成任何chunk块文件
 *
 * 比如在main.js文件中,require.ensure([],function(require){alert(11);}),这样不会打包块文件
 * 只有这样才会打包生成块文件require.ensure([],function(require){alert(11);require(’./greeter’)})
 * 或者这样require.ensure([’./greeter’],function(require){alert(11);})
 * chunk的hash值只有在require.ensure中引入的模块发生变化,hash值才会改变
 * 注意:对于不是在ensure方法中引入的模块,此属性不会生效,只能用CommonsChunkPlugin插件来提取
 */
 chunkFilename: utils.assetsPath(‘js/[id].[chunkhash].js’)
 },
 plugins: [
 // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({
 ‘process.env’: env
 }),
 new UglifyJsPlugin({//压缩js代码的插件 具体可以去npm查一下这个插件怎么用以及能设置哪些参数
 uglifyOptions: {
 compress: {
 warnings: false
 }
 },
 sourceMap: config.build.productionSourceMap,//是否生成sourceMap
 parallel: true
 }),
 // extract css into its own file
 new ExtractTextPlugin({
 filename: utils.assetsPath(‘css/[name].[contenthash].css’),
 // Setting the following option to false will not extract CSS from codesplit chunks.
 // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
 // It’s currently set to true because we are seeing that sourcemaps are included in the codesplit bundle as well when it’s false,
 // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 allChunks: true,
 }),
 // Compress extracted CSS. We are using this plugin so that possible
 // duplicated CSS from different components can be deduped.
 new OptimizeCSSPlugin({
 cssProcessorOptions: config.build.productionSourceMap
 ? { safe: true, map: { inline: false } }
 : { safe: true }
 }),
 // generate dist index.html with correct asset hash for caching.
 // you can customize output by editing /index.html
 // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({
 filename: config.build.index,
 template: ‘index.html’,
 inject: true,
 minify: {
 removeComments: true,
 collapseWhitespace: true,
 removeAttributeQuotes: true
 // more options:
 // https://github.com/kangax/html-minifier#options-quick-reference },
 // necessary to consistently work with multiple chunks via CommonsChunkPlugin
 chunksSortMode: ‘dependency’
 }),
 // keep module.id stable when vendor modules does not change
 new webpack.HashedModuleIdsPlugin(),
 // enable scope hoisting
 new webpack.optimize.ModuleConcatenationPlugin(),
 // split vendor js into its own file
 new webpack.optimize.CommonsChunkPlugin({
 name: ‘vendor’,
 minChunks (module) {
 // any required modules inside node_modules are extracted to vendor
 return (
 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
 new webpack.optimize.CommonsChunkPlugin({
 name: ‘manifest’,
 minChunks: Infinity
 }),
 // This instance extracts shared chunks from code splitted chunks and bundles them
 // in a separate chunk, similar to the vendor chunk
 // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk new webpack.optimize.CommonsChunkPlugin({
 name: ‘app’,
 async: ‘vendor-async’,
 children: true,
 minChunks: 3
 }),
// copy custom static assets
new CopyWebpackPlugin([
  {
    from: path.resolve(__dirname, '../static'),
    to: config.build.assetsSubDirectory,
    ignore: ['.*']
  }
])
]//添加插件,是webpack功能更丰富
 })
 //是否允许压缩?
 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’).BundleAnalyzerPlugin
 webpackConfig.plugins.push(new BundleAnalyzerPlugin())
 }module.exports = webpackConfig

关于开发环境和生产环境的区别,引用一段官网长的解释。

开发环境(development)和生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server。而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。

虽然,以上我们将生产环境和开发环境做了略微区分,但是,请注意,我们还是会遵循不重复原则(Don’t repeat yourself - DRY),保留一个“通用”配置。为了将这些配置合并在一起,我们将使用一个名为 webpack-merge 的工具。

webpack单元测试配置:
// This is the webpack config used for unit tests.
var utils = require(’./utils’)//utils.js文件导入 var webpack = require(‘webpack’)//webpack模块导入
 var merge = require(‘webpack-merge’)//合并模块插件
 var baseConfig = require(’./webpack.base.conf’)//导入基础配置webpack.base.conf.jsvar webpackConfig = merge(baseConfig, {
 // use inline sourcemap for karma-sourcemap-loader
 module: {
 rules: utils.styleLoaders()
 },
 devtool: ‘#inline-source-map’,
 plugins: [
 new webpack.DefinePlugin({
 ‘process.env’: require(’…/config/test.env’)//指定环境为测试环境 test.env中设置了NODE_ENV=‘testing’
 })
 ]
 })// no need for app entry during tests
 delete webpackConfig.entrymodule.exports = webpackConfig
package.json文件配置及其含义,这个是vue-cli自动生成的文件,先贴一张代码及其含义
 {
 “name”: “secondproject”,//模块名称
 “version”: “1.0.0”,//模块版本
 “description”: “A Vue.js project”,//对模块的描述
 “author”: “datura”,//作者是谁
 “private”: true,//如果值为true,npm将拒绝发布它
 “scripts”: {//值是一个对象,里面指定了项目的生命周期各个环节需要执行的命令
 “dev”: “node build/dev-server.js”,//这个就是在命令行执行npm run dev,其实是运行dev-server.js文件
 “build”: “node build/build.js”,//build命令(有一个钩子的概念:比如这个build有prebuild和postbuild
 “unit”: “cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run”,//babel是一个编译器,可以把ES6编译成ES5.,这句先是设置编译环境为test环境下;karma是一个运行时,它产生一个web服务环境来运行项目代码,并执行测试。…
 “e2e”: “node test/e2e/runner.js”,//e2e模拟用户行为的测试,端到端测试
 “test”: “npm run unit && npm run e2e”//执行单元测试和e2e测试
 },//关于npm钩子:通常程序只能处理来自内部的消息,如果希望对外部发来的消息也能拦截处理,就需要用到Hook技术。比如想在run build之前自动执行点任务,可以将其写在run prebuild标签里;postbuild在build之后自动执行
 “dependencies”: {//配置模块依赖的模块列表,key是模块名称,value是版本范围,版本范围是一个字符,可被一个或多个空格分割。
 “router”: “^1.3.0”,//路由版本
 “vue”: “^2.2.1”,//vue版本
 “vue-resource”: “^1.2.1”,//一个插件,通过xmlHttpRequest或jsonp发起请求并处理响应。
 “vue-router”: “^2.3.0”//
 },
 “devDependencies”: {//这里写的依赖是用于开发环境的,不发布到生产环境。
 “autoprefixer”: “^6.7.2”,
 “babel-core”: “^6.22.1”,
 “babel-loader”: “^6.2.10”,
 “babel-plugin-transform-runtime”: “^6.22.0”,
 “babel-preset-latest”: “^6.22.0”,
 “babel-preset-stage-2”: “^6.22.0”,
 “babel-register”: “^6.22.0”,
 “chalk”: “^1.1.3”,
 “connect-history-api-fallback”: “^1.3.0”,
 “copy-webpack-plugin”: “^4.0.1”,
 “css-loader”: “^0.26.1”,
 “eventsource-polyfill”: “^0.9.6”,
 “express”: “^4.14.1”,
 “extract-text-webpack-plugin”: “^2.0.0”,
 “file-loader”: “^0.10.0”,
 “friendly-errors-webpack-plugin”: “^1.1.3”,
 “function-bind”: “^1.1.0”,
 “html-webpack-plugin”: “^2.28.0”,
 “http-proxy-middleware”: “^0.17.3”,
 “webpack-bundle-analyzer”: “^2.2.1”,
 “cross-env”: “^3.1.4”,
 “karma”: “^1.4.1”,
 “karma-coverage”: “^1.1.1”,
 “karma-mocha”: “^1.3.0”,
 “karma-phantomjs-launcher”: “^1.0.2”,
 “karma-sinon-chai”: “^1.2.4”,
 “karma-sourcemap-loader”: “^0.3.7”,
 “karma-spec-reporter”: “0.0.26”,
 “karma-webpack”: “^2.0.2”,
 “lolex”: “^1.5.2”,
 “mocha”: “^3.2.0”,
 “chai”: “^3.5.0”,
 “sinon”: “^1.17.7”,
 “sinon-chai”: “^2.8.0”,
 “inject-loader”: “^2.0.1”,
 “babel-plugin-istanbul”: “^3.1.2”,
 “phantomjs-prebuilt”: “^2.1.14”,
 “chromedriver”: “^2.27.2”,
 “cross-spawn”: “^5.0.1”,
 “nightwatch”: “^0.9.12”,
 “selenium-server”: “^3.0.1”,
 “semver”: “^5.3.0”,
 “opn”: “^4.0.2”,
 “optimize-css-assets-webpack-plugin”: “^1.3.0”,
 “ora”: “^1.1.0”,
 “rimraf”: “^2.6.0”,
 “url-loader”: “^0.5.7”,
 “vue-loader”: “^11.0.0”,
 “vue-style-loader”: “^2.0.0”,
 “vue-template-compiler”: “^2.2.1”,
 “webpack”: “^2.2.1”,
 “webpack-dev-middleware”: “^1.10.0”,
 “webpack-hot-middleware”: “^2.16.1”,
 “webpack-merge”: “^2.6.1”
 },
 “engines”: {//指定项目运行的node或者npm版本范围,有点像安卓的指定开发level哦
 “node”: “>= 4.0.0”,
 “npm”: “>= 3.0.0”
 },
 “browserlist”: [//在不同的前端工具之间共享目标浏览器的库,确定哪些支持哪些版本的浏览器
 “> 1%”,//全球有超1%的人使用的浏览器
 “last 2 versions”,//根据CanIUse.com追踪的最后两个版本的所有浏览器 “not ie <= 8”//排除先前查询选择的浏览器 天啦噜 英语不好是硬伤 不知怎么翻译好理解
 ]
 }

好了,脚手架目录中重要的文件基本都介绍了,但还有一个不太注意到的文件没有解释,这里也说明一下。

config文件夹下的index.js,作用是不同开发环境下的参数配置(可选项很多,生产环境、开发环境、测试环境):

vue2 全局安装yarn vue-cli全局安装_css_11

condig文件夹中的其他几个文件,这几个文件主要是暴露接口(其他文件会引用这些暴露出来的变量等):

vue2 全局安装yarn vue-cli全局安装_css_12


vue2 全局安装yarn vue-cli全局安装_json_13


vue2 全局安装yarn vue-cli全局安装_css_14


.babelrc文件:由于浏览器的兼容问题,很多js新方法都不能用,babel因此而生。它可以将这些新方法编译成兼容的代码,尽量多的适应主流浏览器。

想要深入了解可以去巴别官网查看详细配置和解释。官网地址: https://babeljs.io/docs/plugins/

vue2 全局安装yarn vue-cli全局安装_vue-cli目录详解_15

.editorconfig文件配置:用来规范开发中缩进风格的统一

vue2 全局安装yarn vue-cli全局安装_vue2 全局安装yarn_16


editorConfig相关参数:

匹配除/之外的任意字符串

** 匹配任意字符串
? 匹配任意单个字符
[name] 匹配name中的任意一个单一字符
[!name] 匹配不存在name中的任意一个单一字符
{s1,s2,s3} 匹配给定的字符串中的任意一个(用逗号分隔)
{num1…num2}  匹配num1到num2之间的任意一个整数, 这里的num1和num2可以为正整数也可以为负整数

属性
indent_style 设置缩进风格(tab是硬缩进,space为软缩进)
indent_size 用一个整数定义的列数来设置缩进的宽度,如果indent_style为tab,则此属性默认为tab_width
tab_width 用一个整数来设置tab缩进的列数。默认是indent_size
end_of_line 设置换行符,值为lf、cr和crlf
charset 设置编码,值为latin1、utf-8、utf-8-bom、utf-16be和utf-16le,不建议使用utf-8-bom
trim_trailing_whitespace 设为true表示会去除换行行首的任意空白字符。
insert_final_newline 设为true表示使文件以一个空白行结尾
root    表示是最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件

.gitignore文件:用来配置不需要加在版本管理中的文件,忽略git不必要提交文件。

vue2 全局安装yarn vue-cli全局安装_配置文件_17


忽略文件的原则是:

忽略操作系统自动生成的文件,比如缩略图等;
忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
下面我们看看常用的规则:
1)/mtk/ 过滤整个文件夹
2)*.zip 过滤所有.zip文件
3)/mtk/do.c 过滤某个具体文件
复制代码
这里很有意思~

需要注意的是,gitignore还可以指定要将哪些文件添加到版本管理中:
1)!*.zip
2)!/mtk/one.txt

唯一的区别就是规则开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。
为什么要有两种规则呢?想象一个场景:假如我们只需要管理/mtk/目录中的one.txt文件,这个目录中的其他文件都不需要管理,那么我们就需要使用:
1)/mtk/
2)!/mtk/one.txt

说明:如果你不慎在创建.gitignore文件之前就push了项目,那么即使你在.gitignore文件中写入新的过滤规则,这些规则也不会起作用,Git仍然会对所有文件进行版本管理。因此一定要养成在项目开始就创建.gitignore文件的习惯,否则一旦push,处理起来会非常麻烦。

.postcssrc.js文件:postCss提供一个解析器,将css解析成抽象语法树。

vue2 全局安装yarn vue-cli全局安装_vue2 全局安装yarn_18

如果Sass等预编译器是新定义了一种模板语言,然后将其转化为css的话,PostCSS则是更纯粹地对css本身做转换。

回想一下你是如何学习使用css预编译器的:了解到有这样一种可以转化为css的语言,它有很多特性,变量、嵌套、继承等等,每一种特性都通过一定语法实现。大概就像是递给你一个已经封装好的工具箱(量产型?),你可以在里面找有用的东西。

那PostCSS是怎样呢?PostCSS就像只递给你一个盒子,但告诉你你可以从旁边的陈列柜取走自己想要的工具放进盒子打包带走。如果你觉得陈列柜里的不够好,PostCSS还可以帮你打造你