转载地址:http://blog.csdn.net/hongchh/article/details/55113751css
本文主要分析开发(dev)和构建(build)两个过程涉及到的文件,故下面文件结构仅列出相应的内容。html
1 ├─build 2 │ ├─build.js 3 │ ├─check-versions.js 4 │ ├─dev-client.js 5 │ ├─dev-server.js 6 │ ├─utils.js 7 │ ├─vue-loader.conf.js 8 │ ├─webpack.base.conf.js 9 │ ├─webpack.dev.conf.js 10 │ ├─webpack.prod.conf.js 11 │ └─webpack.test.conf.js 12 ├─config 13 │ ├─dev.env.js 14 │ ├─index.js 15 │ ├─prod.env.js 16 │ └─test.env.js 17 ├─... 18 └─package.json
首先看package.json里面的scripts字段,前端
1 "scripts": { 2 "dev": "node build/dev-server.js", 3 "start": "node build/dev-server.js", 4 "build": "node build/build.js", 5 "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", 6 "e2e": "node test/e2e/runner.js", 7 "test": "npm run unit && npm run e2e", 8 "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs" 9 },
运行”npm run dev”的时候执行的是build/dev-server.js文件,运行”npm run build”的时候执行的是build/build.js文件,咱们能够从这两个文件开始进行代码阅读分析。vue
首先来看执行”npm run dev”时候最早执行的build/dev-server.js文件。该文件主要完成下面几件事情:node
说明: express服务器提供静态文件服务,不过它还使用了http-proxy-middleware,一个http请求代理的中间件。前端开发过程当中须要使用到后台的API的话,能够经过配置proxyTable来将相应的后台请求代理到专用的API服务器。webpack
详情请看代码注释:git
1 // 检查NodeJS和npm的版本
2 require('./check-versions')() 3
4 // 获取基本配置
5 var config = require('../config') 6 // 若是Node的环境变量中没有设置当前的环境(NODE_ENV),则使用config中的dev环境配置做为当前的环境
7 if (!process.env.NODE_ENV) { 8 process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 9 } 10
11 // opn是一个能够调用默认软件打开网址、图片、文件等内容的插件 12 // 这里用它来调用默认浏览器打开dev-server监听的端口,例如:localhost:8080
13 var opn = require('opn') 14 var path = require('path') 15 var express = require('express') 16 var webpack = require('webpack') 17 // http-proxy-middleware是一个express中间件,用于将http请求代理到其余服务器 18 // 例:localhost:8080/api/xxx --> localhost:3000/api/xxx 19 // 这里使用该插件能够将前端开发中涉及到的请求代理到提供服务的后台服务器上,方便与服务器对接
20 var proxyMiddleware = require('http-proxy-middleware') 21 // 开发环境下的webpack配置
22 var webpackConfig = require('./webpack.dev.conf') 23
24 // dev-server 监听的端口,若是没有在命令行传入端口号,则使用config.dev.port设置的端口,例如8080
25 var port = process.env.PORT || config.dev.port 26 // 用于判断是否要自动打开浏览器的布尔变量,当配置文件中没有设置自动打开浏览器的时候其值为 false
27 var autoOpenBrowser = !!config.dev.autoOpenBrowser 28 // HTTP代理表,指定规则,将某些API请求代理到相应的服务器
29 var proxyTable = config.dev.proxyTable 30 // 建立express服务器
31 var app = express() 32 // webpack根据配置开始编译打包源码并返回compiler对象
33 var compiler = webpack(webpackConfig) 34 // webpack-dev-middleware将webpack编译打包后获得的产品文件存放在内存中而没有写进磁盘 35 // 将这个中间件挂到express上使用以后便可提供这些编译后的产品文件服务
36 var devMiddleware = require('webpack-dev-middleware')(compiler, { 37 publicPath: webpackConfig.output.publicPath, // 设置访问路径为webpack配置中的output里面所对应的路径
38 quiet: true // 设置为true,使其不要在控制台输出日志
39 }) 40 // webpack-hot-middleware,用于实现热重载功能的中间件
41 var hotMiddleware = require('webpack-hot-middleware')(compiler, { 42 log: false, // 关闭控制台的日志输出
43 heartbeat: 2000 // 发送心跳包的频率
44 }) 45 // webpack(从新)编译打包完成后并将js、css等文件inject到html文件以后,经过热重载中间件强制页面刷新
46 compiler.plugin('compilation', function (compilation) { 47 compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 48 hotMiddleware.publish({ action: 'reload' }) 49 cb() 50 }) 51 }) 52
53 // 根据 proxyTable 中的代理请求配置来设置express服务器的http代理规则
54 Object.keys(proxyTable).forEach(function (context) { 55 var options = proxyTable[context] 56 // 格式化options,例如将'www.example.com'变成{ target: 'www.example.com' }
57 if (typeof options === 'string') { 58 options = { target: options } 59 } 60 app.use(proxyMiddleware(options.filter || context, options)) 61 }) 62
63 // handle fallback for HTML5 history API 64 // 重定向不存在的URL,用于支持SPA(单页应用) 65 // 例如使用vue-router并开启了history模式
66 app.use(require('connect-history-api-fallback')()) 67
68 // serve webpack bundle output 69 // 挂载webpack-dev-middleware中间件,提供webpack编译打包后的产品文件服务
70 app.use(devMiddleware) 71
72 // enable hot-reload and state-preserving 73 // compilation error display 74 // 挂载热重载中间件
75 app.use(hotMiddleware) 76
77 // serve pure static assets 78 // 提供static文件夹上的静态文件服务
79 var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 80 app.use(staticPath, express.static('./static')) 81
82 // 访问连接
83 var uri = 'http://localhost:' + port 84
85 // 建立promise,在应用服务启动以后resolve 86 // 便于外部文件require了这个dev-server以后的代码编写
87 var _resolve 88 var readyPromise = new Promise(resolve => { 89 _resolve = resolve 90 }) 91
92 console.log('> Starting dev server...') 93 // webpack-dev-middleware等待webpack完成全部编译打包以后输出提示语到控制台,代表服务正式启动 94 // 服务正式启动才自动打开浏览器进入页面
95 devMiddleware.waitUntilValid(() => { 96 console.log('> Listening at ' + uri + '\n') 97 // when env is testing, don't need open it
98 if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 99 opn(uri) 100 } 101 _resolve() 102 }) 103
104 // 启动express服务器并监听相应的端口
105 var server = app.listen(port) 106
107 // 暴露本模块的功能给外部使用,例以下面这种用法 108 // var devServer = require('./build/dev-server') 109 // devServer.ready.then(() => {...}) 110 // if (...) { devServer.close() }
111 module.exports = { 112 ready: readyPromise, 113 close: () => { 114 server.close() 115 } 116 }
从代码中看到,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。es6
webpack.base.conf.js主要完成了下面这些事情:github
说明: 这个配置里面只配置了.js、.vue、图片、字体等几类文件的处理规则,若是须要处理其余文件能够在module.rules里面另行配置。web
具体请看代码注释:
1 var path = require('path') 2 var fs = require('fs') 3 var utils = require('./utils') 4 var config = require('../config') 5 var vueLoaderConfig = require('./vue-loader.conf') 6 7 // 获取绝对路径 8 function resolve (dir) { 9 return path.join(__dirname, '..', dir) 10 } 11 12 module.exports = { 13 // webpack入口文件 14 entry: { 15 app: './src/main.js' 16 }, 17 // webpack输出路径和命名规则 18 output: { 19 // webpack输出的目标文件夹路径(例如:/dist) 20 path: config.build.assetsRoot, 21 // webpack输出bundle文件命名格式 22 filename: '[name].js', 23 // webpack编译输出的发布路径(例如'//cdn.xxx.com/app/') 24 publicPath: process.env.NODE_ENV === 'production' 25 ? config.build.assetsPublicPath 26 : config.dev.assetsPublicPath 27 }, 28 // 模块resolve的规则 29 resolve: { 30 extensions: ['.js', '.vue', '.json'], 31 // 别名,方便引用模块,例若有了别名以后, 32 // import Vue from 'vue/dist/vue.common.js'能够写成 import Vue from 'vue' 33 alias: { 34 'vue$': 'vue/dist/vue.esm.js', 35 '@': resolve('src'), 36 }, 37 symlinks: false 38 }, 39 // 不一样类型模块的处理规则 40 module: { 41 rules: [ 42 {// 对src和test文件夹下的.js和.vue文件使用eslint-loader进行代码规范检查 43 test: /\.(js|vue)$/, 44 loader: 'eslint-loader', 45 enforce: 'pre', 46 include: [resolve('src'), resolve('test')], 47 options: { 48 formatter: require('eslint-friendly-formatter') 49 } 50 }, 51 {// 对全部.vue文件使用vue-loader进行编译 52 test: /\.vue$/, 53 loader: 'vue-loader', 54 options: vueLoaderConfig 55 }, 56 {// 对src和test文件夹下的.js文件使用babel-loader将es6+的代码转成es5 57 test: /\.js$/, 58 loader: 'babel-loader', 59 include: [resolve('src'), resolve('test')] 60 }, 61 {// 对图片资源文件使用url-loader 62 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 63 loader: 'url-loader', 64 options: { 65 // 小于10K的图片转成base64编码的dataURL字符串写到代码中 66 limit: 10000, 67 // 其余的图片转移到静态资源文件夹 68 name: utils.assetsPath('img/[name].[hash:7].[ext]') 69 } 70 }, 71 {// 对多媒体资源文件使用url-loader 72 test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 73 loader: 'url-loader', 74 options: { 75 // 小于10K的资源转成base64编码的dataURL字符串写到代码中 76 limit: 10000, 77 // 其余的资源转移到静态资源文件夹 78 name: utils.assetsPath('media/[name].[hash:7].[ext]') 79 } 80 }, 81 {// 对字体资源文件使用url-loader 82 test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 83 loader: 'url-loader', 84 options: { 85 // 小于10K的资源转成base64编码的dataURL字符串写到代码中 86 limit: 10000, 87 // 其余的资源转移到静态资源文件夹 88 name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 89 } 90 } 91 ] 92 } 93 }
utils提供工具函数,包括生成处理各类样式语言的loader,获取资源文件存放路径的工具函数。
1. 计算资源文件存放路径
2. 生成cssLoaders用于加载.vue文件中的样式
3. 生成styleLoaders用于加载不在.vue文件中的单独存在的样式文件
1 var path = require('path') 2 var config = require('../config') 3 // extract-text-webpack-plugin能够提取bundle中的特定文本,将提取后的文本单独存放到另外的文件 4 // 这里用来提取css样式 5 var ExtractTextPlugin = require('extract-text-webpack-plugin') 6 7 // 资源文件的存放路径 8 exports.assetsPath = function (_path) { 9 var assetsSubDirectory = process.env.NODE_ENV === 'production' 10 ? config.build.assetsSubDirectory 11 : config.dev.assetsSubDirectory 12 return path.posix.join(assetsSubDirectory, _path) 13 } 14 15 // 生成css、sass、scss等各类用来编写样式的语言所对应的loader配置 16 exports.cssLoaders = function (options) { 17 options = options || {} 18 // css-loader配置 19 var cssLoader = { 20 loader: 'css-loader', 21 options: { 22 // 是否最小化 23 minimize: process.env.NODE_ENV === 'production', 24 // 是否使用source-map 25 sourceMap: options.sourceMap 26 } 27 } 28 29 // generate loader string to be used with extract text plugin 30 // 生成各类loader配置,而且配置了extract-text-pulgin 31 function generateLoaders (loader, loaderOptions) { 32 // 默认是css-loader 33 var loaders = [cssLoader] 34 // 若是非css,则增长一个处理预编译语言的loader并设好相关配置属性 35 // 例如generateLoaders('less'),这里就会push一个less-loader 36 // less-loader先将less编译成css,而后再由css-loader去处理css 37 // 其余sass、scss等语言也是同样的过程 38 if (loader) { 39 loaders.push({ 40 loader: loader + '-loader', 41 options: Object.assign({}, loaderOptions, { 42 sourceMap: options.sourceMap 43 }) 44 }) 45 } 46 47 // Extract CSS when that option is specified 48 // (which is the case during production build) 49 if (options.extract) { 50 // 配置extract-text-plugin提取样式 51 return ExtractTextPlugin.extract({ 52 use: loaders, 53 fallback: 'vue-style-loader' 54 }) 55 } else { 56 // 无需提取样式则简单使用vue-style-loader配合各类样式loader去处理<style>里面的样式 57 return ['vue-style-loader'].concat(loaders) 58 } 59 } 60 61 // https://vue-loader.vuejs.org/en/configurations/extract-css.html 62 // 获得各类不一样处理样式的语言所对应的loader 63 return { 64 css: generateLoaders(), 65 postcss: generateLoaders(), 66 less: generateLoaders('less'), 67 sass: generateLoaders('sass', { indentedSyntax: true }), 68 scss: generateLoaders('sass'), 69 stylus: generateLoaders('stylus'), 70 styl: generateLoaders('stylus') 71 } 72 } 73 74 // Generate loaders for standalone style files (outside of .vue) 75 // 生成处理单独的.css、.sass、.scss等样式文件的规则 76 exports.styleLoaders = function (options) { 77 var output = [] 78 var loaders = exports.cssLoaders(options) 79 for (var extension in loaders) { 80 var loader = loaders[extension] 81 output.push({ 82 test: new RegExp('\\.' + extension + '$'), 83 use: loader 84 }) 85 } 86 return output 87 }
vue-loader.conf的配置比较简单,详情请看代码注释:
1 var utils = require('./utils') 2 var config = require('../config') 3 var isProduction = process.env.NODE_ENV === 'production' 4 5 module.exports = { 6 // 处理.vue文件中的样式 7 loaders: utils.cssLoaders({ 8 // 是否打开source-map 9 sourceMap: isProduction 10 ? config.build.productionSourceMap 11 : config.dev.cssSourceMap, 12 // 是否提取样式到单独的文件 13 extract: isProduction 14 }), 15 transformToRequire: { 16 video: 'src', 17 source: 'src', 18 img: 'src', 19 image: 'xlink:href' 20 } 21 }
dev-client.js里面主要写了浏览器端代码,用于实现webpack的热更新。
1 /* eslint-disable */ 2 // 实现浏览器端的EventSource,用于跟服务器双向通讯 3 // webpack热重载客户端跟dev-server上的热重载插件之间须要进行双向通讯 4 // 服务端webpack从新编译后,会向客户端推送信息,告诉客户端进行更新 5 require('eventsource-polyfill') 6 // webpack热重载客户端 7 var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 8 9 // 客户端收到更新动做,执行页面刷新 10 hotClient.subscribe(function (event) { 11 if (event.action === 'reload') { 12 window.location.reload() 13 } 14 })
讲完了开发环境下的配置,下面开始来看构建环境下的配置。执行”npm run build”的时候首先执行的是build/build.js文件,build.js主要完成下面几件事:
说明: webpack编译以后会输出到配置里面指定的目标文件夹;删除目标文件夹以后再建立是为了去除旧的内容,以避免产生不可预测的影响。
详情请看代码注释:
1 // 检查NodeJS和npm的版本 2 require('./check-versions')() 3 4 process.env.NODE_ENV = 'production' 5 6 // ora,一个能够在终端显示spinner的插件 7 var ora = require('ora') 8 // rm,用于删除文件或文件夹的插件 9 var rm = require('rimraf') 10 var path = require('path') 11 // chalk,用于在控制台输出带颜色字体的插件 12 var chalk = require('chalk') 13 var webpack = require('webpack') 14 var config = require('../config') 15 var webpackConfig = require('./webpack.prod.conf') 16 17 var spinner = ora('building for production...') 18 spinner.start() // 开启loading动画 19 20 // 首先将整个dist文件夹以及里面的内容删除,以避免遗留旧的没用的文件 21 // 删除完成后才开始webpack构建打包 22 rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 23 if (err) throw err 24 // 执行webpack构建打包,完成以后在终端输出构建完成的相关信息或者输出报错信息并退出程序 25 webpack(webpackConfig, function (err, stats) { 26 spinner.stop() 27 if (err) throw err 28 process.stdout.write(stats.toString({ 29 colors: true, 30 modules: false, 31 children: false, 32 chunks: false, 33 chunkModules: false 34 }) + '\n\n') 35 36 if (stats.hasErrors()) { 37 console.log(chalk.red(' Build failed with errors.\n')) 38 process.exit(1) 39 } 40 41 console.log(chalk.cyan(' Build complete.\n')) 42 console.log(chalk.yellow( 43 ' Tip: built files are meant to be served over an HTTP server.\n' + 44 ' Opening index.html over file:// won\'t work.\n' 45 )) 46 }) 47 })
构建的时候用到的webpack配置来自webpack.prod.conf.js,该配置一样是在webpack.base.conf基础上的进一步完善。主要完成下面几件事情:
说明: webpack插件里面多了丑化压缩代码以及抽离css文件等插件。
1 var path = require('path') 2 var utils = require('./utils') 3 var webpack = require('webpack') 4 var config = require('../config') 5 var merge = require('webpack-merge') 6 var baseWebpackConfig = require('./webpack.base.conf') 7 // copy-webpack-plugin,用于将static中的静态文件复制到产品文件夹dist 8 var CopyWebpackPlugin = require('copy-webpack-plugin') 9 var HtmlWebpackPlugin = require('html-webpack-plugin') 10 var ExtractTextPlugin = require('extract-text-webpack-plugin') 11 // optimize-css-assets-webpack-plugin,用于优化和最小化css资源 12 var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 13 14 var env = config.build.env 15 16 var webpackConfig = merge(baseWebpackConfig, { 17 module: { 18 // 样式文件的处理规则,对css/sass/scss等不一样内容使用相应的styleLoaders 19 // 由utils配置出各类类型的预处理语言所须要使用的loader,例如sass须要使用sass-loader 20 rules: utils.styleLoaders({ 21 sourceMap: config.build.productionSourceMap, 22 extract: true 23 }) 24 }, 25 // 是否使用source-map 26 devtool: config.build.productionSourceMap ? '#source-map' : false, 27 // webpack输出路径和命名规则 28 output: { 29 path: config.build.assetsRoot, 30 filename: utils.assetsPath('js/[name].[chunkhash].js'), 31 chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 32 }, 33 // webpack插件 34 plugins: [ 35 // http://vuejs.github.io/vue-loader/en/workflow/production.html 36 new webpack.DefinePlugin({ 37 'process.env': env 38 }), 39 // 丑化压缩JS代码 40 new webpack.optimize.UglifyJsPlugin({ 41 compress: { 42 warnings: false 43 }, 44 sourceMap: true 45 }), 46 // extract css into its own file 47 // 将css提取到单独的文件 48 new ExtractTextPlugin({ 49 filename: utils.assetsPath('css/[name].[contenthash].css') 50 }), 51 // Compress extracted CSS. We are using this plugin so that possible 52 // duplicated CSS from different components can be deduped. 53 // 优化、最小化css代码,若是只简单使用extract-text-plugin可能会形成css重复 54 // 具体缘由能够看npm上面optimize-css-assets-webpack-plugin的介绍 55 new OptimizeCSSPlugin({ 56 cssProcessorOptions: { 57 safe: true 58 } 59 }), 60 // generate dist index.html with correct asset hash for caching. 61 // you can customize output by editing /index.html 62 // see https://github.com/ampedandwired/html-webpack-plugin 63 // 将产品文件的引用注入到index.html 64 new HtmlWebpackPlugin({ 65 filename: config.build.index, 66 template: 'index.html', 67 inject: true, 68 minify: { 69 // 删除index.html中的注释 70 removeComments: true, 71 // 删除index.html中的空格 72 collapseWhitespace: true, 73 // 删除各类html标签属性值的双引号 74 removeAttributeQuotes: true 75 // more options: 76 // https://github.com/kangax/html-minifier#options-quick-reference 77 }, 78 // necessary to consistently work with multiple chunks via CommonsChunkPlugin 79 // 注入依赖的时候按照依赖前后顺序进行注入,好比,须要先注入vendor.js,再注入app.js 80 chunksSortMode: 'dependency' 81 }), 82 // keep module.id stable when vender modules does not change 83 new webpack.HashedModuleIdsPlugin(), 84 // split vendor js into its own file 85 // 将全部从node_modules中引入的js提取到vendor.js,即抽取库文件 86 new webpack.optimize.CommonsChunkPlugin({ 87 name: 'vendor', 88 minChunks: function (module, count) { 89 // any required modules inside node_modules are extracted to vendor 90 return ( 91 module.resource && 92 /\.js$/.test(module.resource) && 93 module.resource.indexOf( 94 path.join(__dirname, '../node_modules') 95 ) === 0 96 ) 97 } 98 }), 99 // extract webpack runtime and module manifest to its own file in order to 100 // prevent vendor hash from being updated whenever app bundle is updated 101 // 从vendor中提取出manifest,缘由如上 102 new webpack.optimize.CommonsChunkPlugin({ 103 name: 'manifest', 104 chunks: ['vendor'] 105 }), 106 // copy custom static assets 107 // 将static文件夹里面的静态资源复制到dist/static 108 new CopyWebpackPlugin([ 109 { 110 from: path.resolve(__dirname, '../static'), 111 to: config.build.assetsSubDirectory, 112 ignore: ['.*'] 113 } 114 ]) 115 ] 116 }) 117 118 // 若是开启了产品gzip压缩,则利用插件将构建后的产品文件进行压缩 119 if (config.build.productionGzip) { 120 // 一个用于压缩的webpack插件 121 var CompressionWebpackPlugin = require('compression-webpack-plugin') 122 123 webpackConfig.plugins.push( 124 new CompressionWebpackPlugin({ 125 asset: '[path].gz[query]', 126 // 压缩算法 127 algorithm: 'gzip', 128 test: new RegExp( 129 '\\.(' + 130 config.build.productionGzipExtensions.join('|') + 131 ')$' 132 ), 133 threshold: 10240, 134 minRatio: 0.8 135 }) 136 ) 137 } 138 139 // 若是启动了report,则经过插件给出webpack构建打包后的产品文件分析报告 140 if (config.build.bundleAnalyzerReport) { 141 var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 142 webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 143 } 144 145 module.exports = webpackConfig
最后是build文件夹下的check-version.js,它完成对node和npm的版本检测,下面是其代码注释:
1 // chalk, 用于在控制台输出带颜色字体的插件 2 var chalk = require('chalk') 3 // semver, 语义化版本检查插件(The semantic version parser used by npm) 4 var semver = require('semver') 5 var packageConfig = require('../package.json') 6 // shelljs, 执行Unix命令行的插件 7 var shell = require('shelljs') 8 // 开辟子进程执行指令cmd并返回结果 9 function exec (cmd) { 10 return require('child_process').execSync(cmd).toString().trim() 11 } 12 13 // node和npm版本需求 14 var versionRequirements = [ 15 { 16 name: 'node', 17 currentVersion: semver.clean(process.version), 18 versionRequirement: packageConfig.engines.node 19 } 20 ] 21 22 if (shell.which('npm')) { 23 versionRequirements.push({ 24 name: 'npm', 25 currentVersion: exec('npm --version'), 26 versionRequirement: packageConfig.engines.npm 27 }) 28 } 29 30 module.exports = function () { 31 var warnings = [] 32 // 依次判断版本是否符合要求 33 for (var i = 0; i < versionRequirements.length; i++) { 34 var mod = versionRequirements[i] 35 if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 36 warnings.push(mod.name + ': ' + 37 chalk.red(mod.currentVersion) + ' should be ' + 38 chalk.green(mod.versionRequirement) 39 ) 40 } 41 } 42 // 若是有警告则将其输出到控制台 43 if (warnings.length) { 44 console.log('') 45 console.log(chalk.yellow('To use this template, you must update following to modules:')) 46 console.log() 47 for (var i = 0; i < warnings.length; i++) { 48 var warning = warnings[i] 49 console.log(' ' + warning) 50 } 51 console.log() 52 process.exit(1) 53 } 54 }
config文件夹下最主要的文件就是index.js了,在这里面描述了开发和构建两种环境下的配置,前面的build文件夹下也有很多文件引用了index.js里面的配置。下面是代码注释:
1 // see http://vuejs-templates.github.io/webpack for documentation. 2 var path = require('path') 3 4 module.exports = { 5 // 构建产品时使用的配置 6 build: { 7 // 环境变量 8 env: require('./prod.env'), 9 // html入口文件 10 index: path.resolve(__dirname, '../dist/index.html'), 11 // 产品文件的存放路径 12 assetsRoot: path.resolve(__dirname, '../dist'), 13 // 二级目录,存放静态资源文件的目录,位于dist文件夹下 14 assetsSubDirectory: 'static', 15 // 发布路径,若是构建后的产品文件有用于发布CDN或者放到其余域名的服务器,能够在这里进行设置 16 // 设置以后构建的产品文件在注入到index.html中的时候就会带上这里的发布路径 17 assetsPublicPath: '/', 18 // 是否使用source-map 19 productionSourceMap: true, 20 // Gzip off by default as many popular static hosts such as 21 // Surge or Netlify already gzip all static assets for you. 22 // Before setting to `true`, make sure to: 23 // npm install --save-dev compression-webpack-plugin 24 // 是否开启gzip压缩 25 productionGzip: false, 26 // gzip模式下须要压缩的文件的扩展名,设置js、css以后就只会对js和css文件进行压缩 27 productionGzipExtensions: ['js', 'css'], 28 // Run the build command with an extra argument to 29 // View the bundle analyzer report after build finishes: 30 // `npm run build --report` 31 // Set to `true` or `false` to always turn it on or off 32 // 是否展现webpack构建打包以后的分析报告 33 bundleAnalyzerReport: process.env.npm_config_report 34 }, 35 // 开发过程当中使用的配置 36 dev: { 37 // 环境变量 38 env: require('./dev.env'), 39 // dev-server监听的端口 40 port: 8080, 41 // 是否自动打开浏览器 42 autoOpenBrowser: true, 43 // 静态资源文件夹 44 assetsSubDirectory: 'static', 45 // 发布路径 46 assetsPublicPath: '/', 47 // 代理配置表,在这里能够配置特定的请求代理到对应的API接口 48 // 例如将'localhost:8080/api/xxx'代理到'www.example.com/api/xxx' 49 proxyTable: {}, 50 // CSS Sourcemaps off by default because relative paths are "buggy" 51 // with this option, according to the CSS-Loader README 52 // (https://github.com/webpack/css-loader#sourcemaps) 53 // In our experience, they generally work as expected, 54 // just be aware of this issue when enabling this option. 55 // 是否开启 cssSourceMap 56 cssSourceMap: false 57 } 58 }
这三个文件就简单设置了环境变量而已,没什么特别的。