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"'