2020年1月18号,还有一周就是农历2020年的春节了,我提早请了6天的假,回家过年。此时公司的项目仍是如火如茶的开展,一如既往的赶工。css
原本打算年前辞去工做,回家过个长春节,来年金三银四江湖再会。(毕竟,这是我二十多年来,第一次回老家过年)html
待遇通常,配的也是租来的黑瞎眼的古董thinkPad T430笔记本,每天无条件加班9->0点。要是我辞,试用期内,不辞,过完年就过试用期了,考虑到新项目尚未作完(期实也就是作了一个月,可是已完成7成了),负责任的我犹豫了好久,没有提交那份书。前端
拿了在这里上班的第一个月工资,以及卖掉了本身的游戏本,换了一个二手的macbook pro。vue
刚入行前端的头一年,我知道,我要的是知识,我要的不是没日没夜的加班,还有不停的百度,不停的试完一个博客的案例发现不合适又找下一个。node
应了当前项目两个开发环境,三个打包路径改来改去的痛点,我决定在这个春节,怎么也要抽点时间出来看完这本《深刻浅出Webpack》。webpack
看的是电子书,2018年1月发售的,在京东上找,这本书还在买。看了京东对本书的简介好像并无更新。书中用的webpack 是@2版并穿插@3版本。据说webpack 4有了相对大的更新,目前好像更新到了5,别说老油条,我一个新人,都以为前端学起来费劲。web
对于书上的安装方法来装各个工具是版本是不对的。可是能不能用,出现的坑,我都在下文的总结中列出来吧。vue-cli
本次学习没有过深研究webpack,参照了vue-cli2.9版本搭建的webpack模版,以及webpack 4.4的官方中文文档(不知道怎么能看到旧文档),对于要在vue项目中用到的一些配置做了学习。npm
后期跟据须要会不断的完善这份总结。json
有不少过来人都说前端更新快,看书学习不是最佳方法(考虑到书的价格不低),可是我仍是比较喜欢看书,本身也买了不少书,这本是到目前为止看的惟一一本电子书。这本书到底值不值看?
前半部分对api的介绍没有webpack官方文档好理解,可是后半段对webpack的配置优化总结及一些按例仍是很值得新手去看
文中没有很明确说到如何启动build和运行webpack中的命令,
期实,运行webpack就是在终端中(进入当前文件夹)输入webpack,回车后项目就打包放在dist文件夹了,可是,这时打包的结果是一个js文件,入口index.html文件仍是在dist同级目录下的那个index.html。
当你的webpack没有全局安装时,不能直接在终端中输入webpack,而是要输入webpack所在的文件,在node_modules/.bin/webpack。直接输入
node_modules/.bin/webpack
回车。
运行devServer时也是在这个目录下
node_modules/.bin/webpack-dev-server
要看到热更新,还要改一下入口文件index.html中的bundle.js的路径,由于devserver不会理会webpack.config.js里的output.path属性。
<script src="./dist/bundle.js" ></script> <!-- 改成下面的--!> <script src="bundle.js"></script>
固然这些命令是能够写在package.json文件里的script下,而后经过npm run 去运行的
更改:在webpack的配置文件中:
const path = require('path'); { context: path.resolve(__dirname,'app'),//或者 ./ ../ 等 }
entry: { app: './src/main.js',//能够配置多个入口,或动态入口 }
output: { filename: '[name].js',//[name]是node内置的name变量 path: path.resolve(__dirname, '../dist'),//必须是绝对路径,经过之path能够找出绝对路径。 publicPath: '', }
说明:
filename 输出文件的名称
path 输出文件存放在本地的目录
publicPath 异步加载的地址,(发布到线上资源的URL前缀)
配置模块如何解析,
改import后面的引用路径,从而达到简写
resolve: { alias: { "@": resolve('src'),//resolve方法是找到src是绝对地址 "vue$": './src/vue/' } } //当引用 import Comp from 'vue$/vue'; import Button from '@/components/button'; //实际会被改为 import Comp from './src/vue/vue'; import Button from './src/components/button';
使import 的引用路径不用写相应的后缀名,
resolve: { extensions: ['.js','.json'],//默认值 //extensions: ['.js','.vue','.json'],vue项目能够加入'.vue' }
用于描述web pack-dev-server的行为选项
模块热替换采用不刷新整个页面,而是热替换有变动的模块来更新浏览器视图,默认是刷新整个页面
devServer: { hot: true, }
用于方便开发使用了HTML5 History API的单页面应用
当设为:
devServer: { historyApiFallback: true, }
任意的 404
响应均可能须要被替代为 index.html
,但只能应用于只有一个html文件的应用。
若是要devServer能跟据不一样的页面请求后回不周的html文件,配置:
historyApiFallback: { rewrites: [ // /user开头的都返回user.html { from: /^\/user/, to: '/user.html'}, { from: /^\/game/, to: './game.html'}, //其余的返回index.html { from: /./, to: '/index.html'} ] }
boolean,在devServer启动且第一次构建完成时,自动打开系统默认浏览器
使用了http-proxy-middleware
包,用于代理url。
直接代理:
devServer: { proxy: { "/api": "http://localhost:3000", } }
当请求/api/index
时会被代理到 'http://localhost:3000/api/index'
若是你不想始终传递 /api
,则须要重写路径:
proxy: { "/api": { target: "http://localhost:3000", pathRewrite: { "^/api": "", } } }
若是是https
请求加入source: false,
proxy: { source: false,//source直译:安全的 }
解决跨域:changeOrigin
proxy: { changeOrigin: true, }
本地就会虚拟一个服务器接收你的请求并代你发送该请求
boolean
启用 quiet
后,除了初始启动信息以外的任何内容都不会被打印到控制台。这也意味着来自 webpack 的错误或警告在控制台不可见。
构建针对不一样运行环境的代码
配置如何生成source Map,以方便调试
string
boolean
默认: false
不一样的值会明显影响到构建(build)和从新构建(rebuild)的速度。
vue-cli2中应在development开发环境的devtool为:cheap-module-eval-source-map
对于适合开发环境的值,webpack文档中有以下说明:
eval
- 每一个模块都使用eval()
执行,而且都有//@ sourceURL
。此选项会很是快地构建。主要缺点是,因为会映射到转换后的代码,而不是映射到原始代码(没有从 loader 中获取 source map),因此不能正确的显示行数。
eval-source-map
- 每一个模块使用eval()
执行,而且 source map 转换为 DataUrl 后添加到eval()
中。初始化 source map 时比较慢,可是会在从新构建时提供比较快的速度,而且生成实际的文件。行数可以正确映射,由于会映射到原始代码中。它会生成用于开发环境的最佳品质的 source map。
cheap-eval-source-map
- 相似eval-source-map
,每一个模块使用eval()
执行。这是 "cheap(低开销)" 的 source map,由于它没有生成列映射(column mapping),只是映射行数。它会忽略源自 loader 的 source map,而且仅显示转译后的代码,就像eval
devtool。
cheap-module-eval-source-map
- 相似cheap-eval-source-map
,而且,在这种状况下,源自 loader 的 source map 会获得更好的处理结果。然而,loader source map 会被简化为每行一个映射(mapping)。
Vue-cli2在build生产环境中的devtool为: #source-map
不知道为何加了一个'#'
对于适合生产环境的值,webpack文档中有以下说明:
(none)
(省略devtool
选项) - 不生成 source map。这是一个不错的选择。
source-map
- 整个 source map 做为一个单独的文件生成。它为 bundle 添加了一个引用注释,以便开发工具知道在哪里能够找到它。你应该将你的服务器配置为,不容许普通用户访问 source map 文件!
hidden-source-map
- 与source-map
相同,但不会为 bundle 添加引用注释。若是你只想 source map 映射那些源自错误报告的错误堆栈跟踪信息,但不想为浏览器开发工具暴露你的 source map,这个选项会颇有用。你不该将 source map 文件部署到 web 服务器。而是只将其用于错误报告工具。
nosources-source-map
- 建立的 source map 不包含sourcesContent(源代码内容)
。它能够用来映射客户端上的堆栈跟踪,而无须暴露全部的源代码。你能够将 source map 文件部署到 web 服务器。这仍然会暴露反编译后的文件名和结构,但它不会暴露原始代码。在使用
uglifyjs-webpack-plugin
时,你必须提供sourceMap:true
选项来启用 source map 支持。
其中,devtool有六个值,这六个值能够随意组合:
watch
webpack的监听模式,它支持监听文件更新,在文件发生变化时从新编译。
默认为false
在webpack-dev-server 和 web pack-dev-middleware中是默认开启的。
watchOption是相应的配置
也就是webpack的命令,写在package.json的script
字段里
经常使用工具: ESlint、TSlint、stylelint
价绍了ESlint的一些设定,TSlint用于TypeScript,stylelint用于css
改变打包后的文件名,以方便寻找路径,用hash命名。
Url-loader
将小文件的资源改成base64格式以嵌入代码中。
好处:http/1协议中,每加载一次资源都要创建一次http请求,将小图片注入代码中能够减小这一次请求
很差处: 会导至js/css代码体积变大,文件过大将使网页加载缓慢。
module.export = { module: { rules: [ { test: /\.png$/, use: [ { loader: 'url-loader', options: { //30KB如下的文件采用url-loader, limit: 1024*03, //不然用file-loader, fallback: 'file-loader', } } ] } ] } }
踩坑1: 更改paralleUglifyPlugin并无加快打包的速度
个人项目是用vue-cli2拉的默认环境,开发了一段时间,也加入了好多第三方包。平时的打包大概是50秒,改为paralleUglifyPlugin后,时间为48.5秒。
其中,配置时也有不少报错:正确的配置:
new ParallelUglifyJsPlugin({ //uglifyJs要改成uglifyES(求上传服务器验证) uglifyES: { output: { beautify: false, comments: false, } }, compress: { warnings: false, drop_console: true, collapse_vars: true, reduce_vars: true, }, sourceMap: config.build.productionSourceMap,//false parallel: true, }),
书中介绍的方法是设置process.env.NODE_ENV
const DefinePlugin = require('webpack/lib/DefinePlugin'); module.export = { plugins: [ new DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production') } }) ] }
在定义环境时用JSON.stringify的缘由是,环境烃量的值须要是一个由双引号包裹的字符串,而JSON.stringify('production')的值正好等于'"production"'