学习链接:

http://blog.csdn.net/hongchh/article/details/55113751

https://segmentfault.com/a/1190000009356434

http://www.jianshu.com/p/42e11515c10f

主要分析开发(dev)和构建(build)两个过程涉及到的文件,故下面文件结构仅列出相应的内容。

├─build
│   ├─build.js
│   ├─check-versions.js
│   ├─dev-client.js
│   ├─dev-server.js
│   ├─utils.js
│   ├─vue-loader.conf.js
│   ├─webpack.base.conf.js
│   ├─webpack.dev.conf.js
│   ├─webpack.prod.conf.js
│   └─webpack.test.conf.js
├─config
│   ├─dev.env.js
│   ├─index.js
│   ├─prod.env.js
│   └─test.env.js
├─...
└─package.json

package.json

关注scripts字段的内容:

  "scripts": {"dev": "node build/dev-server.js","build": "node build/build.js","lint": "eslint --ext .js,.vue src"},

直接看”dev”和”build”。运行”npm run dev”的时候执行的是build/dev-server.js文件,运行”npm run build”的时候执行的是build/build.js文件,我们可以从这两个文件开始进行代码阅读分析。

build文件夹

build/dev-server.js

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

  1. 检查node和npm的版本
  2. 引入相关插件和配置
  3. 创建express服务器和webpack编译器
  4. 配置开发中间件(webpack-dev-middleware)和热重载中间件(webpack-hot-middleware)
  5. 挂载代理服务和中间件
  6. 配置静态资源
  7. 启动服务器监听特定端口(8080)
  8. 自动打开浏览器并打开特定网址(localhost:8080)

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

require('./check-versions')()   /*检查NodeJS和npm的版本*/
var config = require('../config')  // 获取配置
// 如果Node的环境变量中没有设置当前的环境(NODE_ENV),则使用config中的配置作为当前的环境
if (!process.env.NODE_ENV) process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
// 一个可以调用默认软件打开网址、图片、文件等内容的插件
// 这里用它来调用默认浏览器打开dev-server监听的端口,例如:localhost:8080
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var opn = require('opn')
// 一个express中间件,用于将http请求代理到其他服务器
// 例:localhost:8080/api/xxx  -->  localhost:3000/api/xxx
// 这里使用该插件可以将前端开发中涉及到的请求代理到API服务器上,方便与服务器对接
var proxyMiddleware = require('http-proxy-middleware')
// 引入相应的 webpack 配置
var webpackConfig = require('./webpack.dev.conf')
// dev-server 监听的端口,默认为config.dev.port设置的端口,即8080
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port// Define HTTP proxies to your custom API backend// https://github.com/chimurai/http-proxy-middleware// 定义 HTTP 代理表,代理到 API 服务器
var proxyTable = config.dev.proxyTable
// 创建1个 express 实例
var app = express()// 数据mock
var appData = require('../static/data.json')//在根目录下放置的一个data.json文件,用以模拟请求的数据
var seller = appData.seller//获取data中的数据对象
var goods = appData.goods
var ratings = appData.ratingsvar apiRoutes = express.Router()//创建一个路由实例

apiRoutes.get('/seller', function(req, res) {//获取数据
  res.json({errno: 0,data: seller})
})apiRoutes.get('/goods', function(req, res) {res.json({errno: 0,data: goods})
})apiRoutes.get('/ratings', function(req, res) {res.json({errno: 0,data: ratings})
})app.use('/api', apiRoutes)// express使用api
// 根据webpack配置文件创建Compiler对象
var compiler = webpack(webpackConfig)
// webpack-dev-middleware使用compiler对象来对相应的文件进行编译和绑定
// 编译绑定后将得到的产物存放在内存中而没有写进磁盘
// 将这个中间件交给express使用之后即可访问这些编译后的产品文件
var devMiddleware = require('webpack-dev-middleware')(compiler, {publicPath: webpackConfig.output.publicPath,stats: {colors: true,chunks: false}
})
// webpack-hot-middleware,用于实现热重载功能的中间件
var hotMiddleware = require('webpack-hot-middleware')(compiler)// force page reload when html-webpack-plugin template changes// 当html-webpack-plugin提交之后通过热重载中间件发布重载动作使得页面重载
compiler.plugin('compilation', function(compilation) {compilation.plugin('html-webpack-plugin-after-emit', function(data, cb) {hotMiddleware.publish({action: 'reload'})cb()})
})
// 将 proxyTable 中的代理请求配置挂在到express服务器上
// proxy api requests
Object.keys(proxyTable).forEach(function(context) {var options = proxyTable[context]if (typeof options === 'string') {options = {target: options}}app.use(proxyMiddleware(context, options))
})// handle fallback for HTML5 history API
// 重定向不存在的URL,常用于SPA
app.use(require('connect-history-api-fallback')())// serve webpack bundle output
// 使用webpack开发中间件
// 即将webpack编译后输出到内存中的文件资源挂到express服务器上
app.use(devMiddleware)
// 将热重载中间件挂在到express服务器上
// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)// serve pure static assets// 静态资源的路径// 将静态资源挂到express服务器上
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))
// 启动express服务器并监听相应的端口(8080)
module.exports = app.listen(port, function(err) {if (err) {console.log(err)return}  // 应用的地址信息,例如:http://localhost:8080var uri = 'http://localhost:' + portconsole.log('Listening at ' + uri + '\n')// 如果符合自动打开浏览器的条件,则通过opn插件调用系统默认浏览器打开对应的地址uri// when env is testing, don't need open itif (process.env.NODE_ENV !== 'testing') {opn(uri)}
})

 build/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主要完成了下面这些事情:

  1. 配置webpack编译入口
  2. 配置webpack输出路径和命名规则
  3. 配置模块resolve规则
  4. 配置不同类型模块的处理规则

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

var path = require('path')
var config = require('../config')
var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../')// 给出正确的绝对路径var env = process.env.NODE_ENV// check env & config/index.js to decide weither to enable CSS Sourcemaps for the// various preprocessor loaders added to vue-loader at the end of this file
var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
var useCssSourceMap = cssSourceMapDev || cssSourceMapProdmodule.exports = {entry: {// 配置webpack编译入口app: './src/main.js'},output: {// 配置webpack输出路径和命名规则path: config.build.assetsRoot,// webpack输出的目标文件夹路径(例如:/dist)publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,// webpack编译输出的发布路径filename: '[name].js'  // webpack输出bundle文件命名格式},resolve: {// 配置模块resolve的规则extensions: ['', '.js', '.vue'],// 自动resolve的扩展名fallback: [path.join(__dirname, '../node_modules')],alias: {// 创建路径别名,有了别名之后引用模块更方便,例如 // import Vue from 'vue/dist/vue.common.js'可以写成 import Vue from 'vue''vue$': 'vue/dist/vue.common.js','src': path.resolve(__dirname, '../src'),'assets': path.resolve(__dirname, '../src/assets'),'components': path.resolve(__dirname, '../src/components'),'common': path.resolve(__dirname, '../src/common'),'img': path.resolve(__dirname, '../resource/img')}},resolveLoader: {fallback: [path.join(__dirname, '../node_modules')]},module: {// 配置不同类型模块的处理规则preLoaders: [{test: /\.vue$/,loader: 'eslint',include: projectRoot,exclude: /node_modules/}, {test: /\.js$/,// 对所有.vue文件使用eslintloader: 'eslint',include: projectRoot,exclude: /node_modules/}],loaders: [{test: /\.vue$/,loader: 'vue'}, {test: /\.js$/,// 对src和test文件夹下的.js文件使用babel-loaderloader: 'babel',include: projectRoot,exclude: /node_modules/}, {test: /\.json$/,loader: 'json'}, {test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader: 'url',query: {limit: 10000,name: utils.assetsPath('img/[name].[hash:7].[ext]')}}, {// 对字体资源文件使用url,query.name指明了输出的命名规则test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,loader: 'url',query: {limit: 10000,name: utils.assetsPath('fonts/[name].[hash:7].[ext]')}}]},eslint: {formatter: require('eslint-friendly-formatter')},vue: {loaders: utils.cssLoaders({sourceMap: useCssSourceMap}),postcss: [require('autoprefixer')({browsers: ['last 2 versions']})]}
}

build/webpack.dev.conf.js

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

  1. 将hot-reload相关的代码添加到entry chunks
  2. 合并基础的webpack配置
  3. 使用styleLoaders
  4. 配置Source Maps
  5. 配置webpack插件
var config = require('../config')
var webpack = require('webpack')// 一个可以合并数组和对象的插件
var merge = require('webpack-merge')
var utils = require('./utils')
var baseWebpackConfig = require('./webpack.base.conf')// 一个用于生成HTML文件并自动注入依赖文件(link/script)的webpack插件
var HtmlWebpackPlugin = require('html-webpack-plugin')// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})
// 合并基础的webpack配置
module.exports = merge(baseWebpackConfig, {// 配置样式文件的处理规则,使用styleLoadersmodule: {loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })},// eval-source-map is faster for development// 配置Source Mapsdevtool: '#eval-source-map',plugins: [// 配置webpack插件new webpack.DefinePlugin({'process.env': config.dev.env}),// https://github.com/glenjamin/webpack-hot-middleware#installation--usagenew webpack.optimize.OccurenceOrderPlugin(),new webpack.HotModuleReplacementPlugin(),new webpack.NoErrorsPlugin(),// https://github.com/ampedandwired/html-webpack-pluginnew HtmlWebpackPlugin({filename: 'index.html',template: 'index.html',inject: true})]
})

 build/webpack.prod.conf.js

构建的时候用到的webpack配置来自webpack.prod.conf.js,该配置同样是在webpack.base.conf基础上的进一步完善。主要完成下面几件事情:

  1. 合并基础的webpack配置
  2. 使用styleLoaders
  3. 配置webpack的输出
  4. 配置webpack插件
  5. gzip模式下的webpack插件配置
  6. webpack-bundle分析

说明: webpack插件里面多了丑化压缩代码以及抽离css文件等插件。

var path = require('path')
var config = require('../config')
var utils = require('./utils')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')// 用于从webpack生成的bundle中提取文本到特定文件中的插件 // 可以抽取出css,js文件将其与webpack输出的bundle分离
var HtmlWebpackPlugin = require('html-webpack-plugin')
var env = config.build.envvar webpackConfig = merge(baseWebpackConfig, {// 合并基础的webpack配置module: {loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })},devtool: config.build.productionSourceMap ? '#source-map' : false,output: {// 配置webpack的输出path: config.build.assetsRoot,filename: utils.assetsPath('js/[name].[chunkhash].js'),chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')},vue: {loaders: utils.cssLoaders({sourceMap: config.build.productionSourceMap,extract: true})},plugins: [// http://vuejs.github.io/vue-loader/en/workflow/production.htmlnew webpack.DefinePlugin({// 抽离css文件'process.env': env}),new webpack.optimize.UglifyJsPlugin({compress: {warnings: false}}),new webpack.optimize.OccurrenceOrderPlugin(),// extract css into its own filenew ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),// 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-pluginnew 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 CommonsChunkPluginchunksSortMode: 'dependency'}),// split vendor js into its own filenew webpack.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 updatednew webpack.optimize.CommonsChunkPlugin({name: 'manifest',chunks: ['vendor']})]
})if (config.build.productionGzip) {var 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}))
}module.exports = webpackConfig

转载于:https://www.cnblogs.com/yujihang/p/6995098.html

【webpack】理解配置文件相关推荐

  1. webpack 3 零基础入门教程 #4 - webpack 的配置文件 webpack.config.js

    在命令行中运行 webpack 命令确实可以实现 webpack 的功能,但是我们一般不这么做,我们要用配置文件来处理. 我们把之前学到的知识用 webpack 的配置文件来实现,配置文件的名字叫 w ...

  2. java读取classpath配置文件_SpringBoot2.x入门教程:理解配置文件

    前提 这篇文章是<SpringBoot2.x入门>专辑的「第4篇」文章,使用的SpringBoot版本为2.3.1.RELEASE,JDK版本为1.8. 主要介绍SpringBoot配置文 ...

  3. webpack基础+webpack配置文件常用配置项介绍+webpack-dev-server

    一.webpack基础 1.在项目中生成package.json:在项目根目录中输入npm init,根据提示输入相应信息.(也可以不生成package.json文件,但是package.json是很 ...

  4. webpack基础第一篇(配置文件)

    1.安装mode.js.npm本地环境,lue 2.命令语言 mkdir  webpack_demo  //建立文件夹 cd  webpack_demo  //进入文件夹 npm install -g ...

  5. webpack基础+webpack配置文件常用配置项介绍+webpack-dev-server - QxQstar - 博客园

    一.webpack基础 1.在项目中生成package.json:在项目根目录中输入npm init,根据提示输入相应信息.(也可以不生成package.json文件,但是package.json是很 ...

  6. webpack 配置文件

    像上一节中,我们每次在打包文件时都需要手动输入源文件名和输出文件名,这样会比较麻烦,要解决这个问题,我们可以使用配置文件来进行管理. 本节我们来学习 webpack 的配置文件 webpack.con ...

  7. webpack配置文件:webpack.config.js(一)

    1.webpack的配置文件webpack.config.js //const HtmlWebpackPlugin = require('html-webpack-plugin'); module.e ...

  8. 关于webpack的使用

    关于webpack webpakc的是模块打包器.而不是任务执行器. 它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScri ...

  9. 走近webpack(0)--正文之前的故事

    在前端工作的过程中,只要你接触过vue,angular,react,gulp就一定知道webpack或者听说过或者使用过webpack,但是或许你对webpack的使用方法并不是十分了解,只是会用写好 ...

最新文章

  1. 用计算机打印相片怎么调色,2018年底照片如何使用LOG模式进行调色
  2. Tensorflow Lite Android Demo App
  3. android事件处理概括
  4. Spark SQL 源代码分析系列
  5. Hive客户端secureCRT中文显示设置
  6. 直播 | KDD 2021论文解读:基于协同对比学习的自监督异质图神经网络
  7. python多个装饰器执行顺序_Python面试题之多个装饰器执行顺序
  8. 公司用云桌面还是台式计算机好,相比于性能更强的台式机为什么很多企业更喜欢用云桌面...
  9. 【渝粤题库】陕西师范大学400010 当代西方社会思潮评析 作业(专升本)
  10. 深入了解字符集和编码
  11. 基于Opencv和Tesseract的行驶证识别系统设计
  12. 软考之软件评测师考试详解以及准备篇
  13. 快递扫码入库PC系统
  14. MSP430F415IRTDR
  15. 用matlab调节窗宽窗位的代码,基于HTML5的PACS HTML5图像处理(7)实现客户端JS调整窗宽窗位...
  16. 壳与加壳脱壳基础知识
  17. 连接数据库失败提示hba.conf不符合的处理方法
  18. PictureMerge
  19. linux系统的系统性学习 (持续更新)
  20. 年产10000吨乳制品工厂设计

热门文章

  1. php语句创建数据表,用mysql语句创建数据表详细教程
  2. mysql基本sql语句总结(一)
  3. python3.7.4安装教程win7_Window10下python3.7 安装与卸载教程图解
  4. linux不识别xfs,centos7 grub2无法识别xfs root分区
  5. 怎么把程序内部坐标转为屏幕坐标,如何将工作空间坐标转换为屏幕坐标?
  6. windows防火墙设置_合理利用Windows 7防火墙,阻止部分功能,避免网络恶意软件攻击...
  7. int和Integer有什么区别(转)
  8. python执行多个py文件_【经验分享】如何同时运行多个python脚本
  9. hutool获取5天前的日期_连载|日 产 物 流 管 理 方 式(5)
  10. 代码逻辑分析_双十一模块 79.34% 的代码是怎样智能生成的