本系列文章主要讲下vue的webpack脚手架的来龙去脉,逐行分析其操做。若是写的有问题请务必指出!若是以为写的还不错点个赞就是对我最大的鼓励了,谢谢!javascript
当使用vue-cli脚手架生成项目后,项目架构与其做用大概是这样的:css
首先上面提到,阅读代码首先须要看这个文件,由于当你在命令行敲下第一句命令html
npm run dev
复制代码
webpack就会找到package.json文件中的script属性并依次分析命令,可见,这句命令相应的会执行前端
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
复制代码
这句话的意思是vue
webpack,在开发环境下,请你帮我运行webpack-dev-server插件,而且实时编译文件,另外,我还需有度条可见。最后,你帮我编译build文件夹下的webpack.dev.conf.js文件吧java
前文说了那么多,都是为了给本文的主角(build/webpack.dev.conf.js)作铺垫,从这个文件名就不难看出,此文件是webpack在开发环境下的项目的配置文件,下面来看看这个文件到底作了什么webpack
在文件第71-95行git
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: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
复制代码
webpack.dev.conf.js文件对外暴露出了一个promise对象,从函数里看出,首先是引入了portfinder
这个库,这是一个关于端口相关的一个库,其中指定了端口为项目启动的端口github
portfinder.basePort = process.env.PORT || config.dev.port
复制代码
process.env同config.dev后面会讲到web
接着看代码,portfinder又执行了getPort
方法,当获取到当前运行端口后,给process.env
设置了port
属性
process.env.PORT = port
复制代码
这里这样设置是由于e2e单元测试须要用到的,在这里也不叙述了,有兴趣能够去查阅相关资料
接着往下看,promise返回了一个对象devWebpackConfig
,这个对象就是webpack.dev.conf.js的核心了,往上翻代码看他定义了什么
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
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, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
}
})
复制代码
首先说明的是,在开发环境和生产环境,webpack的配置是有很大不一样的。好比在开发环境,咱们须要快速的开发,因此咱们可能须要一些实时加载和热更新等功能。可是在开发环境,咱们不须要这些,咱们须要更小的bundle,更轻量的source map,以及更轻量的资源,以改善加载时间。所以,为给个环境配置不一样的webpack配置是必作的一步
虽然咱们会为环境作区分,可是基于不重复原则,vue-cli为两个环境公用的配置整合到了(build/webpack.base.conf.js)文件中。而后利用webpack-merge
插件将配置整合在一块儿
webpack.base.conf.js文件在这里不作叙述了,具体配置你们能够翻阅文件查看
在文件第17-19行
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
}
复制代码
这里默认添加了一些匹配规则(css,postcss,less,sass,scss,stylus,styl),当webpack遇到这些文件时会采用相关的loader进行处理,可是这里没有默认配置typescript的loader,想要使用ts的可使用ts-loader进行处理哦
接着看文件第21行
devtool: config.dev.devtool,
复制代码
当 webpack 打包源代码时,可能会很难追踪到错误和警告在源代码中的原始位置。例如,若是将三个源文件(a.js, b.js 和 c.js)打包到一个 bundle(bundle.js)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会简单地指向到 bundle.js。这并一般没有太多帮助,由于你可能须要准确地知道错误来自于哪一个源文件。
webpack一共提供了13中构建文件的模式,不一样的值会明显影响到构建和从新构建的速度。在开发环境webpack是推荐使用cheap-module-eval-source-map
模式的,而在生产环境使用cheap-source-map
模式会更适合。webpack 仓库中包含一个 显示全部 devtool 变体效果的示例。这些例子或许会有助于你理解这些差别之处,在这里也不作多叙述了
当你敲下那句熟悉的npm run dev
后,浏览器就会弹出一个窗口,路径赫然写着localhost:8080
。这是由于vue-cli在开发模式下,采用了webpack-dev-server
插件,这个插件提供了一个简单的web服务器,而且可以实时加载,大大提升了前端开发速度
看文件第24-46行
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
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, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
}
复制代码
这里主要讲下devServer.proxy这个属性
devServer采用了一个很是强大的http请求中间件http-proxy-middleware
。此中间件能对http请求作中间转发处理,而且可以很好的解决了开发中跨域的问题
若是你有单独的后端开发服务器 API,而且但愿在同域名下发送 API 请求 ,那么代理某些 URL 会颇有用
在 localhost:3000 上有后端服务的话,你能够在config/index.js文件下proxyTable属性这样设置:
proxyTable: {
"/api": "http://localhost:3000"
}
复制代码
如今请求到 /api 如今会被代理到请求 http://localhost:3000/api
接着看文件第47-69行
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({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
复制代码
webpack的插件机制能让你使用不少自带的和第三方的插件
这里使用到了:
以上就是webpack.dev.config.js文件所作的事情,欲知后事如何,请听下回分解。